私はうさぎの穴を案内するカスタムエラーハンドラーを使用するという明るい考えを持っていました。
次のコードは、(カスタムエラーハンドラーの有無にかかわらず)与えます:致命的なエラー:変数は参照でのみ渡すことができます
function foo(){
$b=array_pop(array("a","b","c"));
return $b;
}
print_r(foo());
次のコードは、(カスタムエラーハンドラーのみ)を示します。(2048)変数のみを参照渡しする必要があります
function foo(){
$a=explode( '/' , 'a/b/c');
$c=array_pop(array_slice($a,-2,1));
return $c;
}
print_r(foo());
2つ目は、「コンパクト」なコードがたくさんあるので心配です。そのため、カスタムログハンドラーを使用するという優れたアイデア(ロギングモジュールを改善するため)を捨てるか、すべてのコードを拡張します。
より良いアイデアを持つ人はいますか?また、WTF?
[〜#〜]更新[〜#〜]:
回答のおかげで、phpがエラー処理を行う方法について何かを学びました。 E_STRICT(php 5)を含まないE_ALLの混乱はクールではありません。
さらに、独自のカスタムエラーハンドラーを作成すると、デフォルトでE_STRICTが有効になり、問題が発生します。
ストーリーの教訓は、独自のエラーハンドラーを使用してそれらすべてをキャッチし、エラー定数(E_STRICT、E_USER_WARNING、E_USER_ERRORなど)を使用してフィルタリングを行うことです。
変数参照と特定の関数での「メモリ破損の問題」については、何と言えますか?二重に涼しくない。私は(そうする必要があるという意味ではありません)、エラーハンドラーでE_STRICTを無視します。
array_pop()は、パラメーターとして渡された値を変更しようとします。 2番目の例では、これはarray_slice()からの戻り値です。エンジン用語では、これは「一時的な値」であり、そのような値を参照で渡すことはできません。必要なのは一時変数です:
function foo(){
$a=explode( '/' , 'a/b/c');
$b=array_slice($a,-2,1);
$c=array_pop($b);
return $c;
}
print_r(foo());
次に、$ bへの参照をarray_pop()に渡すことができます。リファレンスの詳細については http://php.net/references を参照してください。
Php-cliで2番目のphpコードスニペットを試すと、次のようになりますerror_reportingをE_ALL | E_STRICTに設定した後
gparis@techosaure:~/workspace/universcine.com$ php -a
Interactive Shell
php > function foo(){
php { $a=explode( '/' , 'a/b/c');
php { $c=array_pop(array_slice($a,-2,1));
php { return $c;
php { }
php > print_r(foo());
PHP Strict standards: Only variables should be passed by reference in php Shell code on line 3
PHP Stack trace:
PHP 1. {main}() php Shell code:0
PHP 2. foo() php Shell code:1
ご覧のとおり、これは厳密な基準にすぎません。また、カスタムエラーハンドラーにそれらを無視させることも簡単にできます(取得する値に基づいて、ここでは2048など)。
PHP 5.3以降、E_ALLにはE_STRICTが含まれていません。これを見てください。
php > foreach(array("E_ALL", "E_DEPRECATED", "E_STRICT", "E_NOTICE", "E_PARSE", "E_WARNING") as $const) echo $const . " :\t" . constant($const) ."\t". decbin(constant($const)). "\n";
E_ALL : 30719 111011111111111
E_DEPRECATED : 8192 10000000000000
E_STRICT : 2048 100000000000
E_NOTICE : 8 1000
E_PARSE : 4 100
E_WARNING : 2 10
PHP 5.4以降、E_ALL
にはE_STRICT
が含まれます。
E_ALL : 32767 111111111111111
E_DEPRECATED : 8192 10000000000000
E_STRICT : 2048 100000000000
E_NOTICE : 8 1000
E_PARSE : 4 100
E_WARNING : 2 10
これはメモリ破壊の問題です(PHP開発チームによると)。割り当てを投入するだけです:
function foo(){
$b = array_pop($arr = array("a","b","c"));
return $b;
}
print_r(foo());
:
function foo(){
$a = explode( '/' , 'a/b/c');
$c = array_pop($arr = array_slice($a,-2,1));
return $c;
}
print_r(foo());
2番目はE_STRICTを生成します。必要に応じて(これらの関数を変更したくない場合)、エラーハンドラーで異なる方法で処理できます。
array_pop()
は、エラーが発生した場所に渡された値を変更します。機能は変更できません。つまり、最初に配列を変数に割り当て(参照: manual )、次にarray_pop()
を実行する必要があります。
必要なコードはこれです:
_function foo(){
$a = array("a","b","c");
$b = array_pop($a);
return $b;
}
_
編集:あなたが言及した両方の関数には同じ問題があります。配列を変数に割り当て、変数をarray_pop()
に渡します。
私は今(php 5以降)それは次のようになるはずだと思います:
function &foo(){ //NOTICE THE &
$b=array_pop(array("a","b","c"));
return $b;
}
print_r(foo());
そして
function &foo(){ //NOTICE THE &
$a=explode( '/' , 'a/b/c');
$c=array_pop(array_slice($a, $b = -2, $c = 1)); //NOW NO DIRECT VALUES ARE PASSED IT MUST BE VARIABLES
return $c;
}
print_r(foo());
しかし、私はただの初心者です:)
これを試して:
function foo(){
$a = array("a","b","c");
$b = array_pop($a);
return $b;
}