web-dev-qa-db-ja.com

厳しい基準:変数のみを参照渡しする必要があります

$el = array_shift($instance->find(..))

上記のコードは何らかの形で厳密な標準警告を報告しますが、これはそうではありません:

function get_arr(){
    return array(1,2);
}
$el = array_shift(get_arr());

とにかく、いつ警告を報告するのでしょうか?

81
user198729

次のコードを検討してください。

error_reporting(E_STRICT);
class test {
    function test_arr(&$a) {
        var_dump($a);   
    }
    function get_arr() {
        return array(1,2);  
    }
}

$t= new test;
$t->test_arr($t->get_arr());

これにより、次の出力が生成されます。

Strict Standards: Only variables should be passed by reference in `test.php` on line 14
array(2) {
  [0]=>
  int(1)
  [1]=>
  int(2)
}

理由? test::get_arr()メソッドは変数ではないため、厳格モードでは警告が生成されます。 get_arr()メソッドreturns配列値であるため、この動作は非常に直感的ではありません。

ストリクトモードでこのエラーを回避するには、参照を使用しないようにメソッドのシグネチャを変更します。

function test_arr($a) {
    var_dump($a);  
}

array_shiftの署名を変更できないため、中間変数を使用することもできます。

$inter= get_arr();
$el= array_shift($inter);
93
leepowers

$instance->find()は、変数への参照を返します。

この参照を関数の引数として使用しようとすると、最初に変数に保存せずにレポートを取得します。

これはメモリリークの防止に役立ち、おそらく次のPHPバージョンでエラーになります。

次のように記述した場合、2番目のコードはエラーをスローします(&の関数シグネチャに注意してください):

function &get_arr(){
    return array(1,2);
}
$el = array_shift(get_arr());

したがって、簡単な(そしてそれほど素敵ではない)修正は次のようになります。

$el = array_shift($tmp = $instance->find(..));

基本的に、最初に一時変数に割り当てを行い、変数を引数として送信します。

8
Sagi

エラーの原因は、内部PHPプログラミングデータ構造関数array_shift()[php.net/end]の使用です。

この関数は、パラメーターとして配列を受け取ります。アンパサンドは、マニュアルのarray_shift()のプロトタイプに示されていますが、その関数の拡張定義に続く注意文書はなく、パラメーターが実際に参照によって渡されるという明確な説明もありません。

おそらくこれは/ understandod /です。しかし、理解できなかったため、エラーの原因を見つけることは困難でした。

コードを再現する:

function get_arr()
{
 return array(1,2);
}
$array = get_arr();
$el = array_shift($array);
5
Biju B Adoor

2番目のスニペットも機能しません。そのためです。 array_shiftは、引数を変更する修飾子関数です。したがって、パラメーターが参照であると想定され、変数以外のものを参照することはできません。 Rasmusの説明を参照してください: 厳密な標準:参照によって変数のみを渡す必要があります

3
user187291

このコード:

$monthly_index = array_shift(unpack('H*', date('m/Y')));

以下に変更する必要があります。

$date_time = date('m/Y');
$unpack = unpack('H*', $date_time);
array_shift($unpack);
3
user6031348