この症状が意図しないエラーか、不適切な最適化か、または PHP の予期される動作なのかを理解するのを手伝ってください。
ここに小さなコードがあります:
class Packet {
public $length;
public $time;
}
class Stream {
public $packets = array();
// Basically what I want is to make sure
// I put my packet in the array as reference
// because later in the code where I call this
// function, I change my Packet object's values
// and I want this change to appear in the
// $this->packets array. So I pass by reference.
// I don't want to copy the Packet object at all!
public function addPacket(&$packet){
$this->packets[] = &$packet; //note here the reference operator
}
}
...
foreach($packets as $packet){
$myPrettyStream->addPacket($packet);
}
ということで、やりたいことをコードコメントで説明しました。私の問題は、すべてのパケットを foreach でストリームに追加した後、すべてのStream::packets
配列要素$packet
に、ストリームに追加した LAST への (参照) が含まれることです。
PHP は、関数呼び出し間で関数$packet
内の変数を保持しているようです。(これは意図されたものか、最適化が間違っている可能性がありますか?)配列への参照 (基本的に参照参照 &&$packet) または単に (&$packet) の参照によって変数addPacket(&$packet)
を渡すかどうかにかかわらず、これはすべきではないと思います予想される動作。&$packet
$packet
ただし、関数内で参照を作成しない場合は機能します。
public function addPacket(&$packet){
$this->packets[] = $packet;
}
この振る舞いが理にかなっている理由を誰か説明してください!
ありがとう!
================================================== =======================
解決
正しい答えをありがとう、私は同じように動作する関数呼び出しをエミュレートしました:
// try to emulate function call inside iteration
$packet = $packets[0];
$functionPacket = &$packet;
$packetsItem[0] = &$functionPacket; //functionpacket holds a reference to $packet
var_dump($packetsItem);
echo "\nsecond iteration\n";
unset($functionPacket);
$packet = $packets[1];
$functionPacket = &$packet;
$packetsItem[1] = &$functionPacket;
var_dump($packetsItem);
output:
array(1) {
[0]=>
&object(Packet)#1 (2) {
["time"]=>
int(1)
}
}
array(2) {
[0]=>
&object(Packet)#2 (2) {
["time"]=>
int(2)
}
[1]=>
&object(Packet)#2 (2) {
["time"]=>
int(2)
}
}