PHPの変数代入の原理を深く理解する
PHPにおける変数の割り当て
これは、おそらく多くの人が気にしないであろうタイトルです。しかし、値と参照の関係など、多くの人が混乱するほど基本的なことなのです。今日は、それについて詳しく説明します。
まず、変数の定義と値の代入は言うまでもありませんよね?
$a = 1;
$b = '2';
$c = [4, 5, 6];
$d = new stdClass();
4つの変数で、それぞれ整数、文字列、配列のオブジェクトを定義しています。私たちが日常的に扱うのは、この4つの型です。
そして、変数に値を代入する。
$a1 = $a;
$b1 = $b;
$c1 = $c;
$d1 = $d;
最初の3つの代入は通常の代入、すなわち仕様のコピーであることに注意してください。a1を変更しても、$aは変わりません。a1は私たちの値を保持する新しく開かれたメモリ空間です。つまり、同じ値を持つが、メモリーアドレスは異なる。これは、互いに何の関係もない2つのそっくりさんに過ぎないのです。
しかし、$d1と$dは違います。同じ値であるだけでなく、同じメモリアドレスを持っています。このような状況を参照代入と呼びます。d1が変化すると、$d2も変化します。
いわば、参照代入は、Windowsでは元の変数へのショートカットを、Linuxではソフトリンクを作るのです。
具体的な例で説明すると、まず共通の値を代入する場合
// Common assignment
$v = '1';
$c = $v;
$c = '2';
echo $v, PHP_EOL; // '1'
// Arrays are also normal assignments
$arr1 = [1,2,3];
$arr2 = $arr1;
$arr2[1] = 5;
print_r($arr1); // [1, 2, 3]
cは$vの値に影響を与えません。$arr2は5から2番目の数字である添え字1を修正し、もちろん$arr1には何の影響も与えません。
オブジェクト形式での参照代入はどうでしょうか?
// Objects are assigned by reference
class A {
public $name = 'I am A';
}
$a = new A();
$b = $a;
echo $a->name, PHP_EOL; // 'I am A'
echo $b->name, PHP_EOL; // 'I am A'
$b->name = 'I am B';
echo $a->name, PHP_EOL; // 'I am B'
予想通り、$bがname属性の内容を変更した後、$aの中の名前も$bが変更したものになる。
この場合、オブジェクトが参照渡しでなければ、1つはプロトタイプパターンである__clone()を使って、自分自身のコピーを作ることである。2つは、外からチャントを再新する。
// Use cloning to solve the reference passing problem
class Child{
public $name = 'I am A1's subordinate';
}
class A1 {
public $name = 'I am A';
public $child;
function __construct(){
$this->child = new Child();
}
function __clone(){
$this->name = $this->name;
// new or use Child's clone either
// $this->child = new Child();
$this->child = clone $this->child;
}
}
a1 = new A1();
echo $a1->name, PHP_EOL; // output the original content of a1
echo $a1->child->name, PHP_EOL;
$b1 = $a1;
echo $b1->name, PHP_EOL; // b1 is now also the content of a1
echo $b1->child->name, PHP_EOL;
$b1->name = 'I am B1'; // b1 modifies the content
$b1->child->name = 'I am B1's subordinate';
echo $a1->name, PHP_EOL; // a1 becomes the content of b1
echo $a1->child->name, PHP_EOL;
// Use __clone
$b2 = clone $b1; // b2 clones b1
$b2->name = 'I am B2'; // b2 modifies the content
$b2->child->name = 'I am B2's subordinate';
echo $b1->name, PHP_EOL; // b1 doesn't become what b2 modifies
echo $b1->child->name, PHP_EOL;
echo $b2->name, PHP_EOL; // b2 modified content is fine, b1, b2 is not a cargo anymore
echo $b2->child->name, PHP_EOL;
オブジェクト参照の部分は、本当に混乱することがあります。特に、内部プロパティや他のオブジェクトへの様々な参照を持つ、より複雑なオブジェクトになるとなおさらです。この場合、参照の割り当てが問題を起こさないかどうか、必ず再確認してください。もし問題を起こすようなら、新しいオブジェクトやクローン技術を使って、参照の問題に対処してください。
最後に、簡単に説明すると、参照変数の代入は、メソッドに参照パラメータを渡すのと同じで、&の記号を使うだけです!
// Assigning by reference
$b = &$v;
$b = '3';
echo $v, PHP_EOL;
今日、私たちはPHPの代入について、特に通常の代入と参照代入について学び、理解しました。次回、コードやフレームワークを見るときに、他の人がこの2種類の代入をどのように柔軟に使っているかに注目し、また、自分が書いたバグをこの2つの方法を使って変形してみることができますよ。
<ブロッククオートテストコード
参考文献
https://www.php.net/manual/zh/language.variables.basics.php
この記事では、PHPの変数代入を深く理解するための原理について紹介します。PHPの変数代入に関するより詳しい内容は、BinaryDevelopの過去の記事を検索するか、以下の関連記事を引き続き閲覧してください!今後、BinaryDevelopをよりサポートしていただけると幸いです。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン