バギーCakePHPコード:CakePHP開発者が犯す6つの最も一般的な間違い
公開: 2022-03-11CakePHPは素晴らしいPHPフレームワークですが、学習曲線が急です。 専門家になるには、かなりの研究と訓練が必要です。
私は幸運にもCakePHPを7年以上使用しており、その間、CakePHPコミュニティの多くのメンバーと協力できることを光栄に思っています。
このCakePHPチュートリアルでは、私が何年にもわたって見たいくつかの悪い習慣を説明し、これらの間違いを避けるための正しいアプローチを提案したいと思います。 これは私のコードが完璧だと言っているわけではありませんが、プログラマーとして私たちは常に学習しているので、ベストプラクティスに従い、学習しながら調整することが重要です。
この記事の内容は、CakeCodedからの投稿に触発されています。 CakePHPについて詳しく知りたい場合は、こちらの学習セクションにアクセスしてください。
よくある間違い#1:CakePHPのコーディング規約に従わない
CakePHPのコーディング規約はここで見ることができます。 他のプログラマーのコードを表示するときによく気付くいくつかのことを強調します。
制御構造。 プログラマーがこれを間違えたり、場合によっては他のコーディング言語から実践を取り入れたりすることがよくあります。 CakePHPは、次の構文を想定しています。
if ((expr_1) || (expr_2)) { // action_1; } elseif (!(expr_3) && (expr_4)) { // action_2; } else { // default_action; }
最初の括弧の前に1つのスペースがあり、最後の括弧と開き括弧の間に1つのスペースが必要です。 したがって、これは次のことが正しくないことを意味します。
if($this->request->data){ }
if
と(
、および)
と{
の間の間隔に注意してください
制御構造では、不要な場合でも常に中括弧を使用してください。 コードの可読性が向上し、論理エラーが少なくなります。
したがって、たとえば、次のように正しくありません。
if ($foo) $bar = true
これは次のようにフォーマットする必要があります。
if ($foo) { $bar = true }
最後に、ブラケットを配置する場所に注意してください。 角かっこを開くと、改行が開始されません。 そして、すべてのブラケットが一列に並んでいることを確認して、新しい各ブラケットが閉じブラケットと一直線になるようにします。
ここにいくつかの間違った例があります:
if ($foo) { $bar = true; }
これは正しくありません。開き角かっこは最初の行にある必要があります。
if ($foo) { $bar = true; if ($action) { $to = false; } }
インデントは正しく整列する必要があります。
プログラマーが「忙しすぎてコードをきれいにできない…」と言うのをよく耳にします。 私の答えは、「私を信じてください、きちんとしたコードは時の試練に耐えます」です。 読み取り不可能なCakePHPコードを書くことは、数か月以内に変更を加える必要がある場合に戻ってくるのは悪夢です。
よくある間違い#2:ORMでの包含可能な動作と再帰レベルの不適切な使用
私は最近、Facebookのデータベース開発者と非公式の話し合いをすることができて幸運でした。 私たちはCakePHPについて話し始め、彼は私にこう言いました。 それは恐ろしいことかもしれません。」 私は彼に何を意味するのか尋ねたところ、彼はオブジェクトリレーショナルマッピング(ORM)を使用すると、SQLクエリが不必要に大きくなるのは簡単だとコメントしました。
彼はある意味で正しい。 CakePHPの魔法の一部は、ORMの使用と、さまざまなデータベーステーブルの関係をグループ化する方法にあります。 デフォルトでは、CakePHPは関連する「所属」、「1つ」、「多数」のデータを自動的に選択します。これにより、非常に大きなSQLクエリが発生する可能性があります。 これらのクエリは、最初にアプリケーションを開発するときには問題にならない場合がありますが、ライブデータを収集してから6か月後に、アプリケーションが非常に遅くなり、クエリが最適化されていないとクラッシュする場合があります。
既存のウェブサイトを監査するとき、私は2つのことに注意します。 まず、デフォルトの再帰レベルが変更されましたか? デフォルトでは、CakePHPは再帰レベルを1に設定しますが、これは私の意見では高すぎます。 私は常に-1に設定してから、包含可能な動作を使用して関連するモデルを取得します。
それは私が探す2番目のことにつながります-Containable動作が使用されましたか? 私はよく新しいクライアントを訪ねてきて、CakePHPは遅いと言います。 その理由は、ほとんどの場合、Containableが使用されていないためです。 優れたCakePHPプログラマーは、舞台裏で行われる「自動魔法」の量に関係なく、SQLクエリを最適化します。
封じ込め可能な振る舞いはCakePHP1.2まで追加されませんでしたが、男の子はそれが違いを生みましたか?! SQLを最適化するのに非常に効果的な方法であるため、可能な限り包含可能を使用するようにしてください。 Containable動作を実装および使用する方法の詳細については、ここをクリックしてください。
よくある間違い#3:モデルではなくコントローラーでビジネスロジックを維持する
優れたCakePHPコードには、モデルファイルにロジックが含まれています。 これには慣れるのに少し時間がかかりますが、一度習得すると振り返ることはありません! コントローラーファイルは、MVCパターンで意図されているものに使用する必要があります-制御! したがって、コントローラーファイルを使用してユーザーアクションを処理し、ビジネスロジックをモデルファイルに入れます。
この良い例は、単純なCRUD、つまり日常のアクションです。 例として、ブログチュートリアルの投稿の追加機能を取り上げましょう。 デフォルトの追加機能は次のとおりです。
public function add() { if ($this->request->is('post')) { $this->Post->create(); if ($this->Post->save($this->request->data)) { $this->Session->setFlash(__('Your post has been saved.')); return $this->redirect(array('action' => 'index')); } $this->Session->setFlash(__('Unable to add your post.')); } }
このコントローラーアクションは単純な追加には問題ありませんが、投稿が追加されたときに管理者にメールを送信したり、投稿が追加されたときに別のモデルの関連付けを更新したりする場合はどうなりますか。 これは追加のロジックですが、このロジックをコントローラーファイルに含めるべきではありません。
代わりに、 Post.php
モデルでこのための関数を記述します。 おそらくこのようなもの:
public function addPost($data = array(), $emailAdmin = true) { $this->create(); $this->save($data); // update any other tables // send the email to the admin user if ($emailAdmin) { } // if all is successful return true; }
これにより、コントローラーのアクションが次のようにわずかに変更されます。
public function add() { if ($this->request->is('post')) { if ($this->Post->addPost($this->request->data)) { $this->Session->setFlash(__('Your post has been saved.')); return $this->redirect(array('action' => 'index')); } $this->Session->setFlash(__('Unable to add your post.')); } }
ご覧のとおり、 $this->Post->create()
がモデルファイルに移動されているため、新しいアクションは実際には1行少なくなっています。

これは、ロジックをモデルファイルに移動することをお勧めする、日常的な完璧な例です。これにより、コードベースがはるかにクリーンになります。
よくある間違い#4:頻繁に早く戻るのではなく、コードに複雑すぎることを追加する
これは常に少し進行中の議論ですが、頻繁に戻ること、そして早く戻ることは確かにはるかにきれいに見えるコードになります。 これは、何よりもモデルメソッドに当てはまります。
しかし、私は正確にはどういう意味ですか? さて、上記のCakePHPチュートリアルで追加したメソッドを見てみましょう。
public function addPost($data = array(), $emailAdmin = true) { $this->create(); $this->save($data); // update any other tables // send the email to the admin user if ($emailAdmin) { } // if all is successful return true; }
頻繁に戻り、早く戻るということは、関数を実行するときに、定期的にすべてが正常であることを確認することを意味します。 そうでない場合は、falseを返すか、CakePHPエラーを返します。
これを例で示すのが最も簡単かもしれません。 上記の関数を書くには2つの方法があります。
public function addPost($data = array(), $emailAdmin = true) { if ($data) { $this->create(); $result = $this->save($data); if ($result) { // update any other tables // send the email to the admin user if ($emailAdmin) { // send the admin email } } else { // problem saving the data return false; } // if all is successful return true; } else { // no data submitted return false; } }
コードがすぐに読めなくなる様子をご覧ください。 いたるところにif
とelse
があり、関数はすぐに1つの大きなインデントになります。 誤解しないでください。すっきりとしたインデントが大好きですが、関数が頻繁にreturnで記述されている場合は、関数がどのように見えるかを確認してください。
public function addPost($data = array(), $emailAdmin = true) { if (!$data) { // no data submitted return false; } $this->create(); $result = $this->save($data); if (!$result) { // problem saving the data return false; } // update any other tables // send the email to the admin user if ($emailAdmin) { // send the admin email } // if all is successful return true; }
すぐに、この小さな例では、コードに1つのインデントしかなく、はるかに読みやすいことがわかります。 ロジックは実際にはもっと理にかなっています。ロジックを1行ずつ実行し、途中で問題が発生した場合は、エラーを返し、次の行に進まないでください。
これにより、CakePHPプログラマーは、私たちが読んだのと同じ方法でコードを書くことができます。つまり、コードを異なるブロックではなく、左から右、上から下に読み取るため、すぐに混乱する可能性があります。
よくある間違い#5:DRYの原則を使用しない
DRYはDon'tRepeat Yourselfの略で、CakePHPでコーディングするときに従うべき哲学です。 オブジェクト指向コードでは、同じコードブロックを2回繰り返す言い訳はありません。
繰り返さないようにするためのCakePHPのヒントをいくつか紹介します。
上記のように、ロジックを共有できるように、モデルファイルにロジックを配置することを目指します。
ビューファイルで、ビューを繰り返す場合は、要素として、またはカスタムヘルパーとしてビューコードを作成します。
いくつかの構成設定をセットアップします
app/Config/bootstrap.php
ファイルはこれに最適な場所です。 これは、アプリケーション名やメインの電子メールアドレスなどをハードコーディングしていないことを確認するのに役立ちます。 クライアントがアプリケーションの電子メールアドレスを更新するように要求したという理由だけで、あなたがしたい最後のことは何百ものファイルを調べることです。「コードを繰り返す場合、このコードを書くためのより良い方法はありますか?このコードを適切な場所に配置していますか?」と常に自問してください。 コードを繰り返す必要がある場合は、より適切に記述できる可能性があります。
よくある間違い#6:コードにコメントしない
最後にコメントについてです。 まず、ドキュメントのブロック。 ドキュメントブロックは、メソッドまたはアクションをドキュメント化するときです。 関数が何をしているのかを少し記録するのに1分しかかかりませんが、コードの可読性の点でそのような違いがあります。
CakePHP Doc Blocksは、ページの左マージンに合わせる必要があります。 したがって、上記のコードを使用した簡単な例です。
/** * Adds & saves a post as well as emails the admin to let them know the post has been added. * Also performs some saving to another table * * @param array $data The post data * @param bool $emailAdmin If set to true, will email the website admin * @return bool Returns true if successful */ public function addPost($data = array(), $emailAdmin = true) {
ご覧のとおり、docブロックを作成するのにそれほど時間はかかりませんが、コードの寿命という点で大きな違いがあります。 最終的には、コードが開発者としてあなたを超えて生き続けることができることを意味します。
同様にインラインコメント付き。 コードが何をしているのか、そしてその理由を説明することを恐れないでください! 特に別の開発者がコードを見ている場合は、長期的にはコードを理解しやすくなります。
要約
CakePHPは、広範囲にわたるフル機能のフレームワークです。 設定より規約に従うことを考えると、CakePHPは、ユーザーがコードをレイアウトする特定の方法に従うように「強制」されるという意味で、他のPHPベースのフレームワークよりも厳密です。 これは物議を醸す可能性がありますが、私の経験では、より一貫性があり、読みやすく、理解しやすいコードベースにつながります。開発者にコードの記述方法を「選択」させるのではなく、開発チームはCakeの規則に従って一貫性のあるコードを記述します。 。
このCakePHPチュートリアルに従い、コードが適切に記述されていることを確認することで、アプリケーションは時の試練に耐えることができます。 コードは常に明日のために書かれるべきです-別の開発者が数年後に特定のコードブロックを見ている場合、彼はコードを理解し、期待される標準に固執するでしょう。 CakePHPも例外ではなく、このガイドがいくつかの悪い習慣を修正するのに役立つことを願っています。