非常に奇妙なphp動作に遭遇しました(ubuntu 10.04の5.3.2)。ローカル スコープ内で発生するはずの unset が、呼び出し元関数のスコープに影響を与えています。次のスニペットは、バグであるとしか思えないコードを簡略化したものです。
<?php
function should_not_alter($in)
{
$in_ref =& $in['level1'];
should_only_unset_locally($in);
return $in;
}
function should_only_unset_locally($in)
{
unset($in['level1']['level2_0']);
}
$data = array('level1' => array('level2_0' => 'first value', 'level2_1' => 'second value'));
$data = should_not_alter($data); //test 1
//should_only_unset_locally($data); //test 2
print_r($data);
?>
上記を実行すると、値がグローバル スコープ'first value'
の配列から設定解除されていることがわかります。$data
ただし、コメントアウトしtest 1
て実行すると、test 2
これは起こりません。
PHPは配列の要素を参照するのが好きではないとしか思えません。私のコードでは、変更する必要があります-したがって、上記のコード$in_ref
の行の理由です。$in_ref =& $in['level1'];
この行を削除すると'first value'
、グローバルスコープで設定解除されるという問題が解決されることはわかっていますが、これはオプションではありません。
これがphpの意図した動作であるかどうかを誰でも確認できますか?
この動作は、php が通常の (非配列) 変数を使用してスコープと参照を処理する方法と矛盾しているため、機能ではなくバグであると思われます。たとえば、配列関数でshould_only_unset_locally()
はなく文字列を使用しても、グローバル スコープには影響しません。
<?php
function should_not_alter($in)
{
$in_ref =& $in;
should_only_unset_locally($in);
return $in;
}
function should_only_unset_locally($in)
{
unset($in);
}
$data = 'original';
$data = should_not_alter($data); //test 1
//should_only_unset_locally($data); //test 2
print_r($data);
?>
test1 または test2 の両方original
が期待どおりに出力されます。実際に$data
は、 が配列であるにもかかわらず、配列$in_ref
全体 (つまり$in_ref =& $in;
) を参照している場合でも、バグのある動作はなくなります。
アップデート