2017-12-29 45 views
0

PHP 7.0PHP参考文献による直接指定がありません

実際には配列の割り当てに不具合があります。 PHPの配列は、値のコピー(参照に直接設定されていない場合)で割り当てる必要があります。

ローカルスコープで一度参照される変数は、どこでも参照されるようになりました(これは私が推測するところです)。私の意見では、これはどのように動作するはずではありません。私は1つの場所で参照を作成したいが、他の場所には値をコピーしたい。

てください。この例を見て結果が

After B::__construct 
array(1) { 
    ["randoms"]=> 
    array(0) { 
    } 
} 


After A::__construct(B) 
array(1) { 
    ["randoms"]=> 
    &array(0) { 
    } 
} 


After B::doSomething() 
array(1) { 
    ["randoms"]=> 
    &array(1) { 
    [0]=> 
    int(85799664) 
    } 
} 


B::history 
array(3) { 
    [0]=> 
    array(1) { 
    ["randoms"]=> 
    &array(3) { 
     [0]=> 
     int(85799664) 
     [1]=> 
     int(418164754) 
     [2]=> 
     int(1267239969) 
    } 
    } 
    [1]=> 
    array(1) { 
    ["randoms"]=> 
    &array(3) { 
     [0]=> 
     int(85799664) 
     [1]=> 
     int(418164754) 
     [2]=> 
     int(1267239969) 
    } 
    } 
    [2]=> 
    array(1) { 
    ["randoms"]=> 
    &array(3) { 
     [0]=> 
     int(85799664) 
     [1]=> 
     int(418164754) 
     [2]=> 
     int(1267239969) 
    } 
    } 
} 

code fiddle

あなたはBを参照して見ることができるように:: :: __構築スコープが可能でvarsの

class A 
{ 

    public $b; 

    public $refVar; 

    public function __construct(B $b) 
    { 
     $this->b = $b; 

     // reference here 
     $this->refVar = &$this->b->vars['randoms']; 
    } 

} 

class B 
{ 

    public $vars = []; 
    public $history = []; 


    public function __construct() 
    { 
     $this->vars['randoms'] = []; 
    } 

    public function doSomething() 
    { 
     // copy value here 
     $this->history[] = $this->vars; 

     $this->vars['randoms'][] = rand(); 
    } 

} 

$b = new B(); 

echo "After B::__construct\n"; 
var_dump($b->vars); 

$a = new A($b); 

echo "\n\nAfter A::__construct(B)\n"; 
var_dump($b->vars); 

$b->doSomething(); 

echo "\n\nAfter B::doSomething()\n"; 
var_dump($b->vars); 

$b->doSomething(); 
$b->doSomething(); 

echo "\n\nB::history\n"; 
var_dump($b->history); 

B :: varsはどこでも参照されています。

これを防止するにはどうすればよいですか?

EDIT:長い研究の後、私は簡単な例を示しました。そして何が間違っているかを見いだした - しかし、私はこのような状況を防ぐ方法を知らない。

メタ:まだ誰も答えていないので少し質問を変更しました。誰かがすでにそれに従っているので、私はそれを閉じたくない。

EDIT 2私は完全には満足していない私のソリューションを掲載しました。 誰かがこれを克服する方法を考えているなら(コンセプトを変えて)、どんな提案も歓迎します。しかし、クラスのB :: varsへの参照は、その変数の状態を保存する可能性と同様に必要であることに留意してください。パフォーマンスに大きな影響を与えます -

+0

変数に '&'を使用すると、その変数に参照が割り当てられます。 http://php.net/manual/pt_BR/language.references.php –

+0

参照はB :: pushState()ではなくAコンストラクタで使用されることに注意してください。 – l00k

+0

醜い解決策があります:unserialize(serialize(...))しかし私の意見では、よりエレガントな方法があるはずです。 – l00k

答えて

0

この問題は、唯一の解決策は、シリアル化またはjson_encodeを使用しているようだbug on php.net

として言及し、既にされています。