zendで作られたWEBサイトのスマートフォン用を作ることになったのですが、zendでシステム化されているところは外注で作られた所らしく、 しかも暗号化されており、ソースコードも契約上もらえないという状況。 仕方がないので、既存の仕組みはそのままにしてCakePHPでスマートフォン版を作成する事にしました。 サーバー環境からPHP5.1なのでCakePHP1.3を使用しました。

目次

  • 基本
  • その他

基本

モデル

テーブルはCakePHPの命名規則には当てはまってないので、キーとテーブル名を指定して作成します。

class UserTbl extends AppModel { var $name = 'UserTbl'; function __construct () { $id = array( 'id' => false, 'table' => 'user_tbl', ); parent::__construct($id); $this->primaryKey = 'user_id'; } }
また、複合キーを使ったテーブルもあるのでそこは諦めてSQL直書きで対応する事にしました。
class UserImageTbl extends AppModel { var $name = 'UserImageTbl'; var $useTable = false; // 複合キーのため function findById($user_id, $image_id) { $sql = query($sql, array($user_id, $image_id)); if (count($userImage) === 1) { return $userImage[0]; } return $userImage; } }

コントローラ

viewに渡すために$this->dataにモデルからとった値を設定します。

$profile = $this->UserProfileTbl->read(null, $id); $this->data['ProfileBasic'] = $profile['UserProfileTbl'];
フォーム用モデル(バリデーションまで行う)とデータ登録用モデル(SQL発行)を別々に作成し、一つのフォームに一つのフォーム用モデル、 一つのテーブルに一つのデータ登録用モデル、という風に決めて作成しました。 取得後のキー名(テーブル名のキャメルケース)とフォームのキー名が違うので、フォームに渡す際や更新する際は都度設定する必要が有りましたが、その方がわかりやすいと思ったのでその様にしました。

ビュー

ヘルパーにモデル名とurlを指定して作成しました。

Form->create('Contact', array('url' => '/contact/', 'name' => 'contact-form'));?> Form->text('Contact.mail', array('class' => 'w0')); ?> Form->error('Contact.mail');?>

その他

ページング

複合キーの場合は、paginateも使用できないので自分で仕組みを作成する必要がありました。 ページングで必要な情報は、件数と表示するページの情報が最低限必要です。 件数はapp_model.phpに件数をFOUND_ROWS()を使って件数を返す関数を用意しました。

class AppModel extends Model { function found_rows () { $rows = $this->query('SELECT FOUND_ROWS();', false); if (!empty($rows)) { return $rows[0][0]['FOUND_ROWS()']; } return 0; } }
あとは、検索用のSQLでSQL_CALC_FOUND_ROWSを指定すれば全件数は取得できます。
$sql = query($sql, $param); $rows = $this->found_rows(); $result = array(); foreach ($users as $user) { $i = key(array_slice($user, 0, 1)); $result[]['UserTbl'] = $user[$i]; } return array($result, $rows); }
ページングのリンクは共通処理を行うコンポーネントを作成してリンクを生成するようにしました。
/*---------------------------------------------------------- 検索結果共通処理(ページング) ----------------------------------------------------------*/ function _setPagingLink ($query, $members, $all, $page, $type) { $this-&gt;set(&apos;query&apos;, $query); $this-&gt;set(&apos;members&apos;, $members); $this-&gt;set(&apos;all&apos;, $all); $maxpage = ceil($all / 10); // ページングリンク if ($page != 1) { $this-&gt;set(&apos;prev&apos;, &apos;<a href="/s/search/&apos;.$type.&apos;/?page=&apos;.($page - 1).&apos;&amp;&apos;.http_build_query($query).&apos;">前へ</a>&apos;.&quot;\n&quot;); } $start = ($page - 1) * 10; $end = $start + count($members); $this-&gt;set(&apos;counter&apos;, sprintf(&apos;%d件中/%d~%d件表示&apos;, $all, $start + 1, $end)); if ($page != $maxpage &amp;&amp; $maxpage != 0) { $this-&gt;set(&apos;next&apos;, &apos;<a href="/s/search/&apos;.$type.&apos;/?page=&apos;.($page + 1).&apos;&amp;&apos;.http_build_query($query).&apos;">次へ</a>&apos;.&quot;\n&quot;); } // セッション登録(検索結果戻る対策) $this-&gt;Session-&gt;delete(&apos;Search.back&apos;); $this-&gt;Session-&gt;write(&apos;Search.back.url&apos;, &apos;/s/search/&apos;.$type.&apos;/?page=&apos;.($page).&apos;&amp;&apos;.http_build_query($query)); $this-&gt;Session-&gt;write(&apos;Search.back.pagename&apos;, &apos;検索結果一覧&apos;); }

初めて使ったコンポーネント・プラグイン

SSL Component https://github.com/plank/secured →メソッド単位でSSLの切り替えができるのでめっちゃ便利でした。(ちょっとだけパフォーマンス悪くなる!?) Yalog: Yet Another Logger for CakePHP https://github.com/k1LoW/yalog →Log4phpが簡単に使える様になります。オリジナルのログローテーションクラスもLog4phpには引けをとらないと思いました。

参考になったサイト

AutoLoginComponentを参考に自動ログイン実装しました。 http://d.hatena.ne.jp/sanojimaru/20091210/1260447577 Auth Componentを使用したかったのですが、ユーザー認証がAPI経由で行う仕様だったので非常に参考になりました。http://weble.org/2011/04/05/cakephp-oauth