PHP で静的コード分析を実行する

Syed Hassan Sabeeh Kazmi 2023年10月8日
  1. lint モードを使用して PHP で静的コード分析を実行する
  2. PHPMD または PHP Depend プロジェクトを使用して PHP で静的コード分析を実行する
  3. pfff ツールを使用して PHP で静的コード分析を実行する
  4. HHVM を使用して PHP で静的コード分析を実行する
PHP で静的コード分析を実行する

開発の重要な部分は、エラーを特定し、コードベースから迅速に排除することです。PHP でこれを達成するためにコーディングまたは静的コード分析を実行できます。 このチュートリアルでは、PHP で lint モードとその他のいくつかのメソッドを使用して静的コード分析を実行する方法を説明します。

静的コード分析は、バグを検出し、一般的な開発者の生産性を向上させ、オートコンプリートし、厳密に型指定された PHP コードの多くの型関連機能を使用してコードをリファクタリングするための優れた方法です。 実行またはコンパイルの前に、ソース コードをチェックして構文エラーを排除し、PHP コーディング標準とスタイルを適用して、コード内のセキュリティの脆弱性を検出できます。

lint モードは、PHP で静的コード分析を実行するための最良の方法の 1つです。さらに php lintPHPMDpfff、および HHVM について学習し、自分に合った 1つのアプローチを採用します。 より良い必要があります。 これは PHP の型システムに大きく依存しており、静的解析に提供する情報が多いほど、より良い結果が得られます。コードで型を宣言することは、より多くの情報を追加する 1つの方法です。

注目の投稿のリストを取得する関数 function exp_funct ($args) {}function exp_funct (array $args) : array {} として宣言して、静的コード分析の詳細情報を提供できます。 あるいは、PHPDoc コメントを追加して、関数を宣言する前に // @return array<exp_var> などで関数の入力と出力の型を宣言または初期化することもできます。

lint モードを使用して PHP で静的コード分析を実行する

Lint PHP モードは、静的コード分析を実行して構文エラーをチェックし、未使用の変数割り当て、初期化なしで割り当てられた配列、コード スタイルの警告などを特定するための最良の方法の 1つです。 PHP を実行して php -l FILENAME を使用し、シェルまたはその他のコマンド ラインから lint モードで実行せずに構文を検証できます。

インターネット上には、PHP Lint に基づく高レベルおよび低レベルの静的アナライザーが多数あります。 たとえば、php-satPHPStanPHP-CS-Fixer、および phan は、高レベルの静的アナライザーの一部です。 一方、PHP Parsertoken get all (プリミティブ関数) は、PHP Lint に基づく下位レベルのアナライザーの一部です。

指定されたソースを token_get_all(string $code, int $flags = 0): array のような PHP トークンに分割できます。token_get_all は、Zend を使用して、指定されたコード文字列を PHP 言語トークンに解析するのに役立ちます。 エンジンの lexical スキャナー。 TOKEN_PARSE パラメーター フラグは、特定のコンテキストで予約語を使用する機能を認識し、トークン識別子の配列を返すのに役立ちます。

このメソッドから返される各トークン識別子は、トークン インデックス、元のトークンの文字列の内容、要素 0、1、2 の行番号をそれぞれ含む単一の文字または 3 要素の配列です。 token_get_all() の例が 2つあります。 1つは一般的な使用であり、もう 1つは予約語を使用してクラスで実行することです。

<?php
    $userQuota_getToken = token_get_all('<?php echo; ?>');

    foreach ($userQuota_getToken as $get_tokenQ) {
        if (is_array($get_tokenQ)) {
            echo "Line {$get_tokenQ[2]}: ", token_name($get_tokenQ[0]), " ('{$get_tokenQ[1]}')", PHP_EOL;
        }
    }
?>

// 2nd example on class

/*

$token_quota_source = <<<'code'

class A
{
    const PUBLIC = 1;
}
code;

$userQuota_getToken = token_get_all($token_quota_source, TOKEN_PARSE);

foreach ($userQuota_getToken as $get_tokenQ) {
    if (is_array($get_tokenQ)) {
        echo token_name($get_tokenQ[0]) , PHP_EOL;
    }
}

*/

// its output will be something similar
/*

T_OPEN_TAG
T_WHITESPACE
.
.
.
T_CLASS
T_WHITESPACE
T_STRING
.
.

*/

出力:

Line 1: T_OPEN_TAG ('<?php ')
Line 1: T_ECHO ('echo')
Line 1: T_WHITESPACE (' ')
Line 1: T_CLOSE_TAG ('?>')

さらに、ランタイム アナライザーは lint モードで動作し、このプログラミング言語の動的な性質により、いくつかの場合により便利です。 Xdebug は、コード カバレッジと関数トレーサーを備えたランタイム アナライザーです。

phpweaver には Xdebug 関数トレースがあり、静的/動的アプローチを組み合わせてコード分析を実行します。 実稼働サーバー用の静的コード アナライザーを探している場合、xhprof は、Xdebug に似た最高の lint モードの静的アナライザーですが、軽量で、PHP ベースのインターフェイスが含まれています。

PHPMD または PHP Depend プロジェクトを使用して PHP で静的コード分析を実行する

PHP Mess Detector の略で、有名な Java PMD ツールと同等の静的コード アナライザーを目指している PHP Depend のスピンオフ プロジェクトです。 composer を使用して、PHP_Dependcurl -s http://getcomposer.org/installer | をインストールできます。 php および php composer.phar には pdepend/pdepend:2.12.0 が必要、またはグローバルにインストールされた composer がある場合。

一方、PHPMD は、よりユーザーフレンドリーであり、PHP_Depend によって測定される生のメトリクスの設定が簡単なフロントエンドを備えているため、PHP_Depend よりも推奨されます。 特定のソース コード (PHP コード) ベースを使用し、単純な動作原理を持っているため、そのソース内の潜在的なバグや注意事項を調べたり、見つけようとします。

バグや構文エラー、過度に複雑な式、未使用のプロパティ、メソッド、パラメーター、最適化されていないコードを簡単に検出できます。 PHP Mass Detector は、成熟した PHP プロジェクトおよび静的コード アナライザーとして、PHP ソース コードを分析するための定義済みルールの膨大なライブラリを提供します。

// Type phpmd [filename|directory] [report format] [ruleset file]

hassan@kazmi ~ $ phpmd PHP/Depend/DbusUI/ xml rulesets/codesize.xml

<?xml version="1.0" encoding="UTF-8" ?>
<pmd version="0.0.1" timestamp="2009-12-19T22:17:18+01:00">
  <file name="/projects/pdepend/PHP/Depend/DbusUI/PHPMD.php">
    <violation beginline="54"
               endline="359"
               rule="TooManyProperties"
               ruleset="Code Size Rules"
               package="PHP_Depend\DbusUI"
               class="PHP_Depend_DbusUI_ResultPrinter"
               priority="1">
      This class has too many properties; consider refactoring it.
    </violation>
  </file>
</pmd>

出力:

This class has too many properties; consider refactoring it.

PHP Mess Detector のコマンド ライン使用法は、phpmd [filename|directory] [report format] [ruleset file] と入力することでアクティブ化または使用できます。また、ファイル/ディレクトリ名を PHPMD に 分析用の PHP ソース コードのコンテナー。 codesize.xml または rulesets パラメータは、その Phar ディストリビューションがそのアーカイブ内にルール セット ファイルを含むため、ファイル システム参照のように見えることがあります。

さらに、PHP プログラマーは短縮名または参照を使用して、phpmd 依存 XML コードサイズなどの組み込みルール セットを参照できます。 PHPMD のコマンド ライン インターフェイスは、--min-priority--report-file--suffixes--strict などのオプションの引数も受け入れます。

~ $ phpmd /path/to/source text codesize 構成を適用するには、テスト中のソース コードに対して適用される複数のルール セットを使用し、セット名でその CLI ツールへの呼び出しを有効にします。 さらに、プログラマーがカスタム ルール セット ファイルと組み込みルール セットを混在させるための詳細な構成を可能にし、~ $ phpmd /path/to/source text codesize,/my/rules.xml コマンドは完璧な例です。 ソース コードを分析するためのカスタム ルール セットを指定します。

pfff ツールを使用して PHP で静的コード分析を実行する

API とツールのセットとして、静的コード分析を実行して、ソース コードのインデックス作成、検索、ナビゲート、視覚化、リファクタリング、およびスタイルを保持するソースからソースへの PHP コード変換を実行できます。

pfff のコンパイルとインストールは簡単です。 ただし、go-automatic.php:14:77: CHECK: Use of undeclared variable $goUrl または login-now.php:7:4: CHECK: Unused Local variable $title のような複雑な形式で結果が生成されます。 . $ ~/sw/pfff/scheck ~/code/github/sc/ を使用して、GitHub の pfff にアクセスできます。

さらに、プロジェクト ディレクトリに commons/ および parsing_php/ ディレクトリをコピーし、再帰的な make を追加することで、独自の OCaml アプリケーションに解析ライブラリを埋め込むことができます。 最後に、アプリケーションを parsing_php/parsing_php.cma & commons/commons.cma ライブラリにリンクします。 また、理解を深めるために pfff/demos/Makefile を観察してください。ソースがコンパイルされたら、次のコマンドで pfff をテストできます。

$ cd demos/
$ ocamlc -I ../commons/ -I ../parsing_php/ \
../commons/commons.cma ../parsing_php/parsing_php.cma \
show_function_calls1.ml -o show_function_calls
$ ./show_function_calls foo.php

その後、Facebook アーカイブの pfff プロジェクトの show_function_calls1.m1 のコードに従って、foo.php の関数呼び出しに関するいくつかの役立つ情報を stdout で確認できるはずです。 pfff パーサーは非常に生産的で、phpbb Web サイトでテストできます。

// source code of pfff command-line
$ cd /tmp
$ wget http://d10xg45o6p6dbl.cloudfront.net/projects/p/phpbb/phpBB-3.0.6.tar.bz2
$ tar xvfj phpBB-3.0.6.tar.bz2
$ cd <pfff_src_directory>
$ ./pfff -parse_php /tmp/phpBB3/

pfff プログラムは、その後、すべてのソースコードファイル(.php ソースファイル)を反復処理し、各ソースファイルに対してパーサーを実行し、次のような統計情報を表示します:NB total files = 265; perfect = 265; =========> 100% および nb good = 183197, nb bad = 0 =========> 100.000000% などです。これは、pfff がPHPソースコードの100%を解析できたことを意味します。

コマンド ライン プログラムとして、PHP 言語パーサーをテストするために、pfff などのさまざまなコマンドを備えています。 scheck を使用してバグを見つけることができます。これは、Emacs タグ ジェネレーターの lintstag のように機能し、他のどのツールよりも正確です。

sgrep は、正確なコード パターンを簡単に見つけられるようにする総合的な grep であり、spatch は、PHP コードのリファクタリングを容易にする構文パッチであり、codemappfff_dbcodegraph、および codequery は、一連のソース ファイルに対してグローバルな分析を実行したり、PHP コードベースの構造に関する情報をクエリしたりするために、pfff ツールに最近追加されたものの一部です。

HHVM を使用して PHP で静的コード分析を実行する

Proxygen および FastCGI サーバー タイプのサポートが組み込まれており、完璧な静的コード アナライザーの 1つになります。 HHVM は、Proxygen が直接組み込まれた完全に機能する Web サーバーとして知られており、その使いやすさとソース コードの処理により、静的コード分析に強く推奨されます。

高速な Web リクエストを処理し、FastCGInginx を組み合わせたものと同等の高性能 Web サーバーを提供します。 hhvm -m server -p 8080 を実装して、サーバー モードで HHVM を実行しているときに Proxygen を使用できます。また、コマンド ライン構成でポートを設定できます: hhvm.server.port=7777、または -d hhvm.server を配置します。 port=7777server.ini ファイルに追加します。

-d hhvm.server.type=proxygen コマンドを使用して、明示的に指定せずに Proxygen サーバー タイプを定義できます (Proxygen がデフォルトです)。 init スクリプト HHVM パッケージは、デフォルトで FastCGI モードで開始され、サーバーとして自動的に開始される前に構成の微調整が必要です。

以下は、コマンド ラインでさまざまなカスタマイズ可能なオプション (server.ini または -d オプション) を使用した HHVM パッケージ構成の例です。 これらの構成オプションの一部はデフォルト値であるためオプションですが、より多くの情報を提供したり、ユーザーに図を表示したりするのに役立つことに注意してください。

// initialize a server port
hhvm.server.port = 60
// the default server type is `proxygen`
hhvm.server.type - proxygen
hhvm.server.default_document = source.php
hhvm.error_document404 = source.php
hhvm.server.source_root = /edit/source/php

オプションの構成オプションを使用することは、文書化の目的を明確にするのに適しています。hhvm.server.source_roothhvm.server.port は、明示的な値を必要とする可能性が最も高いものです。 HH Virtual Machine はオープンソースで、Hack で記述されており、JIT (ジャストインタイム) コンパイルを使用して優れたパフォーマンスを実現しながら、優れた開発の柔軟性を維持します。

HHVM バイナリが起動されるデフォルトのディレクトリは、サーバーに基づいて変更できる default_document です。 HHVM を PHP プロジェクトの OS にインストールした後、sudo update-rc.d hhvm defaults および sudo service hhvm restart コマンドを使用して、起動時に HHVM をサーバーとして起動するように設定できます。

Syed Hassan Sabeeh Kazmi avatar Syed Hassan Sabeeh Kazmi avatar

Hassan is a Software Engineer with a well-developed set of programming skills. He uses his knowledge and writing capabilities to produce interesting-to-read technical articles.

GitHub