ホームページ >php教程 >php手册 >PHPエラーサプレッサー(@)によりパラメータの参照渡しが失敗するバグの解析

PHPエラーサプレッサー(@)によりパラメータの参照渡しが失敗するバグの解析

WBOY
WBOYオリジナル
2016-06-13 12:10:241123ブラウズ

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

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


$array = array(1 ,2,3);
関数 add (&$arr) {
$arr[] = 4;
add(@$array); $array);
/**
この時点では、$array は変更されていません。出力:
Array
(
[0] => 1
[1] => 2
[2] => 3
)
*/
add($array);
/**
エラー抑制がなければ、出力は正常です:
Array
(
[0] => 1
[1] => 2
[2] => ; 3
[3] => 4
)
*/
?



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


仕方がない、自分で解析するしかない エラー抑制の原理については以前の記事(PHPのエラー抑制原理と埋め込みHTMLの徹底理解)で紹介しましたが、原則としてエラー抑制は変更するだけです。 error_reporting レベルでは、コンテキスト間の関数呼び出しメカニズムには影響しないのは当然です。これはフィールド テストを通じてのみ実行できます。

gdb の追跡後、間違った移植演算子を使用した後、関数呼び出し前のパラメーターのオペコードが異なることが判明しました:


コードをコピー

コードは次のとおりです。 //エラー抑制機能を使用しない場合

OPCODE = SEND_REF

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


初期の問題 位置づけですが、この違いは何でしょうか?

OPCODE が違うので、構文解析の段階で分岐が違うはずです、このレベルで考えると問題です。 Positioned,

PHP の構文解析段階では、"@" expr の形式のエントリは expr_without_variable に還元されることが判明し、この種のノードの意味は変数のない値であることがわかります。リテラル値は参照渡しできないことを知っているので (変数ではないため)、この違いは次のとおりです。

1 . 構文分析ステージ:



コードをコピー

コードは次のとおりです: expr_without_variable: //...省略あり

| '@' { zend_do_begin_silence(&$1 TSRMLS_CC ); }

expr { $$ = $3 }
//ZEND_SEND_VAL ブランチはここにあります。 non_empty_function_call_parameter_list:
expr_without_variable { ....} //この分岐は実行されました
| 変数 {.... } //通常の状況


実行中に異なる OPCODE が生成されます
最後に、この PHP のバグ ページで理由を説明しました。興味がある方は、私の下手な英語をご覧ください。最後に、これを提供してくれた cici netize に感謝します。興味深い質問です。

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