Symfony (執筆時点では 7.2) や Laravel などのフレームワークは高度にカスタマイズ可能であり、経験やスキルに関係なく、優れたプラクティスを奨励します。
ただし、デザイン、セキュリティ、パフォーマンスの問題が発生する可能性があります。
❌ これは古典的ですが、開発者によって今でも頻繁に使用されています:
class LuckyController extends AbstractController { public function index() { $myDependency = $this->container->get(MyDependencyInterface::class); // }
親 AbstractController が $container を保護済みとして定義しているため、これが可能です。
protected ContainerInterface $container;
出典: Symfony - GitHub
これは機能しますが、さまざまな理由から悪い習慣です。
✅ 代わりにコンストラクターで依存関係の注入を使用します:
class LuckyController extends AbstractController { public function __construct(private MyDependencyInterface $myDependency) {}
Eloquent を使用すると、SQL クエリを非常に簡単に作成できます。
開発者は、SQL クエリを直接記述する代わりに、PHP ラッパーを使用してデータベース エンティティと対話できます。
バックグラウンドで SQL バインディングも使用するため、信頼できない入力であっても、無料でインジェクション保護が得られます。
User::where('email', $request->input('email'))->get();
❌ ただし、whereRaw のようなヘルパーを使用すると、脆弱性が発生する可能性があります。
User::whereRaw('email = "'. $request->input('email'). '"')->get();
✅ 少なくとも、常に SQL バインディングを使用してください:
User::whereRaw('email = :email', ['email' => $request->input('email')])->get();
注意: 上記の例は意味がありませんが、物事を単純にしています。実際のユースケースでは、最適化の目的、または非常に特殊な where 条件を実装するために whereRaw が必要になる場合があります。
CSRF 攻撃では、ハッカーはエンド ユーザーに、現在認証されているアプリ上で望ましくないアクションの実行を強制します。
Laravel には、そのようなシナリオを防ぐためのメカニズムが組み込まれています。
大まかに言うと、リクエストと一緒に送信されるトークン (隠しフィールド) を追加して、「認証されたユーザーが実際にアプリケーションにリクエストを送信している本人である」ことを検証できます。
まあまあです。
❌ ただし、一部のアプリではこの実装が省略されます。
✅ 組み込みミドルウェアを使用するかどうかはここでは関係ありませんが、アプリが CSRF 攻撃から保護されていることを確認してください。
Laravel での実装の詳細については、このページをお読みください。
AJAX リクエストも保護してください。
Eloquent は、積極的/遅延読み込みを可能にし、クエリ キャッシュ、インデックス作成、バッチ処理などのさまざまな最適化をサポートします。
ただし、特に大規模なデータセットでのパフォーマンスの問題をすべて回避できるわけではありません。
❌ このようなループが発生するのは珍しいことではありません:
class LuckyController extends AbstractController { public function index() { $myDependency = $this->container->get(MyDependencyInterface::class); // }
ただし、メモリの問題が発生する可能性があります。
✅ 可能な場合、より良いアプローチは、Laravel コレクションとチャンクのようなヘルパーを活用することです。
protected ContainerInterface $container;
詳細については、ドキュメントを確認してください。
注意: これは機能しますが、これらのヘルパーは実装を容易にすることのみを目的としているため、遅いクエリやその他のボトルネックを監視する必要があることを忘れないでください。
ドキュメントには次のように書かれています:
有用なオブジェクトはサービスと呼ばれ、各サービスはサービス コンテナと呼ばれる非常に特別なオブジェクト内に存在します。コンテナを使用すると、オブジェクトの構築方法を一元化できます。これにより、作業が容易になり、強力なアーキテクチャが促進され、超高速になります!
言い換えると、アプリケーションの特定の責任を処理するカスタム サービスを作成します。
❌ ドキュメントは正しいです。強力なアーキテクチャを促進することを目的としていますが、単一責任原則 (SRP) に違反するサービスを読み取ることは珍しくありません:
class LuckyController extends AbstractController { public function __construct(private MyDependencyInterface $myDependency) {}
✅ その原則を尊重しなければなりません。テストと保守が容易になります。
❌ Symfony では、$container->get('service_id') を使用して任意のパブリック サービスを呼び出すことができます。
$container をそのように呼び出すことは悪い習慣であると考えられることを前に見ました。
すべてのサービスを公開したいという誘惑には抵抗できないかもしれません。そうすれば、プロジェクトのほぼどこでもサービスを ID で取得できます。
それはやめてください。
✅ 代わりに、ほとんどのカスタム サービスを非公開にし、依存関係の注入を使用します。
フレームワークで私が「潜在的なエラー」または「隠れたエラー」と呼ぶものを避けていただければ幸いです。
実装方法がわからない場合は、フレームワークを信頼してください。ただし、一部のメカニズムはデフォルトでは有効になっていない可能性があることに注意してください。
以上がPHP フレームワーク: 避けるべき隠れたエラーの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。