古いPHPアプリケーションの最新化



最近、いくつかの古いPHPアプリケーションを操作する機会が時折ありました。修正が必要ないくつかの一般的なアンチパターンに気づきました。この記事は、古いPHPアプリケーションを<ここにすばらしいフレームワークの名前を挿入>に書き直す方法ではなく、保守を容易にし、操作の手間を軽減する方法について説明しています。



アンチパターン#1:コード内の資格情報



これは私が遭遇した最悪のパターンの中で最も一般的です。多くのプロジェクトでは、バージョン管理されたコードは、データベースにアクセスするための名前やパスワードなどの重要な情報とともにハードコードされています。コードが特定の環境に関連付けられているため、ローカル環境を作成できないため、これは明らかに悪い習慣です。さらに、コードにアクセスできる人は誰でも、通常は実稼働環境に適した資格情報を見ることができます。



これを修正するには、どのアプリケーションでも機能する方法をお勧めします。phpdotenvパッケージをインストールします。これにより、環境ファイルを作成し、環境スーパー変数を使用して変数にアクセスできます。



2つのファイルを作成しましょう.env.example。1つはバージョン管理され、ファイルのテンプレートとして機能します。.env、資格情報が含まれます。ファイルは.envバージョン管理されていないため、に追加し.gitignoreます。これは公式ドキュメントで詳しく説明されています



ファイル.env.exampleに資格情報が一覧表示されます。



DB_HOST=
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=


そして、データ自体はファイルにあります.env



DB_HOST=localhost
DB_DATABASE=mydb
DB_USERNAME=root
DB_PASSWORD=root


通常のファイルで、以下をロードします.env



$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();


次に、を使用してアカウンティングデータに適用できます$_ENV['DB_HOST']



パッケージを「そのまま」操作で使用することはお勧めしません。これには、次の方が適しています。



  • Dockerベースのデプロイメントがある場合は、コンテナーのランタイムに環境変数を挿入し、可能であればサーバー側のHTTP構成に挿入します。
  • 環境変数をキャッシュして、すべての要求で.envを読み取るオーバーヘッドを回避します。これがLaravelのやり方です。


資格情報ファイルはGit履歴から削除できます



アンチパターン#2:Composerを使用しない



PHPMailerのような大きなライブラリを含むlibフォルダがあることは非常に人気がありました。バージョン管理に関しては、これをあらゆる方法で回避する必要があるため、これらの依存関係はComposerで管理する必要がありますそうすれば、使用されているパッケージのバージョンを確認し、必要に応じて更新するのが非常に簡単になります。



したがって、Composerをインストールし、それを使用して管理します。



アンチパターン#3:ローカル環境なし



私が使用したアプリケーションのほとんどには、本番環境という1つの環境しかありませんでした。





しかし、アンチパターン#1を取り除くことで、ローカル環境を簡単にカスタマイズできます。ブートパスなど、構成の一部がハードコーディングされている場合がありますが、これをに移動できます.env



Dockerを使用してローカル環境を作成します。古いプロジェクトでは、不要な、またはインストールできない古いバージョンのPHPを使用することが多いため、特にうまく機能します。PHPDockerの



ようなサービスを使用することも、小さなファイルを使用することもできますdocker-compose.yml



アンチパターン#4:パブリックフォルダを使用しないでください



これらの古いプロジェクトのほとんどは、ルートフォルダーからアクセスできることが判明しました。つまり、ルート内のすべてのファイルを公開して読むことができます。これは、攻撃者(kiddieスクリプトなど)がインクルードされたファイルに直接アクセスしようとした場合に特に悪いです。スクリプトがインクルードされたすべてのファイルに直接アクセスした場合、出力を判別できない可能性があるためです。ベンダーフォルダを開くことは悪い考えであるため、



明らかにこの状況は.envまたはComposerの使用と互換性がありません。はい、これを行うにはいくつかのトリックがあります。ただし、可能であれば、クライアントに公開されているすべてのPHPファイルをフォルダーに移動し、サーバー構成を変更して、このフォルダーがアプリケーションのルートフォルダーになるようにします。 私は通常これを行います:Public







  • dockerDockerに関連するファイル(Nginx config、PHP Dockerfileなど)用のフォルダー作成します
  • appビジネスロジック(サービス、クラスなど)を格納するフォルダーを作成します
  • publicクライアントに公開されているPHPスクリプトとリソース(JS / CSS)を格納するフォルダーを作成します。これは、クライアントの観点から見たアプリケーションのルートフォルダーです。
  • 私は、ファイルを作成.envして.env.example


アンチパターン#5:ひどいセキュリティ問題



PHPアプリケーション、特にフレームワークを使用しない古いアプリケーションは、多くの場合、深刻なセキュリティ問題に悩まされています。



  • クエリ内のパラメータのエスケープが不足しているため、SQLインジェクションの危険性があります。それらを防ぐには、PDOを使用してください。
  • エスケープされていないユーザーデータが表示されるため、XSSインジェクションの危険性があります。それらを防ぐためにhtmlspecialcharsを使用してください。
  • . , , , .
  • - CSRF-. Anti-CSRF, .
  • パスワードの暗号化が不十分です。多くのプロジェクトで、パスワードのハッシュにSHA-1やMD5が使用されているのを見てきました。箱から出してすぐに使えるPHP5.5は、BCryptを適切にサポートしています。これを使用しないのは、残念です。パスワードを快適に転送するために、ユーザーがログオンするときにデータベース内のハッシュを更新することを好みます。主なことは、列passwordがBCryptパスワードを収容するのに十分な長さであることを確認することです。VARCHAR(255)で問題ありません明確にするための疑似コードは次のとおりです。



    <?php
    //    :    $
    //  :     
    if (strpos($oldPasswordHash, '$') !== 0 &&
        hash_equals($oldPasswordHash, sha1($clearPasswordInput))) {
        $newPasswordHash = password_hash($clearPasswordInput, PASSWORD_DEFAULT);
    
        //   password
    
        //  :    
    }
    
    //   
    if (password_verify($clearPasswordInput, $currentPasswordHash)) {
        //  :    
    }
    
    //   :    
    


アンチパターン#6:テストなし



これは古いアプリケーションでは非常に一般的です。アプリケーション全体のユニットテストの作成を開始することはほとんど不可能なので、機能テストを作成できます。





これらは、アプリケーションのその後のリファクタリングによってアプリケーションが破損しないことを確認するのに役立つ高レベルのテストです。テストは簡単です。たとえば、ブラウザを起動してアプリケーションに入り、操作が成功したときのHTTPコードや、最終ページの対応するメッセージを待ちます。テストには、PHPUnit、Cypress、またはcodeceptionを使用できます



アンチパターン#7:エラー処理が不十分



何かが壊れた場合(または最も可能性が高い場合)、すぐに見つける必要があります。しかし、多くの古いアプリケーションは、PHPの寛大さに依存して、エラーをうまく処理しません。



それらを修正するには、できるだけ多くのエラーをキャッチしてログに記録できる必要があります。このトピックに関する良い記事があります



また、システムが特定の例外をスローした場合にエラーが発生する場所を見つけるのが簡単になります。



アンチパターン#8:グローバル変数



古いプロジェクトで働き始めるまで、二度と彼らに会うことはないと思っていました。グローバル変数は、コードの動作の読み取りと理解を予測不可能にします。要するに、それはです。



代わり依存関係インジェクションを使用することをお勧めします。これにより、使用するインスタンスと場所を制御できるためです。たとえば、Pimpleパッケージはうまく機能しています。



他に何を改善する必要がありますか?



アプリケーションの運命や予算に応じて、プロジェクトを改善するために実行できる手順がさらにいくつかあります。



まず、アプリケーションが古いバージョンのPHP(7未満)で実行されている場合は、更新してみてください。ほとんどの場合、これは大きな問題を引き起こしません。そしてmysql_ calls何よりも、もしあれば、呼び出しを取り除くのにほとんどの時間がかかります。これをすばやく修正するには、同様のライブラリを使用できますが、すべてのパラメータが同時にエスケープされるように、PDOのすべての要求を書き直すことをお勧めします



アプリケーションがMVCパターンを使用しない場合、つまりビジネスロジックとテンプレートが分離されている場合は、Smarty、Twig、Bladeなどのテンプレートライブラリ(PHPがテンプレート言語であることはわかっていますが、最新のライブラリの方がはるかに便利です)を追加します。



最後に、長期的には、LaravelやSymfonyなどの最新のPHPフレームワークでアプリケーションを書き直すのが最善です。安全でスマートなPHP開発に必要なすべてのツールが用意されています。アプリケーションが大きい場合は、ストラングラーパターン使用して、ビッグバンの書き換えを回避することをお勧めします。これは、ひどく終了する可能性があります。したがって、現在作業しているコードの部分を新しいシステムに移行し、古い作業部分がそれらに到達するまでそのままにしておくことができます。



これは、プロジェクトに応じて数週間または数か月間機能をフリーズすることなく、日常業務用の最新のPHP環境を作成できる効果的なアプローチです。



All Articles