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->set('query', $query); $this->set('members', $members); $this->set('all', $all); $maxpage = ceil($all / 10); // ページングリンク if ($page != 1) { $this->set('prev', '<a href="/s/search/'.$type.'/?page='.($page - 1).'&'.http_build_query($query).'">前へ</a>'."\n"); } $start = ($page - 1) * 10; $end = $start + count($members); $this->set('counter', sprintf('%d件中/%d~%d件表示', $all, $start + 1, $end)); if ($page != $maxpage && $maxpage != 0) { $this->set('next', '<a href="/s/search/'.$type.'/?page='.($page + 1).'&'.http_build_query($query).'">次へ</a>'."\n"); } // セッション登録(検索結果戻る対策) $this->Session->delete('Search.back'); $this->Session->write('Search.back.url', '/s/search/'.$type.'/?page='.($page).'&'.http_build_query($query)); $this->Session->write('Search.back.pagename', '検索結果一覧'); }初めて使ったコンポーネント・プラグイン
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