ホームページ  >  記事  >  バックエンド開発  >  PHP エラーサプレッサー @ パラメータの参照による受け渡しに失敗することによるバグの分析

PHP エラーサプレッサー @ パラメータの参照による受け渡しに失敗することによるバグの分析

WBOY
WBOYオリジナル
2016-07-29 08:45:031060ブラウズ

以下の例を見てください:

コードをコピーします コードは次のとおりです:


$array = array(1,2,3);
function add (&$arr) {
$arr[] = 4;
add(@$array);
/**
この時点では、$array は変更されておらず、出力:
Array
(
[0] => 1
[1] => 2
[2] => 3
)
*/
print_r($array); **
エラー抑制なしの場合、出力は通常です:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
*/
?>



私はこれまでこの問題に遭遇したことがなかったので、既製の答えがあるかどうかを確認するためにまず関連情報を探しましたが、誰かが答えていることがわかりました。同様の問題を PHP Bug: http://bugs.php.net/bug.php?id=47623 に報告しましたが、PHP 公式はまだ解決しておらず、返答もありません

他に方法はありません。 , 自分で解析するしかありません 以前の記事でも触れましたが、エラー抑制の原理は(エラー抑制と埋め込みHTMLのPHP原理を深く理解する)で紹介していますが、原則としてエラー抑制はレベルを変更するだけです。 error_reporting であり、論理的に言えば、コンテキスト間の関数呼び出しには影響しません。

gdb による追跡後、関数の前のパラメーター opcode が間違っていることが判明しました。呼び出しが異なります:

コードをコピーします

コードは次のとおりです: //No エラー抑制機能を使用する場合 OPCODE = SEND_REF

//エラー抑制機能を使用した後

OPCODE = SEND_VAR_NO_RE


問題は最初に特定されましたが、この違いの理由は何でしょうか?
OPCODE が異なるため、異なる分岐をとったのはこのレベルであると考えると、問題は簡単に特定できます。
PHP の構文解析の段階では、「@」 + expr の形式のエントリは expr_without_variable に変換されることがわかります。この種のノードの意味は、変数値、つまりリテラル値が存在しないことです。リテラル値は (変数ではないため) 参照を渡すことができないことは誰もが知っているので、この違いが生じます。

具体的なプロセスは次のとおりです:
1 . 文法分析フェーズ: コードをコピーします

次のようにコードを記述します。


expr_without_variable:

// ... 省略されています | '@' {zend_begin_silence (& $ 1 TSRMLS_CC);} expr { lence (& $1 TSRMLS_CC) } //ここで ZEND_SEND_VAL 分岐が選択されますnon_empty_function_call_parameter_list:

expr_without_variable { ....} //この分岐は誤って選択されます

variable {..... } //正常 状況


の結果、コンパイル中に異なる OPCODE が生成されました
最後に、PHP のこのバグのページで理由を説明しました。興味がある場合は、私の英語力を確認してください。最後に、この興味深い内容を提供してくれた cici netizen に感謝します。質問です

以上、PHPエラーサプレッサー@の参照パラメータ転送失敗の原因となるバグの解析を内容も含めて紹介しましたので、PHPチュートリアルに興味のある方の参考になれば幸いです。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。