トラブル別!CakePHP1.1 → 1.2 アップグレードの注意点
順調に思えたダイエットも、早くも停滞期を迎えたkimotoです。目標はあと19キロ。
さて、CakePHP1.2 も安定版となって半年近く経ちました。
以前に 1.1 で開発したけど、リニューアルなどの機会に 1.2 にあげるぞ!なんて人も多いかと思います。
まさにシーブレインでもそのような機会がありました。
そこで今回は、このようなトラブルに見舞われたらこうしたら良いよ!というのを集めてみました。参考になれば幸いです。
まずは総入れ替え
まずは、「cake」フォルダの中身を 1.1 から 1.2 に入れ替える事から始めます。
はい、予想通り、動かなくなりました。
では、エラーを見ていきましょう。あ、debug モードにするのを忘れないでくださいね。
Fatal error: Call to a member function connect() on a non-object
エラーメッセージを見ると、connect() って関数の呼び出し方に問題があると言ってるごようす。
指定の通り「routes.php」を確認すると、1.1 と 1.2 では書き方が違います。
$Route->connect
↓
Router::connect
これで解決できました。
Call to undefined function vendor()
vendor関数を利用していると、「vendor() なんて関数はねえよ!」と怒られます。
これも 1.2 では書き方が変わっているので注意が必要です。
どこかで vendor 関数を使っている場合は、以下のように書き換えましょう。
ファイル名の拡張子を略さずに書くのもポイントです。
vendor('dBug'.DS.'dBug');
↓
App::import('Vendor', 'dBug', array('file' => 'dBug'.DS.'dBug.php'));
「generateList」が無いといわれる
「generateList」は、1.2 から非推奨になりました。非推奨になっただけで、使えるのだとばかり思ってたんですが、残してはくれていないようです。
「generateList」を使用している箇所をすべて「find」関数に置き換えるのが確実なのですが、数が多かったりすると漏れが出たりするし、なにより面倒ですね。
ということで、代わりに関数を用意して、それに置き換えましょう。
app_model に以下の関数を用意します。
function getlist ($cond=null,$order=null,$limit=null,$key='id',$val='name') {
return $this->find("list",array(
'conditions' => $cond,
'order' => $order,
'limit' => $limit,
'fields' => array(str_replace('{n}.','',$key), str_replace('{n}.','',$val))
)
);
}
そして、generateList を getList に置換してしまいましょう。
こちらを参考しました。このままではうまくいかない場合もあるため、引数の既定値を変えています。
ヘルパのフォーム関連軒並みエラー
1.1 で使われていた html ヘルパは非推奨になり、代わりに form ヘルパを利用する事が推奨されています。
具体的にどう変えるかを書いてみます。
$html
↓
$form
基本はこれです。ただ、他にも記法はかなり変わってますので注意が必要です。
$html->input
↓
$form->text
「input」のままでも form ヘルパは使えますが、意味合いが変わってくるので注意です。
$html->radio('Project/complete', $complete_params, ' ', , false);
$html->selectTag('Project/group_id', $group_params, null, null, false, 1);
$html->tagErrorMsg('Project/name', '入力されていません')
↓
$form->radio('Project.complete', $complete_params, array());
$form->select('Project.group_id', $group_params, null, null, true);
$form->error('Project.name', '入力されていません')
引数の数や位置のほかにも、メソッド名も変わっています。
また、1.1 では「true」の代わりに「1」でも通ったんですが、1.2 ではキチンと指定してやる必要があります。
そしてもう一点。「'Project/name'」などと指定できたデータのパスですが、「'Project.name'」のようにドットでつなげないとうまくいきません。こちらも要注意ですね。
その他、細かい違い
たとえば、1.2 では「LoadModel」は使えません。モデルを読み込む方法はいくつかありますが、この場合 App::import を利用すると良いと思います。
loadModel('Project');
↓
App::import('Model', 'Project');
$model->find(); で利用する条件ですが、「大なり」などの条件は、配列のキー側に持つようにします。
$cond = array(
"start_date" => "< {$date_string}",
"end_date" => "> {$date_string}",
);
↓
$cond = array(
"start_date <" => $date_string,
"end_date >" => $date_string,
);
その他、細かい部分でも違いは沢山あります。以下に列挙します。
- $_SESSION を直に参照はできない。セッションコンポーネントを使い、$this->session->read と読み取るようにする
- $model->findBySql() は使えない。$model->query() を使う
- コントローラで、exit するとレンダリングされない(1.1 はされる)
まとめ
問題が起きそうな部分に焦点を当ててみました。いかがでしょうか。
おそらく、他にもたくさんひっかかる場所はあると思われますが、それでもアップグレードする価値が、1.2 にはあると思います。
また、他にこんな問題が起きたぜ!みたいな事がありましたら、是非教えてください。