ホームページ > バックエンド開発 > PHPチュートリアル > PHP フレームワーク: 避けるべき隠れたエラー

PHP フレームワーク: 避けるべき隠れたエラー

Susan Sarandon
リリース: 2025-01-04 12:16:35
オリジナル
978 人が閲覧しました

PHP Frameworks: hidden errors to avoid

Symfony (執筆時点では 7.2) や Laravel などのフレームワークは高度にカスタマイズ可能であり、経験やスキルに関係なく、優れたプラクティスを奨励します。

ただし、デザイン、セキュリティ、パフォーマンスの問題が発生する可能性があります。

Symfony: $container を直接呼び出さないでください

❌ これは古典的ですが、開発者によって今でも頻繁に使用されています:

 class LuckyController extends AbstractController
  {
      public function index()
       {
        $myDependency = $this->container->get(MyDependencyInterface::class);
        // 
       }
ログイン後にコピー
ログイン後にコピー

親 AbstractController が $container を保護済みとして定義しているため、これが可能です。

protected ContainerInterface $container;
ログイン後にコピー
ログイン後にコピー

出典: Symfony - GitHub

これは機能しますが、さまざまな理由から悪い習慣です。

  • 可読性が損なわれます
  • テストするのは難しい
  • グローバル状態 ($container) に依存します
  • Symfony が進化するにつれて、将来的に非互換性の問題が発生する可能性があります

✅ 代わりにコンストラクターで依存関係の注入を使用します:

 class LuckyController extends AbstractController
  {
      public function __construct(private MyDependencyInterface $myDependency) {}
ログイン後にコピー
ログイン後にコピー

Eloquent ORM: 生のクエリを盲目的に使用しないでください

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 が必要になる場合があります。

Laravel: CSRF についてはどうですか?

CSRF 攻撃では、ハッカーはエンド ユーザーに、現在認証されているアプリ上で望ましくないアクションの実行を強制します。

Laravel には、そのようなシナリオを防ぐためのメカニズムが組み込まれています。

大まかに言うと、リクエストと一緒に送信されるトークン (隠しフィールド) を追加して、「認証されたユーザーが実際にアプリケーションにリクエストを送信している本人である」ことを検証できます。

まあまあです。

❌ ただし、一部のアプリではこの実装が省略されます。

✅ 組み込みミドルウェアを使用するかどうかはここでは関係ありませんが、アプリが CSRF 攻撃から保護されていることを確認してください。

Laravel での実装の詳細については、このページをお読みください。

AJAX リクエストも保護してください。

Eloquent ORM: クエリは「自動的に」最適化されない

Eloquent は、積極的/遅延読み込みを可能にし、クエリ キャッシュ、インデックス作成、バッチ処理などのさまざまな最適化をサポートします。

ただし、特に大規模なデータセットでのパフォーマンスの問題をすべて回避できるわけではありません。

❌ このようなループが発生するのは珍しいことではありません:

 class LuckyController extends AbstractController
  {
      public function index()
       {
        $myDependency = $this->container->get(MyDependencyInterface::class);
        // 
       }
ログイン後にコピー
ログイン後にコピー

ただし、メモリの問題が発生する可能性があります。

✅ 可能な場合、より良いアプローチは、Laravel コレクションとチャンクのようなヘルパーを活用することです。

protected ContainerInterface $container;
ログイン後にコピー
ログイン後にコピー

詳細については、ドキュメントを確認してください。

注意: これは機能しますが、これらのヘルパーは実装を容易にすることのみを目的としているため、遅いクエリやその他のボトルネックを監視する必要があることを忘れないでください。

Symfony: SRP サービス

ドキュメントには次のように書かれています:

有用なオブジェクトはサービスと呼ばれ、各サービスはサービス コンテナと呼ばれる非常に特別なオブジェクト内に存在します。コンテナを使用すると、オブジェクトの構築方法を一元化できます。これにより、作業が容易になり、強力なアーキテクチャが促進され、超高速になります!

言い換えると、アプリケーションの特定の責任を処理するカスタム サービスを作成します。

❌ ドキュメントは正しいです。強力なアーキテクチャを促進することを目的としていますが、単一責任原則 (SRP) に違反するサービスを読み取ることは珍しくありません:

 class LuckyController extends AbstractController
  {
      public function __construct(private MyDependencyInterface $myDependency) {}
ログイン後にコピー
ログイン後にコピー

✅ その原則を尊重しなければなりません。テストと保守が容易になります。

Symfony: パブリック サービスとプライベート サービス

❌ Symfony では、$container->get('service_id') を使用して任意のパブリック サービスを呼び出すことができます。

$container をそのように呼び出すことは悪い習慣であると考えられることを前に見ました。

すべてのサービスを公開したいという誘惑には抵抗できないかもしれません。そうすれば、プロジェクトのほぼどこでもサービスを ID で取得できます。

それはやめてください。

✅ 代わりに、ほとんどのカスタム サービスを非公開にし、依存関係の注入を使用します。

まとめ

フレームワークで私が「潜在的なエラー」または「隠れたエラー」と呼ぶものを避けていただければ幸いです。

実装方法がわからない場合は、フレームワークを信頼してください。ただし、一部のメカニズムはデフォルトでは有効になっていない可能性があることに注意してください。

以上がPHP フレームワーク: 避けるべき隠れたエラーの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート