ホームページ >バックエンド開発 >PHPの問題 >Deliverer 1.0.8 はすでに PHP5 をサポートしています。

Deliverer 1.0.8 はすでに PHP5 をサポートしています。

藏色散人
藏色散人転載
2021-07-05 16:14:211323ブラウズ

2 週間の反復の後、Deliverer は現在 1.0.8 https://github.com/zhoumengka.. に更新されています。

先祖代々のコードの問題を解決するためであり、友人グループからもやはりPHP5のサポートが必要だという声を聞いたので、頑張って取り組んでいます。このバージョンをこの期間中に解決する必要があります。互換性の問題、問題が予想よりはるかに難しいとは予想していませんでした。

開発中に発生した問題 (主に物理的な作業) を記録し、共有したい場合は、興味のある友人が フォーク コピーすると、コードに慣れなくなります。 PR に送信します。

PHP7 では、関数またはメソッドは execute_data->call->fbc 構造体の zend_execute_data で実行されますが、PHP5 では、対応するフィールドが関数を取得します。は関数を呼び出しますが、この 2 つの違いは比較的大きいです。

後で調べたところ、現在実行されている関数の情報は PHP5 の opline zend_execute_data にあることが分かりましたが、PHP5.4 の前後でロジックが異なるため、必要があります。別の方法で処理されます (幸いなことに、コンパイラがエラーを表示したフィールド)

#if PHP_VERSION_ID < 50400
#define OP1_FUNCTION_PTR(n) (&(n)->op1.u.constant)
#else
#define OP1_FUNCTION_PTR(n) ((n)->op1.zv)
#endif

最初の呼び出しは解決されましたが、埋め込まれた呼び出しが opline にないことが判明し、バージョンがは異なり、入手場所も異なり、同じでした。 上記のオプリンの判定バージョン番号は同じではないため、体力に頼るしかありません。

#if PHP_VERSION_ID < 50500
    if (execute_data->fbc != NULL)
    {
        fbc = execute_data->fbc;
    }
#else
    if (execute_data->call != NULL && execute_data->call->fbc != NULL)
    {
        fbc = execute_data->call->fbc;
    }
#endif

最終的な関数情報の取得は多層判定です

    zend_function *fbc;

#if PHP_VERSION_ID < 70000
#if PHP_VERSION_ID < 50500
    if (execute_data->fbc != NULL)
    {
        fbc = execute_data->fbc;
    }
#else
    if (execute_data->call != NULL && execute_data->call->fbc != NULL)
    {
        fbc = execute_data->call->fbc;
    }
#endif
    if (fbc == NULL)
    {
        fbc = get_function_from_opline(execute_data->opline);
    }
#else
    if (execute_data->call != NULL && execute_data->call->func != NULL)
    {
        fbc = execute_data->call->fbc;
    }
#endif

oplineから問い合わせられるのは関数名のみで、対応する関数ポインタをglobal function table

static zend_function *get_function_from_opline(zend_op *opline)
{
    zend_function *fbc;

    zval *function_name = OP1_FUNCTION_PTR(opline);

    if (Z_STRVAL_P(function_name) == NULL)
    {
        return NULL;
    }

    if (zend_hash_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name) + 1, (void **)&fbc) ==
        FAILURE)
    {
        return NULL;
    }

    return fbc;
}

全体として、PHP5 の処理は PHP7 の処理よりもはるかに複雑ですが、これは PHP7 の方が優れた仕事をすることも示しています。

これらはここ数日間の開発作業です。私が遭遇していない実際のオンライン環境がたくさんあるかもしれません。興味があれば、このツールを使用して問題を解決することも、一緒に作業することもできます。この小さなツールを改善するために。

来週か再来週に、関数とメソッドのパラメータ出力をサポートするための watch 関数を追加します。主に Java の Arthas から類推します。私が最もよく使うのはトレース関数とウォッチ関数だからです。PHP はオンラインでログを直接変更したり追加したりできますが、これは結局標準化されておらず、リリース プロセスが遅すぎます。ウォッチ関数は次のとおりだと思います。必要に応じて、おそらく

$ ./bin/deliverer -w foo -n 3

は、監視中の foo 関数が 3 回の呼び出し後に終了し、deliver-request-id とその入力パラメータを出力することを意味します。その後、deliver-request-id に基づいて完全なコール スタックを表示できます。

これに興味がある場合は、スターを付けてください。https://github.com/zhoumengkang/deliverer

インストールと使用について質問がある場合は、私を追加してください。 WeChat zhoumengkang 前嫌がらせするには、パスワード:deliveryer

推奨学習:「PHP ビデオ チュートリアル

以上がDeliverer 1.0.8 はすでに PHP5 をサポートしています。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。