SlideShare a Scribd company logo
1 of 176
姫路IT系勉強会 Vol.7

CakePHP+Smartyハイブリッド
    によるラクラク開発
       MVCの栄光を君に!
お品書き


自己紹介など
MVCとは?
Smarty
CakePHP
Smarty+CakePHP
自己紹介など
今日のプレゼンは
太い @architshin
       と
細い @aWebprogrammer
まず太いほうから
@architshin
本名: 齊藤新三
       この顔で→
「新ちゃん」「新三さん」
   とよんでね♡
特筆すべき点は…


 ガンヲタです。
次、細いほう
@aWebprogrammer
  ※アカウント作った時にネタでつけたやつをいまだに引きずってる・・・o
Perlよりも、Rubyよりも、普通の女子よりも、PHPが好きだー!って



        変ジニアです(キリッ
                     ※例外として、天然入ってる人には激しく反応します!
「ワテさん」とか「変ジニア
     さん」
    と呼んでね♡
    ※「田中佳明」って本名もあるけど、こっちの方が馴染んでます
MVCとは?
WEBアプリのサーバーサイドの動きというのは…



表示画面     処理      表示画面     処理      表示画面




       PHPファイル          PHPファイル
例えば、こんな画面を表示するPHPを
デザイナさんにデザインしてもらおうとする…
ソースコードは…
<?php                                                                                   else {
print("<?xml version="1.0" encoding="UTF-8" ?>n");                           ?>
$odTotalFloor = $_POST['odTotalFloor'];                                           <p><?php print($count) ?>件ありました。</p>
?>                                                                                <table border="1">
<!DOCTYPE html PUBLIC "-                                                             <thead>
//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1       <tr>
-transitional.dtd">                                                                     <th>注文コード</th>
<html xmlns="http://www.w3.org/1999/xhtml">                                             <th>注文日時</th>
<head>                                                                                  <th>注文合計金額</th>
    <title>サンプル01: MVC未分離</title>                                                       <th>注文者氏名</th>
</head>                                                                                 <th>注文者住所</th>
<body>                                                                                  <th>注文者電話番号</th>
<h1>Histudy7 サンプル01: MVC未分離</h1>                                                     </tr>
<hr/>                                                                                </thead>
<form action="sample01.php" method="post">                                           <tbody>
注文合計が                                                                             <?php
<input type="text" name="odTotalFloor" value="<?php print($odTotalFloor) ?>"/>円            $sql2 = "SELECT * FROM orders WHERE od_total>=:od_total ORDER BY od_total";
以上の注文情報を<input type="submit" value="表示"/>                                                  $stmt2 = $db->prepare($sql2);
</form>                                                                                    $stmt2->bindParam(":od_total", $odTotalFloor);
<?php                                                                                      $stmt2->execute();
if(is_numeric($odTotalFloor)) {                                                            $i = 0;
    $dsn = "mysql:host=localhost;dbname=histudy7";                                         while($row = $stmt2->fetch()) {
    $username = "histudy";                                                        ?>
    $password = "hihi";                                                                 <tr>
                                                                                           <td><?php print($row['od_code']) ?></td>
   try {                                                                                   <td><?php print(strftime('%Y/%m/%d %H:%M:%S',strtotime($row['od_date']))) ?
      $db = new PDO($dsn, $username, $password);                                  ></td>
      $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);                        <td><?php print($row['od_total']) ?></td>
      $db->query("SET NAMES utf8;");                                                       <td><?php print($row['od_name']) ?></td>
      $sql1 = "SELECT COUNT(DISTINCT(od_code)) AS count FROM orders WHERE od               <td><?php print($row['od_address']) ?></td>
_total>=:od_total ORDER BY od_total";                                                      <td><?php print($row['od_tel']) ?></td>
      $stmt1 = $db->prepare($sql1);                                                     </tr>
                                                                                  <?php
     $stmt1->bindParam(":od_total", $odTotalFloor);                                        }
     $stmt1->execute();                                                           ?>
     $result1 = $stmt1->fetch();                                                     </tbody>
                                                                                  </table>
     $count = $result1["count"];                                                  <?php
     if($count == 0) {                                                                  }
?>                                                                                      $db = null;
<p>表示すべき情報はありません。</p>                                                                }
<?php
    }
こんなのデザインできる
 デザイナーなんて…
そんな変態
ほとんどいない

      たまにいるけど…
さらに
    <th>注文者住所</th>
    <th>注文者電話番号</th>
  </tr>
  </thead>
  <tbody>
<?php
       $sql2 = "SELECT * FROM orders WHERE od_total>=:od_total ORDER BY od_total";
       $stmt2 = $db->prepare($sql2);
       $stmt2->bindParam(":od_total", $odTotalFloor);
       $stmt2->execute();
       $i = 0;
       while($row = $stmt2->fetch()) {




                        SQL文!
                        ここに書いちゃうと、他のPHPファイルで使えない。
同じSQL文が
あちらにもこちらにも
表示画面              PHP             表示画面                PHP            表示画面


                        ここにも               ここにも

$sql2 = "SELECT * FROM orders WHERE od_total>=:od_total ORDER BY od_total";
DBに変更があったら…
各処理PHPから
DB処理を分離する!
表示画面   PHP   表示画面    PHP   表示画面




       利用            利用
             DB処理
              PHP




             Model
DB操作のクラス(DAO)を作る
<?php                                                         /**
require_once("OrderEntity.class.php");                         * 指定金額以上の注文情報を取得するメソッド。
                                                               *
/**                                                            * @param integer $odTotalFloor 注文合計下限
 * テーブルordersのデータ操作を行うDAOクラス。                                  * @return array 各要素はOrderEntityオブジェクト
 *                                                             */
 */                                                           public function findMoreThanOdTotalFloor($odTotalFloor) {
class OrderDAO {                                                  $orderEntities = array();
                                                                  try {
  /**                                                                $this->_db->query("SET NAMES utf8;");
   * データソース                                                          $sql = "SELECT * FROM orders WHERE od_total>=:od_total ORDER BY
   *                                                        od_total";
   * @var PDO                                                        $stmt = $this->_db->prepare($sql);
   */
  private $_db;                                                    $stmt->bindParam(":od_total", $odTotalFloor);
                                                                   $result = $stmt->execute();
  /**                                                              while($row = $stmt->fetch()) {
   * コンストラクタ。データベースへの接続を行う。                                           $orderEntity = new OrderEntity();
   *                                                                  $odCode = $row['od_code'];
   */                                                                 $orderEntity->setOdCode($odCode);
  public function __construct() {                                     $orderEntity->setOdDate($row['od_date']);
      $dsn = "mysql:host=localhost;dbname=histudy7";                  $orderEntity->setOdTotal($row['od_total']);
      $username = "histudy";                                          $orderEntity->setOdName($row['od_name']);
      $password = "hihi";                                             $orderEntity->setOdAddress($row['od_address']);
      $this->_db = new PDO($dsn, $username, $password);               $orderEntity->setOdTel($row['od_tel']);
      $this->_db-                                                     $orderEntities[$odCode] = $orderEntity;
>setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);          }
  }                                                              }
                                                                 catch(PDOException $ex) {
  /**                                                               $expMessage = "<p>DB接続に失敗しました。<hr/>";
   * デストラクタ。データベースへの接続解除を行う。                                        $expMessage .= "例外の中身:Code=".$ex->getCode()."<br/>".$ex-
   *                                                        >getFile()."(".$ex->getLine()."): ".$ex->getMessage()."<br/>".$ex-
   */                                                       >getTraceAsString();
  public function __destruct() {                                    print($expMessage);
      $this->_db = null;                                         }
  }                                                              return $orderEntities;
                                                               }
                                                            }
                                                            ?>
重要なところだけ見ると…
class OrderDAO {
                 ~ 中略 ~
   public function findMoreThanOdTotalFloor($odTotalFloor) {
      $orderEntities = array();
      try {
         $this->_db->query("SET NAMES utf8;");
         $sql = "SELECT * FROM orders WHERE od_total>=:od_total ORDER BY od_total";
         $stmt = $this->_db->prepare($sql);

       $stmt->bindParam(":od_total", $odTotalFloor);
       $result = $stmt->execute();
       while($row = $stmt->fetch()) {                         さっき出てきたSQL
          $orderEntity = new OrderEntity();
                                                              文!
          $odCode = $row['od_code'];
          $orderEntity->setOdCode($odCode);
          $orderEntity->setOdDate($row['od_date']);
          $orderEntity->setOdTotal($row['od_total']);
          $orderEntity->setOdName($row['od_name']);
          $orderEntity->setOdAddress($row['od_address']);
          $orderEntity->setOdTel($row['od_tel']);
          $orderEntities[$odCode] = $orderEntity;
       }
エンティティクラスを作る
<?php                          /**
                                * 注文者電話番号
/**                             * @var string
 * 注文情報エンティティクラス。               */
 *                             private $_odTel;
 * @author Shinzo SAITO
 *                             /**
 */                             * @return integer 注文コード
class OrderEntity {             */
    /**                        public function getOdCode() {
     * 注文コード                       return $this->_odCode;
     * @var integer            }
     */
    private $_odCode;          /**
                                * @param integer $odCode 注文コード
  /**                           */
   * 注文日時                      public function setOdCode($odCode) {   つまり、
   */                              $this->_odCode = $odCode;
  private $_odDate;            }                                      このクラス1コが
  /**                          /**                                    テーブルの1行分の
   * 注文合計金額                     * @return mixed 注文日時
   * @var integer               */                                    データに対応する
   */                          public function getOdDate() {
  private $_odTotal;               return $this->_odDate;
                               }
  /**
   * 注文者氏名                         ~ 以下setter/getterがつづく~
   * @var string          ?>
   */
  private $_odName;

  /**
   * 注文者住所
   * @var string
   */
  private $_odAddress;
SQLの結果
od_code   od_date               od_total   od_name   od_address   od_tel   OrderEntity
4         2008/06/07 12:54:21   53500      中谷桃       …            …

18        2008/06/07 12:54:21   53500      梶原淳       …            …
                                                                           OrderEntity
32        2008/06/07 12:54:21   53500      森俊之       …            …



                                                                           OrderEntity




                                                                              連想配列に格
                                                                                 納
表示画面         PHP   表示画面




          利用

              エンティティ
DB処理          (の連想配列)
 PHP
Mが分離された処理PHPは…
<?php                                                                         <section>
require_once("OrderEntity.class.php");                                        <?php if($count == 0) { ?>
require_once("OrderDAO.class.php");                                           <p>表示すべき情報はありません。</p>
                                                                              <?php }
                                                                              else { ?>
$orderEntities = array();                                                     <?php print($count) ?>件ありました。
$odTotalFloor = $_POST['odTotalFloor'];                                       <table border="1">
if(is_numeric($odTotalFloor)) {                                                  <thead>
    $orderDAO = new OrderDAO();                                                  <tr>
    $orderEntities = $orderDAO->findMoreThanOdTotalFloor($odTotalFloor);            <th>注文コード</th>
}                                                                                   <th>注文日時</th>
$count = count($orderEntities);                                                     <th>注文合計金額</th>
?>                                                                                  <th>注文者氏名</th>
                                                                                    <th>注文者住所</th>
<!DOCTYPE html>                                                                     <th>注文者電話番号</th>
<html>                                                                           </tr>
<head>                                                                           </thead>
   <meta charset="UTF-8">                                                        <tbody>
   <title>サンプル02: Mの分離</title>                                                   <?php foreach($orderEntities as $key1=>$orderEntity) { ?>
</head>                                                                             <tr>
<body>                                                                                 <td><?php print($orderEntity->getOdCode()) ?></td>
<header>                                                                               <td><?php print(strftime('%Y/%m/%d %H:%M:%S',strtotime($order
   <h1>Histudy7 サンプル02: Mの分離</h1>                                             Entity->getOdDate()))) ?></td>
</header>                                                                              <td><?php print($orderEntity->getOdTotal()) ?></td>
<section>                                                                              <td><?php print($orderEntity->getOdName()) ?></td>
   <form action="sample02.php" method="post">                                          <td><?php print($orderEntity->getOdAddress()) ?></td>
   注文合計が                                                                               <td><?php print($orderEntity->getOdTel()) ?></td>
<input type="text" name="odTotalFloor" value="<?php print($odTotalFloor) ?>         </tr>
"/>円以上の注文情報を<input type="submit" value="表示"/>                                    <?php } ?>
   </form>                                                                       </tbody>
</section>                                                                    </table>
                                                                              <?php } ?>
                                                                              </section>
                                                                              </body>
                                                                              </html>
ををを!
見やすくなった!
でも、
まだ足らない!
PHPコードを駆逐する!
        刹那・F・セイエイ
例えば、こんな画面のHTMLは…
                   <!DOCTYPE html>
                   <html>
                   <head>
                     <meta charset="UTF-8">
                     <title>サンプル03: Vの分離</title>
                   </head>
                   <body>
                   <header>
                     <h1>Histudy7 サンプル03: Vの分離</h1>
                   </header>
                   <section>
                     <table border="1">
                       <tr>
                          <th>注文コード</th>
                          <td>18</td>
                       </tr>
                       <tr>
                          <th>注文日時</th>
                          <td>2008/06/21 12:54:21</td>
                       </tr>
                       <tr>
                          <th>注文合計金額</th>
                          <td>53,500円</td>
                       </tr>
                       <tr>
                          <th>注文者氏名</th>
                          <td>梶原順</td>
                       </tr>
                       <tr>
                          <th>注文者住所</th>
                          <td>京都市伏見区小豆屋町</td>
                       </tr>
                       <tr>
                          <th>注文者電話番号</th>
                          <td>078-846-8767</td>
                       </tr>
                     </table>
                   </section>
                   </body>
                   </html>
このまま使えないかなあ。
DBデータによって変動する部分は…
<!DOCTYPE html>                           <tr>
<html>                                       <th>注文者氏名</th>
<head>                                       <td>梶原順</td>
  <meta charset="UTF-8">                  </tr>
  <title>サンプル03: Vの分離</title>             <tr>
</head>                                      <th>注文者住所</th>
<body>                                       <td>京都市伏見区小豆屋町</td>
<header>                                  </tr>
  <h1>Histudy7 サンプル03: Vの分離</h1>          <tr>
</header>                                    <th>注文者電話番号</th>
<section>                                    <td>078-846-8767</td>
  <table border="1">                      </tr>
    <tr>                                </table>
       <th>注文コード</th>                 </section>
       <td>18</td>                    </body>
    </tr>                             </html>
    <tr>
       <th>注文日時</th>
       <td>2008/06/21 12:54:21</td>
    </tr>                             これら、変動する部分を変数化し
    <tr>
       <th>注文合計金額</th>                て置き換え可能にしてみる
       <td>53,500円</td>
    </tr>
変数化してみると…
<!DOCTYPE html>                        <tr>
<html>                                    <th>注文者氏名</th>
<head>                                    <td>#OD_NAME#</td>
  <meta charset="UTF-8">               </tr>
  <title>サンプル03: Vの分離</title>          <tr>
</head>                                   <th>注文者住所</th>
<body>                                    <td>#OD_ADDRESS#</td>
<header>                               </tr>
  <h1>Histudy7 サンプル03: Vの分離</h1>       <tr>
</header>                                 <th>注文者電話番号</th>
<section>                                 <td>#OD_TEL#</td>
  <table border="1">                   </tr>
    <tr>                             </table>
       <th>注文コード</th>              </section>
       <td>#OD_CODE#</td>          </body>
    </tr>                          </html>
    <tr>
       <th>注文日時</th>
       <td>#OD_DATE#</td>
    </tr>                          このファイルを読み込んで使う
    <tr>
       <th>注文合計金額</th>
       <td>#OD_TOTAL#円</td>
    </tr>
Controller


        表示画面           PHP      表示画面



                              読込
           利用                  +
                             変数置換
               エンティティ
DB処理           (の連想配列)                 変数化
 PHP                                   HTML



Model                                  View
MVが分離されたControllerは…
<?php
require_once("OrderEntity.class.php");
require_once("OrderDAO.class.php");

$odCode = $_GET['odCode'];
                                                       Mからデータ取得
$orderDAO = new OrderDAO();
$orderEntity = $orderDAO->findyByPK($odCode);
                                                       Vファイルの読込
$htmlTemp = file_get_contents("sample03t.html");

$html = str_replace("#OD_CODE#", $orderEntity->getOdCode(), $htmlTemp);
$html = str_replace("#OD_DATE#",
       strftime('%Y/%m/%d %H:%M:%S',strtotime($orderEntity->getOdDate())), $html);
$html = str_replace("#OD_TOTAL#", number_format($orderEntity->getOdTotal()), $html);
$html = str_replace("#OD_NAME#", $orderEntity->getOdName(), $html);
$html = str_replace("#OD_ADDRESS#", $orderEntity->getOdAddress(), $html);
$html = str_replace("#OD_TEL#", $orderEntity->getOdTel(), $html);

print($html);
                                                      Vファイルの変数置換
?>
じゃあ、
これは?
HTMLは…
<!DOCTYPE html>                                                     <tr>
<html>                                                                <td>18</td>
<head>                                                                <td>2008/06/21 12:54:21</td>
  <meta charset="UTF-8">                                              <td>53500</td>
  <title>サンプル02: Mの分離</title>                                         <td>梶原順</td>
</head>                                                               <td>京都市伏見区小豆屋町</td>
<body>                                                                <td>078-846-8767</td>
<header>                                                            </tr>
  <h1>Histudy7 サンプル02: Mの分離</h1>                                    <tr>
</header>                                                             <td>32</td>
<section>                                                             <td>2008/07/05 12:54:21</td>
  <form action="sample02.php" method="post">                          <td>53500</td>
  注文合計が<input type="text" name="odTotalFloor" value="50000"/>         <td>森俊之</td>
円以上の注文情報を<input type="submit" value="表示"/>                            <td>福岡県福岡市博多区</td>
  </form>                                                             <td>078-846-8781</td>
</section>                                                          </tr>
<section>                                                           <tr>
11件ありました。                                                             <td>1</td>
<table border="1">                                                    <td>2008/06/04 12:54:21</td>
  <thead>                                                             <td>56421</td>
    <tr>                                                              <td>後藤武</td>
       <th>注文コード</th>                                                 <td>兵庫県神戸市東灘区住吉町</td>
       <th>注文日時</th>                                                  <td>078-846-8750</td>
       <th>注文合計金額</th>                                              </tr>
       <th>注文者氏名</th>                                                        ~中略~
       <th>注文者住所</th>                                             </tbody>
       <th>注文者電話番号</th>                                         </table>
    </tr>                                                       </section>
  </thead>                                                      </body>
  <tbody>                                                       </html>
    <tr>
       <td>4</td>
       <td>2008/06/07 12:54:21</td>
       <td>53500</td>
       <td>中谷桃</td>
       <td>和歌山県新宮市あけぼの</td>                                      ル、ループ…
       <td>078-846-8753</td>
    </tr>
で、できない…orz
Smarty
またまた、これを例にとると…
                 <table border="1">
                   <tr>
                     <th>注文コード</th>
                     <td>#OD_CODE#</td>
                   </tr>
                   <tr>
                     <th>注文日時</th>
                     <td>#OD_DATE#</td>
                   </tr>
                   <tr>
                     <th>注文合計金額</th>
                     <td>#OD_TOTAL#円</td>
変数が埋め込まれたtable     </tr>
                   <tr>
タグの部分だけ見てみる          <th>注文者氏名</th>
と                    <td>#OD_NAME#</td>
                   </tr>
                   <tr>
                     <th>注文者住所</th>
                     <td>#OD_ADDRESS#</td>
                   </tr>
                   <tr>
                     <th>注文者電話番号</th>
                     <td>#OD_TEL#</td>
                  </tr>
                 </table>
これがSmartyを使うと…
<table border="1">
  <tr>
    <th>注文コード</th>
    <td>{$odCode}</td>
  </tr>
  <tr>
    <th>注文日時</th>
    <td>{$odDate|date_format:"%Y/%m/%d %H:%M:%S"}</td>
  </tr>
  <tr>
    <th>注文合計金額</th>
    <td>{$odTotal}円</td>
  </tr>
  <tr>                                                    {$変数名}
    <th>注文者氏名</th>
    <td>{$odName}</td>                                    という記述
  </tr>
  <tr>                                                       ||
    <th>注文者住所</th>
    <td>{$odAddress}</td>
                                                         テンプレート変数
  </tr>
  <tr>
    <th>注文者電話番号</th>
    <td>{$odTel}</td>
  </tr>
</table>
Controllerは…
<?php                                           Smartyクラスの読
require_once("libs/Smarty.class.php");          込
require_once("OrderEntity.class.php");
require_once("OrderDAO.class.php");
                                                   Smarty利用の準備
$oSmarty = new Smarty();
$oSmarty->template_dir = "./templates/";
$oSmarty->compile_dir = "./templates_c";
                                                     Mからデータ取得
$odCode = $_GET['odCode'];

$orderDAO = new OrderDAO();                              テンプレートに送るデータを
$orderEntity = $orderDAO->findyByPK($odCode);            セット
$oSmarty->assign("odCode", $orderEntity->getOdCode());
$oSmarty->assign("odDate", $orderEntity->getOdDate());
$oSmarty->assign("odTotal", number_format($orderEntity->getOdTotal()));
$oSmarty->assign("odName", $orderEntity->getOdName());
$oSmarty->assign("odAddress", $orderEntity->getOdAddress());
$oSmarty->assign("odTel", $orderEntity->getOdTel());

$oSmarty->display("sample01.tpl");                         Vの表示
?>
Smartyの準備1

Smartyのサイト(http://www.smarty.net/)から適切な
バージョンをダウンロード、解凍。
中にあるlibsディレクトリを今から記述する
Controllerから読み込めるところに配置する。
Smartyの準備2

Controllerから読み込めるところにテンプレート
ファイルを配置するディレクトリを作る。
同じく、テンプレートをコンパイルしたものを格
納するからディレクトリを作る。
テンプレートの作成

HTMLファイルにテンプレート変数を埋め込んだ
ファイル=テンプレートファイルを.tplとして作成
し、テンプレートを格納するディレクトリに入れ
る。
Smartyの読込

準備での配置にしたがってlibs/Smarty.class.phpを
読み込む。

  <?php
  require_once("libs/Smarty.class.php");
  require_once("OrderEntity.class.php");
  require_once("OrderDAO.class.php");
Smarty利用の準備

Smartyクラスをnew。
準備での配置にしたがってテンプレート関連ディ
レクトリを登録。
template_dirフィールドにテンプレートが入ってい
るディレクトリを指定。
compile_dirフィールドにコンパイル済みテンプ
レートを格納するディレクトリを指定。PHPからの
書き込み権限を与えておく。

 $oSmarty = new Smarty();
 $oSmarty->template_dir = "./templates/";
 $oSmarty->compile_dir = "./templates_c";
テンプレートに送るデータの
      セット

    Smartyクラスのassignメソッドを使ってテンプレー
    トに埋め込むデータをセット。
    第1引数が変数名文字列、第2引数が値。
$oSmarty->assign("odCode", $orderEntity->getOdCode());
$oSmarty->assign("odDate", $orderEntity->getOdDate());
$oSmarty->assign("odTotal", number_format($orderEntity->getOdTotal()));
$oSmarty->assign("odName", $orderEntity->getOdName());
$oSmarty->assign("odAddress", $orderEntity->getOdAddress());
$oSmarty->assign("odTel", $orderEntity->getOdTel());
Vの表示

Smartyクラスのdisplayメソッドを使って画面表示。
引数はテンプレート名。


 $oSmarty->display("sample01.tpl");
ところで…
<table border="1">
  <tr>
    <th>注文コード</th>
    <td>{$odCode}</td>
  </tr>
  <tr>
    <th>注文日時</th>


                                                         これ、
    <td>{$odDate|date_format:"%Y/%m/%d %H:%M:%S"}</td>
  </tr>
  <tr>
    <th>注文合計金額</th>
    <td>{$odTotal}円</td>
  </tr>
  <tr>
    <th>注文者氏名</th>
    <td>{$odName}</td>
                                                         なに?
  </tr>
  <tr>
    <th>注文者住所</th>
    <td>{$odAddress}</td>
  </tr>
  <tr>
    <th>注文者電話番号</th>
    <td>{$odTel}</td>
  </tr>
</table>
修飾子


 {$変数名|修飾子}という形で変数の値を加工するこ
 とができる。

{$odDate|date_format:"%Y/%m/%d %H:%M:%S"}
           ||
          日付のフォーマティングを行う
修飾子の種類1


分類      修正子             説明
文字列操作   capitalize      単語の先頭を大文字に変換
        lower           小文字に変換
        upper           大文字に変換
        cat             指定された変数を連結
        replace         置き換え
        regex_replace   正規表現による置換
書式設定    date_format     日付の書式設定
        string_format   文字列の書式設定
        default         初期値の設定
修飾子の種類2


分類       修正子          説明
特殊文字処理   strip        空白・改行・タブの削除
         strip_tags   マークアップタグの削除
         nl2br        改行文字を<br/>タグに置換
         escape       エスケープ処理
         spacify      文字の間に空白挿入
文字列操作    truncate     指定桁で文字列を切り捨て
         wordwrap     指定桁でワードラップ
         indent       インデント指定
修飾子の種類3


分類            修正子            説明
文章情報          count_characters 文字数取得
              count_paragraphs 段落数取得
              count_sentences センテンス数取得
              count_words    単語数取得


詳細は本家サイトのマニュアルを参照。
http://www.smarty.net/docs/ja/language.modifiers.tpl
修飾子は重ねられる


{$変数名|修飾子|修飾子|修飾子|…}と複数の修飾子
を重ねて使える。

 {$odMemo|escape|nl2br|default:"&nbsp"}
          ||
         エスケープして、改行文字を改行タグに変換する。
         さらに、もし値がない場合は空白文字を出力。
じゃあ、
これは?
テンプレートファイル(抜粋)は…
<section>
  {if $count == 0}
  <p>表示すべき情報はありません。</p>                          分岐
  {else}
  {$count}件ありました。
  <table border="1">
      <thead>
      <tr>
         <th>注文コード</th>
         <th>注文日時</th>
         <th>注文合計金額</th>
         <th>注文者氏名</th>
         <th>注文者住所</th>
         <th>注文者電話番号</th>
      </tr>
                                                                       ルー
      </thead>                                                         プ
      <tbody>
      {foreach from=$orderEntities item="orderEntity"}
         <tr>
            <td>{$orderEntity->getOdCode()}</td>
            <td>{$orderEntity->getOdDate()|date_format:"%Y/%m/%d %H:%M:%S"}</td>
            <td>{$orderEntity->getOdTotal()|number_format}</td>
            <td>{$orderEntity->getOdName()}</td>
            <td>{$orderEntity->getOdAddress()}</td>
            <td>{$orderEntity->getOdTel()}</td>
         </tr>
      {/foreach}
      </tbody>
  </table>
  {/if}
</section>
分岐

分岐の書式は
{if 条件}~{elseif 条件}~{/if}

<section>
  {if $count == 0}
  <p>表示すべき情報はありません。</p>
  {else}
  {$count}件ありました。
  <table border="1">
        ~略~
  </table>
  {/if}
</section>
ループ

     ループの書式は
     {foreach from=配列 item=各要素を格納する変数名}
     ~
     {/foreach}
<tbody>
{foreach from=$orderEntities item="orderEntity"}
   <tr>
      <td>{$orderEntity->getOdCode()}</td>
      <td>{$orderEntity->getOdDate()|date_format:"%Y/%m/%d %H:%M:%S"}</td>
      <td>{$orderEntity->getOdTotal()|number_format}</td>
      <td>{$orderEntity->getOdName()}</td>
      <td>{$orderEntity->getOdAddress()}</td>
      <td>{$orderEntity->getOdTel()}</td>
   </tr>
{/foreach}
</tbody>
ループのelse

     {foreach}~{foreachelse}~{/foreach}
     でループがなかった時の表示が書ける。
<tbody>
{foreach from=$orderEntities item="orderEntity"}
   <tr>
      <td>{$orderEntity->getOdCode()}</td>
      <td>{$orderEntity->getOdDate()|date_format:"%Y/%m/%d %H:%M:%S"}</td>
      <td>{$orderEntity->getOdTotal()|number_format}</td>
      <td>{$orderEntity->getOdName()}</td>
      <td>{$orderEntity->getOdAddress()}</td>
      <td>{$orderEntity->getOdTel()}</td>
   </tr>
{foreachelse}
   <tr>
      <td colspan=“6”>表示するリストはありません。</td>
   </tr>
{/foreach}
</tbody>
ところで、WEBレイアウトって…




                   共通部分がある
共通部分を別テンプレートに

           header.tpl

                           hoge.tpl

                navi.tpl




           footer.tpl
別テンプレートの挿入

共通部分を別tplにしてそれを読み込む。
{include file="パス"}

  <header>
    {include file="layout/header.tpl"}
  </header>
その他詳細は…


本家サイトのマニュアルを参照。
http://www.smarty.net/docs/ja/
CakePHP
再びModelに注目
例えば、以下のようなテーブル
orders
 フィールド         種別          NOT NULL   その他
od_code        INTEGER     YES        主キー / AUTO_INCREMENT
od_date        DATETIME    YES
od_total       INTEGER     YES
od_name        TEXT        YES
od_address     TEXT        YES
od_tel         TEXT        YES

members
フィールド            種別        NOT NULL   その他
mb_code          INTEGER   YES        主キー / AUTO_INCREMENT
mb_name_last     TEXT      YES
mb_name_first    TEXT      YES
mb_mail          TEXT      YES
主キーによる検索SQLは…



orders
 $sql1 = "SELECT * FROM orders WHERE od_code=:od_code";




members
 $sql2 = "SELECT * FROM members WHERE mb_code=:mb_code";
ほとんど同じやん!
ModelクラスのfindByPKメソッドは…
<?php                                                       <?php
class OrderDAO {                                            class MemberDAO {
   public function findyByPK($odCode) {                        public function findyByPK($mbCode) {
      $orderEntity = new OrderEntity();                           $memberEntity = new MemberEntity();
      try {                                                       try {
         $this->_db->query("SET NAMES utf8;");                       $this->_db->query("SET NAMES utf8;");
         $sql =                                                      $sql =
          "SELECT * FROM orders WHERE od_code=:od_code";               "SELECT * FROM members WHERE mb_code:mb_code";
         $stmt = $this->_db->prepare($sql);                          $stmt = $this->_db->prepare($sql);

       $stmt->bindParam(":od_code", $odCode);                         $stmt->bindParam(":mbCode", $mbCode);
       $result = $stmt->execute();                                    $result = $stmt->execute();
       while($row = $stmt->fetch()) {                                 while($row = $stmt->fetch()) {
          $orderEntity->setOdCode($row['od_code']);                     $memberEntity->setMbCode($row[„mb_code']);
          $orderEntity->setOdDate($row['od_date']);                     $memberEntity->setMbNameLst($row[„mb_name_last']);
          $orderEntity->setOdTotal($row['od_total']);                   $memberEntity->setMbNameFirst($row[„mb_name_first']);
          $orderEntity->setOdName($row['od_name']);                     $memberEntity->setMbMail($row[„mb_mail']);
          $orderEntity->setOdAddress($row['od_address']);             }
          $orderEntity->setOdTel($row['od_tel']);                    }
       }                                                             catch(PDOException $ex) {
     }                                                                  $expMessage = "<p>DB接続に失敗しました。<hr/>";
     catch(PDOException $ex) {                                          print($expMessage);
        $expMessage = "<p>DB接続に失敗しました。                               }
<hr/>";                                                              return $memberEntity;
        print($expMessage);                                      }
     }                                                      }
     return $orderEntity;                                   ?>
   }
}
?>
ほとんど同じやん!
Modelは
同じようなことを
 書くことが多い
書くのがめんどくさい!
そこで…
すんませんm(_ _)mほんと、もう、ベタで…
またまた、これを例にとると…




      CakePHPでのソースコードは…
Modelは…
<?php
class Order extends AppModel {
   var $name = 'Order';
   var $primaryKey = 'od_code';
}
?>
Controllerは…
<?php
class OrdersController extends AppController {
   public $name = 'Orders';

     function showOneOrder($id) {
        $data = $this->Order->findByOd_code($id);
        $this->set('data', $data);
     }
}
?>
Viewは…
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>CakePHP Sample01</title>
</head>
<body>
<header>
  <h1>CakePHP Sample01</h1>
</header>
<section>
  <table border="1">
    <tr>
       <th>注文コード</th>
       <td><?php print($data['Order']['od_code'])?></td>
    </tr>
    <tr>
       <th>注文日時</th>
       <td><?php print(strftime('%Y/%m/%d %H:%M:%S',strtotime($data['Order']['od_date'])))?></td>
    </tr>
    <tr>
       <th>注文合計金額</th>
       <td><?php print(number_format($data['Order']['od_total']))?>円</td>
    </tr>
    <tr>
       <th>注文者氏名</th>
       <td><?php print($data['Order']['od_name'])?></td>
    </tr>
    <tr>
       <th>注文者住所</th>
       <td><?php print($data['Order']['od_address'])?></td>
    </tr>
    <tr>
       <th>注文者電話番号</th>
       <td><?php print($data['Order']['od_tel'])?></td>
    </tr>
  </table>
</section>
</body>
</html>
え?
これだけ?
これだけです!
しかも、表示させてみると…
な、なんか、
色がついている…
オイシイ!
ということで、
ケーキの食べ方
CakePHPの準備

CakePHPのサイト
(http://cakephp.org/)か
ら適切なバージョンを
ダウンロード、解凍。
この状態ですでに動作
する。
TOPを表示させてみると…




                あかん所を表示してくれるので、
                そこに注目する
DB設定をする



app/Config/database.php.dafaultをコピーして、
database.phpとし、中を適切に書き換える。
                          class DATABASE_CONFIG {
                             public $default = array(
                                'datasource' => 'Database/Mysql',
                                'persistent' => false,
           database.php         'host' => 'localhost',
                                'login' => 'user',
                                'password' => 'password',
                                'database' => 'database_name',
                                'prefix' => '',
                                //'encoding' => 'utf8',
                             );
                          }
通常のControllerは…

       例えば、こんなアプリと
       して


              showList.php              showOneLine.php

表示画面              処理             表示画面         処理            表示画面




http://…/wow/hoge/showList.php

                                    http://…/wow/hoge/ showOneLine.php
CakePHPのControllerは…


    表示画面              処理                       表示画面                         処理     表示画面


                             <?php
                             class HogeController extends AppController {
                                public $name = 'Hoge';

                                  function showList() {
                                     …
                                  }

                                  function showOneLine() {
                                     …
                                  }
                             }
                             ?>


http://…/wow/hoge/showList
                                                               http://…/wow/hoge/ showOneLine
CakePHPの規約1


ひとつのユースケース(機能)でひと
つのControllerクラスを作る。
各処理はその中のメソッドとして実
装する。
クラス名は「○○Controller」とし、
ファイル名も同様に
「○○Controller.php」とする。
このファイルをapp/Controllerディレ
クトリに入れる。
CakePHPの規約2

 AppControllerを継承する。
 $nameにController名を設定。
 URLは
 http://ドメイン/アプリルート/コントローラー名/メソッド
 名
<?php
class HogeController extends AppController {
   public $name = 'Hoge';                      例えば、
   function showList() {                       これは、
      …                                        http://…/wow/hoge/showList
   }
}
?>
CakePHPの規約3


  Controllerで使用するViewファイルは
  コントローラー名のディレクトリを
  app/View/に作成し、
  「メソッド名のアンダーバー記
  法.ctp」
  ファイルとしておく。
  例えば、HogeControllerのshowListな
  ら、
  app/View/Hoge/show_list.ctp
  となる。
index

例えば、
http://…/wow/hoge/
の場合は、メソッド名がない

 「コントローラー名/」で終わる場合(メソッド名が
 ない場合)の処理は、indexメソッドに書く。
 Viewファイルは「index.ctp」。
Viewにデータを送る方法

        Controllerの各メソッド内で、
        $this->set(“変数名”, 値)
        View側では普通に変数として使用する


<?php
class HogeController extends AppController {
   function showList() {
      …
                                               <td><?php print($list)?></td>
      $this->set(„list', $listData);
   }
}
?>
Modelの作り方1

テーブル名を複数形にする。
(ex) members
主キーのカラム名をidとする。
INTEGER型のAUTO_INCREMENTのサロゲートキーとす
ると便利。
members
フィールド           種別        NOT NULL   その他
id              INTEGER   YES        主キー / AUTO_INCREMENT
mb_name_last    TEXT      YES
mb_name_first   TEXT      YES
mb_mail         TEXT      YES
Modelの作り方2

 AppModelを継承したクラスを作る。
 クラス名、ファイル名は、テーブル名
 を単数形にしたものとする。
 原則、1テーブル1モデルクラス。
 $nameにモデル名を設定する。
 このファイルをapp/Modelに置く。

<?php
class Member extends AppModel {
   public $name = 'Member';
}
?>
Modelの使い方


$usesフィールドに使用するModel名を配列で設定。
↑でModelがControllerに登録されるので、
$this->モデル名->モデルのメソッド
でDBを操作できる。
<?php
class MemberController extends AppController {
                                                    モデルの登録
   public $name = 'Member';
   public $uses = array('Member');

     function showList() {
        $memberList = $this->Member->find('all');
                                                    モデルの操作
        $this->set('memberList', $memberList);
     }
}
?>
SELECT系基本1

データ取得(SELECT)メソッドは
find($type, $params)
第1引数$typeは取得の方法。
 all: 条件に合う全レコードを取得。
 first: 条件に合う最初の1レコードを取得。
 list: id番号をキーとして特定のカラムの値だけが収められた配
 列を取得。セレクトボックスの生成に便利。
 count: レコード数を取得。
第1引数を省略すると、firstが適用される。
SELECT系基本2

第2引数$paramsはオプ
ション設定の連想配列(省            $params = array(
                          'conditions' => array('Model.field' => $thisValue),
略可)。主なものは以下の              'recursive' => 1,
通り。                       'fields' =>
                               array('Model.field1', 'DISTINCT Model.field2'),
 conditions: 条件。WHERE     'order' =>
 句に該当                           array('Model.created', 'Model.field3 DESC'),
                          'group' => array('Model.field'),
 fields: 取得するフィールド        'limit' => 15,
                          'page' => 3,
 order: 取得順。ORDER BY      'offset' => 4,
 に該当。                     'callbacks' => true
                        )
 group: グループ化。
 GROUP BYに該当。
findの結果

Modelの取得結果は連想配列                             Array
                                            (
に格納されている。                                      [0] => Array
                                                  (
                                                    [Member] => Array
                                                       (
                                                          [id] => 1
                                                          [mb_name_last] => 安室
                                                          [mb_name_first] => 令
                                                          [mb_mail] => rey@amuro.com
$memberList = $this->Member->find('all');              )
                                                  )
                                               [1] => Array
                                                  (
                                                    [Member] => Array
                                                       (
                                                          [id] => 2
                                                          [mb_name_last] => 神湯
                                                          [mb_name_first] => 美談
                                                          [mb_mail] => kamille@bidan.com
                                                       )
                                                  )
                                            )
その他便利なSELECT系

findAllByフィールド名(値)
で「フィールド=値」の条件に合致する全レコードを取
得 $memberList = $this->Member->findAllByMb_name_last("神湯");



findByフィールド名(値)
で「フィールド=値」の条件に合致する最初の1レコード
  $oneMember = $this->Member->findById(1);
を取得

 その他、詳細は本家サイトのマニュアルを参照。
 http://book.cakephp.org/2.0/en/models/retrieving-your-data.html
INSERT&UPDATE

INSERTとUPDATEは同一のメソッド
save($data, $validate, $fieldList)
を使う。引数はすべて省略可。
第1引数$dataは登録データの配列。
  形式は取得データと同じ。
  このデータ内に主キー項目があればUPDATE、なければINSERT。
第2引数$validateはデータチェックを行うかどうかをtrueか
falseで指定。
第3引数$fieldListはデータ登録のカラムを制限したい場合は
配列で指定。
$newMember = array(
         "mb_name_first"=>"枢木",
         "mb_name_last"=>"朱雀",
         "mb_mail"=>"suzaku@kururugi.net"           INSERT
      );
$this->Member->save($newMember);



$oldMember = array(
         "id"=>4,
         "mb_mail"=>"suzaki@kururugi.com"           UPDATE
      );
$this->Member->save($oldMember);




その他、詳細は本家サイトのマニュアルを参照。
http://book.cakephp.org/2.0/en/models/saving-your-data.html
DELETE
削除(DELETE)は
delete($id, $cascade)
  第1引数$idは主キー値。
                    $this->Member->delete(4);
  第2引数$cascadeは省略可。
  関連テーブルのレコードも削除するかどうかをtrueかfalseで指
  定。
条件指定の削除は
deleteAll($conditions, $cascade, $callbacks)
  第1引数$conditionsに条件を表す連想配列を指定。
  第2引数第3引数は省略可。
   $this->Member->deleteAll(array("mb_mail"=>"suzaki@kururugi.com"));

  その他、詳細は本家サイトのマニュアルを参照。
  http://book.cakephp.org/2.0/en/models/deleting-data.html
その他
便利なものなど
Relation

RDBのRはリレーション。
Modelでリレーションを設定                            public $hasMany = array(
                                                „Membergroup' => array(
するには、以下のフィール                                       „className' => „Membergroup',
ドを設定する。                                            „foreignKey' => „member_id„
                                                 )
   $hasOne                                 );

   $hasMany
   belongsTo
   hasAndBelongsToMany
詳細は本家サイトのマニュアルを参照。
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html
Validation


必須チェックや数値                       public $validate = array(
                                     „mb_name_last' => array(
チェックなど、Model側                          „notempty' => array(
で各カラムのValidationが                         „rule' => array(„notempty„),
                                          „message‟ => „名前(姓)は必須です。'
できる。                                   )
                                     )
$validateフィールドに                 );
ルールを記述。

  詳細は本家サイトのマニュアルを参照。
  http://book.cakephp.org/2.0/en/models/data-validation.html
Virtual fields


カラム同士の値の計算結果など、演算結果で導き出す
フィールドも設定できる。
$virtualFieldsフィールドにSQLを記述。

public $virtualFields = array(
      „mb_fullname' => „CONCAT(Member.mb_last_name, “ ”, Member.mb_first_name)'
);



     詳細は本家サイトのマニュアルを参照。
     http://book.cakephp.org/2.0/en/models/virtual-fields.html
Transactions


トランザクション               $dataSource = $this->Member->getDataSource();
                       $dataSource->begin();
制御も可能。                 $memberResult = $this->Member->save($newMember);
                       $orderResult = $this->Order->save($newOrder);
オススメは                  if(…) {
Controllerで制御。            $dataSource->commit();
                       }
                       else(…) {
                          $dataSource->rallback();
                       }

  詳細は本家サイトのマニュアルを参照。
  http://book.cakephp.org/2.0/en/models/transactions.html
参考書籍



CakePHP1.3によるWebアプリケーション開
発
http://www.amazon.co.jp/dp/4798026646/
え?
1.3?
時代は2系だよ、君!
        って、誰?
参考書籍



CakePHP2.1によるWebアプリケーション開
発
http://www.amazon.co.jp/dp/4798034185/
でも、一番いいのは
CakePHP Cookbook 2.x
http://book.cakephp.org/2.0/en/contents.html
ただし、
現状英語のみ!
Smarty+CakePHP
ところで、
    CakePHPの
Viewに注目してみる
たとえば…
ソースコードは…
<!DOCTYPE html>
<html>
<head>
   <meta charset="UTF-8">
   <title>CakePHP Sample02</title>
</head>
<body>
<header>
   <h1>CakePHP Sample02</h1>
</header>
<section>
<?php if(empty($memberList)) { ?>
<p>表示すべき情報はありません。</p>
<?php }
else { ?>
<?php print(count($memberList)) ?>件ありました。
<table border="1">
   <thead>
      <tr>
         <th>会員コード</th>
         <th>会員名</th>
         <th>メールアドレス</th>
      </tr>
   </thead>
   <tbody>
   <?php foreach($memberList as $key=>$member) { ?>
      <tr>
         <td><?php print($member['Member']['id']) ?></td>
         <td><?php print($member['Member']['mb_name_last']." ".$member['Member']['mb_name_first']) ?></td>
         <td><?php print($member['Member']['mb_mail']) ?></td>
      </tr>
   <?php } ?>
   </tbody>
</table>
<?php } ?>
</section>
</body>
</html>
PHPソースが混ざってる…
Model-Controllerは便利だが、
CakePHP
          Viewがちょっと…


          View-Controller分離は完璧だが、
Smarty
          Modelは自分で実装…
そこで…
CakePHP   Smarty
手順


←P.444~454に記載。
 Smartyライブラリのインストール
 →所定の場所にlibフォルダを入れる
 Smartyが使用するディレクトリの用
 意
 →所定の場所にフォルダを作成
 Smarty View Classのインストール
 →以下のURLからPHPファイルを取得
 し所定の位置にいれる
 http://cakeforge.org/snippet/detail.php?type=snippet&id=6
これでOK!
ただし、
CakePHP1.3 + Smarty2.6
時代は
CakePHP2.2 + Smarty3.1
     だよ、君!
                 だから、誰?
CakePHP2.2 + Smarty3.1
    で試してみる
情報を求めて
 SmartyViewClassを
取得するURLにアクセス
                              ↑
 http://cakeforge.org/snippet/detail.php?type=snippet&id=6
ショ、ショック…
ちなみに…




        Smarty連携の項目自体
        がなくなっていた…
もうええちゅうねん
困ったときにGoogle先生…
http://bakery.cakephp.org/articles/skler/2011/08/05/cakephp_2_0_0_beta_smarty_3
う、うごかない…
ということで、
    不肖新三
このソースを改造して
   とりあえず
動くようにしました!
あらためて…
CakePHP+Smarty準備手順1


Smartyライブラリのインストール
 Smartyのサイト
 (http://www.smarty.net/)から適切
 なバージョンをダウンロード、解
 凍。
 中にあるlibsディレクトリを
 「smarty」と名称変更。
 cakephpディレクトリのvendors
 ディレクトリに入れる。
CakePHP+Smarty準備手順2


Smartyが使用するディレクトリの用
意
 テンプレートをコンパイルしたものを
 格納する空ディレクトリとして
 cakephpの
 app/tmp/smarty/compile
 として作る。
CakePHP+Smarty準備手順3

Smarty View Classのインストール
 SmartyView.phpファイルを入手し、
 cakephpの
 app/View
 直下に配置する。
 入手は、この勉強会のサンプル自体を
 github
 https://github.com/architshin/histudy7
 に置いてあるので、このリポジトリの
 histudy7/cakesmarty/app/View/SmartyView.php
 を参照。
CakePHP+Smarty準備手順4

default.tplの配置
 app/View/Layouts/default.ctp
 をコピーしてSmarty記法に書き換えた
 default.tplを作成する。
 先のリポジトリのからコピーしても可。
CakePHP+Smarty利用方法


Controllerのフィールド$viewClassにSmartyを指定。
Viewファイルの拡張子は.tplで保存。
あとは、通常の記述方法。
 ModelとControllerはCakePHPのルール。
 ViewはSmartyのルール。
Controller

<?php
class MemberController extends AppController {
   public $name = 'Member';
   public $uses = array('Member');
   public $viewClass = 'Smarty';

     function showList() {
        $memberList = $this->Member->find('all');
        $this->set('memberList', $memberList);
        $this->set('memberListCount', count($memberList));
     }
}
?>
View: show_list.tpl(一部)
<section>
{if empty($memberList) }
<p>表示すべき情報はありません。</p>
{else}
{$memberListCount}件ありました。
<table border="1">
    <thead>
       <tr>
          <th>会員コード</th>
          <th>会員名</th>
          <th>メールアドレス</th>                                       Smartyでは配列のアクセスは
       </tr>                                                     $member[‘Member’][‘id’]
    </thead>
    <tbody>
                                                                 ではなく、
    {foreach from=$memberList item="member"}                     「.」でつなぐ
       <tr>
          <td>{$member.Member.id}</td>
          <td>{$member.Member.mb_name_last}&nbsp;{$member.Member.mb_name_first}</td>
          <td>{$member.Member.mb_mail}</td>
       </tr>
    {/foreach}
    </tbody>
</table>
{/if}
</section>
ということで、
CakePHP+Smarty
   便利です!
ぜひ、使ってみてください!
特に
CakePHP2.2 + Smarty3.1
で、
バグ報告ください!
      ただし、対応するかどうかは不明…
以上です。
太い
新ちゃん
と
細い
ワテさん
でした
ご清聴ありがとうございまし
      た!

More Related Content

What's hot

負荷テストことはじめ
負荷テストことはじめ負荷テストことはじめ
負荷テストことはじめKazumune Katagiri
 
ビギナーだから使いたいO/Rマッパー ~Tengを使った開発~
ビギナーだから使いたいO/Rマッパー ~Tengを使った開発~ビギナーだから使いたいO/Rマッパー ~Tengを使った開発~
ビギナーだから使いたいO/Rマッパー ~Tengを使った開発~Akabane Hiroyuki
 
HCEでなんちゃってType4のNDEFタグをつくる
HCEでなんちゃってType4のNDEFタグをつくるHCEでなんちゃってType4のNDEFタグをつくる
HCEでなんちゃってType4のNDEFタグをつくるHiroshi Tanaka
 
Yapc -asia 2012 lt @studio3104
Yapc -asia 2012 lt @studio3104Yapc -asia 2012 lt @studio3104
Yapc -asia 2012 lt @studio3104Satoshi Suzuki
 
Type 4 andefを自力で読む
Type 4 andefを自力で読むType 4 andefを自力で読む
Type 4 andefを自力で読むHiroshi Tanaka
 
PerlとSQLのいろいろ
PerlとSQLのいろいろPerlとSQLのいろいろ
PerlとSQLのいろいろTakuya Tsuchida
 
C#を始めたばかりの人へのLINQ to Objects
C#を始めたばかりの人へのLINQ to ObjectsC#を始めたばかりの人へのLINQ to Objects
C#を始めたばかりの人へのLINQ to ObjectsFumitaka Yamada
 
詳説ぺちぺち
詳説ぺちぺち詳説ぺちぺち
詳説ぺちぺちdo_aki
 
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~leverages_event
 
PHP classの教室
PHP classの教室PHP classの教室
PHP classの教室Yusuke Ando
 
J qmobiはjqueryから軽量化しているか
J qmobiはjqueryから軽量化しているかJ qmobiはjqueryから軽量化しているか
J qmobiはjqueryから軽量化しているかHisashi Aruji
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-Kazunari Hara
 
Local php-100828 2
Local php-100828 2Local php-100828 2
Local php-100828 2Akio Ishida
 
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020Fujio Kojima
 

What's hot (19)

負荷テストことはじめ
負荷テストことはじめ負荷テストことはじめ
負荷テストことはじめ
 
ビギナーだから使いたいO/Rマッパー ~Tengを使った開発~
ビギナーだから使いたいO/Rマッパー ~Tengを使った開発~ビギナーだから使いたいO/Rマッパー ~Tengを使った開発~
ビギナーだから使いたいO/Rマッパー ~Tengを使った開発~
 
HCEでなんちゃってType4のNDEFタグをつくる
HCEでなんちゃってType4のNDEFタグをつくるHCEでなんちゃってType4のNDEFタグをつくる
HCEでなんちゃってType4のNDEFタグをつくる
 
Teclab3
Teclab3Teclab3
Teclab3
 
Try Jetpack
Try JetpackTry Jetpack
Try Jetpack
 
Yapc -asia 2012 lt @studio3104
Yapc -asia 2012 lt @studio3104Yapc -asia 2012 lt @studio3104
Yapc -asia 2012 lt @studio3104
 
Django boodoo
Django boodooDjango boodoo
Django boodoo
 
Type 4 andefを自力で読む
Type 4 andefを自力で読むType 4 andefを自力で読む
Type 4 andefを自力で読む
 
PerlとSQLのいろいろ
PerlとSQLのいろいろPerlとSQLのいろいろ
PerlとSQLのいろいろ
 
C#を始めたばかりの人へのLINQ to Objects
C#を始めたばかりの人へのLINQ to ObjectsC#を始めたばかりの人へのLINQ to Objects
C#を始めたばかりの人へのLINQ to Objects
 
詳説ぺちぺち
詳説ぺちぺち詳説ぺちぺち
詳説ぺちぺち
 
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
「スピード」と「品質」を実現するPHP開発チームの取り組み~AngularJS+FuelPHP+AspectMock~
 
PHP classの教室
PHP classの教室PHP classの教室
PHP classの教室
 
swooleを試してみた
swooleを試してみたswooleを試してみた
swooleを試してみた
 
J qmobiはjqueryから軽量化しているか
J qmobiはjqueryから軽量化しているかJ qmobiはjqueryから軽量化しているか
J qmobiはjqueryから軽量化しているか
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-
 
Local php-100828 2
Local php-100828 2Local php-100828 2
Local php-100828 2
 
OSC京都2011
OSC京都2011OSC京都2011
OSC京都2011
 
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020
 

Similar to CakePHP+Smartyハイブリッドによるラクラク開発

Html5 Web Applications
Html5  Web ApplicationsHtml5  Web Applications
Html5 Web Applicationstotty jp
 
Mojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてるMojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてるjamadam
 
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)Hiroaki KOBAYASHI
 
[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2Atsuo Yamasaki
 
フラットなPHPからフレームワークへ
フラットなPHPからフレームワークへフラットなPHPからフレームワークへ
フラットなPHPからフレームワークへMasao Maeda
 
フラットなPHPからフレームワークへ
フラットなPHPからフレームワークへ フラットなPHPからフレームワークへ
フラットなPHPからフレームワークへ VOYAGE GROUP
 
MT meets PHP - PHP conference Kansai 2013
MT meets PHP - PHP conference Kansai 2013MT meets PHP - PHP conference Kansai 2013
MT meets PHP - PHP conference Kansai 2013純生 野田
 
SecurityとValidationの奇妙な関係、あるいはDrupalはなぜValidationをしたがらないのか
SecurityとValidationの奇妙な関係、あるいはDrupalはなぜValidationをしたがらないのかSecurityとValidationの奇妙な関係、あるいはDrupalはなぜValidationをしたがらないのか
SecurityとValidationの奇妙な関係、あるいはDrupalはなぜValidationをしたがらないのかHiroshi Tokumaru
 
モダンmod_perl入門 #yapcasia
モダンmod_perl入門 #yapcasiaモダンmod_perl入門 #yapcasia
モダンmod_perl入門 #yapcasia鉄次 尾形
 
eZ Publish勉強会9月〜テンプレート言語〜
eZ Publish勉強会9月〜テンプレート言語〜eZ Publish勉強会9月〜テンプレート言語〜
eZ Publish勉強会9月〜テンプレート言語〜ericsagnes
 
for JSDeferred Code Reading
for JSDeferred Code Readingfor JSDeferred Code Reading
for JSDeferred Code ReadingKenichirou Oyama
 
勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration勉強会force#4 Chatter Integration
勉強会force#4 Chatter IntegrationKazuki Nakajima
 
もにかじ2 lt @studio3104
もにかじ2 lt @studio3104もにかじ2 lt @studio3104
もにかじ2 lt @studio3104Satoshi Suzuki
 
2012 keynote-2
2012 keynote-22012 keynote-2
2012 keynote-2kmiyako
 
T sql の parse と generator
T sql の parse と generatorT sql の parse と generator
T sql の parse と generatorOda Shinsuke
 

Similar to CakePHP+Smartyハイブリッドによるラクラク開発 (20)

Html5 Web Applications
Html5  Web ApplicationsHtml5  Web Applications
Html5 Web Applications
 
Mojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてるMojoliciousをウェブ制作現場で使ってみてる
Mojoliciousをウェブ制作現場で使ってみてる
 
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
 
Inside Movable Type
Inside Movable TypeInside Movable Type
Inside Movable Type
 
[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2
 
フラットなPHPからフレームワークへ
フラットなPHPからフレームワークへフラットなPHPからフレームワークへ
フラットなPHPからフレームワークへ
 
フラットなPHPからフレームワークへ
フラットなPHPからフレームワークへ フラットなPHPからフレームワークへ
フラットなPHPからフレームワークへ
 
Ci tutorial
Ci tutorialCi tutorial
Ci tutorial
 
test
testtest
test
 
MT meets PHP - PHP conference Kansai 2013
MT meets PHP - PHP conference Kansai 2013MT meets PHP - PHP conference Kansai 2013
MT meets PHP - PHP conference Kansai 2013
 
MT meets PHP
MT meets PHPMT meets PHP
MT meets PHP
 
SecurityとValidationの奇妙な関係、あるいはDrupalはなぜValidationをしたがらないのか
SecurityとValidationの奇妙な関係、あるいはDrupalはなぜValidationをしたがらないのかSecurityとValidationの奇妙な関係、あるいはDrupalはなぜValidationをしたがらないのか
SecurityとValidationの奇妙な関係、あるいはDrupalはなぜValidationをしたがらないのか
 
モダンmod_perl入門 #yapcasia
モダンmod_perl入門 #yapcasiaモダンmod_perl入門 #yapcasia
モダンmod_perl入門 #yapcasia
 
eZ Publish勉強会9月〜テンプレート言語〜
eZ Publish勉強会9月〜テンプレート言語〜eZ Publish勉強会9月〜テンプレート言語〜
eZ Publish勉強会9月〜テンプレート言語〜
 
for JSDeferred Code Reading
for JSDeferred Code Readingfor JSDeferred Code Reading
for JSDeferred Code Reading
 
勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration
 
Ll xcode
Ll xcodeLl xcode
Ll xcode
 
もにかじ2 lt @studio3104
もにかじ2 lt @studio3104もにかじ2 lt @studio3104
もにかじ2 lt @studio3104
 
2012 keynote-2
2012 keynote-22012 keynote-2
2012 keynote-2
 
T sql の parse と generator
T sql の parse と generatorT sql の parse と generator
T sql の parse と generator
 

CakePHP+Smartyハイブリッドによるラクラク開発