Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code)

不言
Freigeben: 2023-04-04 06:16:01
Original
7328 Leute haben es durchsucht

Dieser Artikel bietet Ihnen eine detaillierte Einführung (Code) zur Referenzzuweisung und Wertzuweisung. Ich hoffe, dass er Ihnen weiterhilft.

1. Verwenden Sie „memory_get_usage()“, um die PHP-Speichernutzung zu überprüfen

1. Übergeben Sie die Wertzuweisung

// 定义一个变量
$a = range(0, 10000);
var_dump(memory_get_usage());

// 定义变量b,将a变量的值赋值给b
$b = $a;
var_dump(memory_get_usage());

// 对a进行修改
// COW: Copy-On-Write
$a = range(0, 10000);
var_dump(memory_get_usage());
Nach dem Login kopieren

Definieren Sie a Variablen

$a = range(0, 10000);

Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code)

$b = $a;

Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code)

Ändern Sie einen

$a = range(0, 10000);

Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code)PHP-Copy-on-Write-Mechanismus (Copy-on-Write). on-Write (auch als COW abgekürzt)

Wie der Name schon sagt, wird beim Schreiben tatsächlich eine Kopie des Speichers zur Änderung kopiert.

COW wurde zuerst in Unix-Systemen verwendet, um die Thread- und Speichernutzung zu optimieren, und wurde später häufig in verschiedenen Programmiersprachen wie C++s STL usw. verwendet.

Im PHP-Kernel ist COW auch die Hauptmethode zur Speicheroptimierung.
Wenn einer Variablen durch Variablenzuweisung ein Wert zugewiesen wird, wird kein neuer Speicher zum Speichern des Werts der neuen Variablen zugewiesen, sondern der Speicher wird einfach über einen Zähler gemeinsam genutzt. Nur wenn sich der Wert der Variablen, auf die eine der Referenzen zeigt, ändert, wird neuer Speicherplatz zugewiesen, um den Wertinhalt zu speichern und so die Speichernutzung zu reduzieren.
In vielen Szenarien verwendet PHP COW zur Speicheroptimierung. Zum Beispiel: Mehrfachzuweisungen von Variablen, Übergabe von Funktionsparametern und Änderung tatsächlicher Parameter im Funktionskörper usw.

2. Referenzzuweisung

int(989768)
int(989856)
int(1855608)
Nach dem Login kopieren

Ausgabeergebnis:

// 定义一个变量
$a = range(0, 10000);
var_dump(memory_get_usage());

// 定义变量b,将a变量的引用赋给b
$b = &$a;
var_dump(memory_get_usage());

// 对a进行修改
$a = range(0, 10000);
var_dump(memory_get_usage());
Nach dem Login kopieren

Variable definieren

$a = range(0, 10000);

Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code)

Variable b definieren und die Referenz der Variablen a auf b zuweisen

$b = &$a;

Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code)

Ändern Sie eine

$a = range(0, 10000);

Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code) 2. Verwenden Sie

, um den Referenzstatus von Variablen anzuzeigen

xdebug_debug_zval()

wird verwendet, um variable Informationen anzuzeigen. Die xdebug-Erweiterung muss installiert werden.

xdebug_debug_zval()1. Wertzuweisung

int(989760)
int(989848)
int(989840)
Nach dem Login kopieren

Ausgabeergebnis:

$a = 1;
xdebug_debug_zval('a');

// 定义变量b,把a的值赋值给b
$b = $a;
xdebug_debug_zval('a');
xdebug_debug_zval('b');

// a进行写操作
$a = 2;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
Nach dem Login kopieren

Variablen definieren

$a = 1;
a: (refcount=1, is_ref=0)=1
a: (refcount=2, is_ref=0)=1
b: (refcount=2, is_ref=0)=1
a: (refcount=1, is_ref=0)=2
b: (refcount=1, is_ref=0)=1
Nach dem Login kopieren
Ausgabe

$a = 1;
xdebug_debug_zval('a');
Nach dem Login kopieren
Nach dem Login kopieren

bedeutet, dass die Anzahl der Referenzen auf die Speicheradresse, auf die die Variable zeigt, 1 wird.

refcount=1 bedeutet, dass die Variable keine Referenz ist
is_ref=0

Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code)

definiert die Variable

und weist den Wert von den $b$a$b
a: (refcount=1, is_ref=0)=1
Nach dem Login kopieren
$b = $a;-Ausgängen
$b = $a;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
Nach dem Login kopieren

zu

zur Darstellung der Die Anzahl der Verweise auf die Speicheradresse, auf die die Variable zeigt, beträgt 2

, was bedeutet, dass die Variable kein Verweis auf die Variable istrefcount=2
is_ref=0

Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code) 🎜> Schreibvorgang ausführen

a: (refcount=2, is_ref=0)=1
b: (refcount=2, is_ref=0)=1
Nach dem Login kopieren
$a Ausgabe $a = 2;
$a = 2;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
Nach dem Login kopieren
Nach dem Login kopieren
Aufgrund des COW-Mechanismus beim Schreiben in eine Variable

, ein neuer Speicher wird für die Variable

reserviert. Platz, der zum Speichern des Werts der Variablen

verwendet wird.

Zu diesem Zeitpunkt wird die Anzahl der Verweise auf die Speicheradresse, auf die sowohl $a als auch $a zeigen, 1. $a
$a$b

2. ReferenzzuweisungDetaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code)

a: (refcount=1, is_ref=0)=2
b: (refcount=1, is_ref=0)=1
Nach dem Login kopieren
$a = 1;
xdebug_debug_zval('a');

// 定义变量b,把a的引用赋给b
$b = &$a;
xdebug_debug_zval('a');
xdebug_debug_zval('b');

// a进行写操作
$a = 2;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
Nach dem Login kopieren

Variablen definieren

a: (refcount=1, is_ref=0)=1
a: (refcount=2, is_ref=1)=1
b: (refcount=2, is_ref=1)=1
a: (refcount=2, is_ref=1)=2
b: (refcount=2, is_ref=1)=2
Nach dem Login kopieren
Ausgabe $a = 1;
$a = 1;
xdebug_debug_zval('a');
Nach dem Login kopieren
Nach dem Login kopieren

bedeutet, dass die Anzahl der Referenzen auf die Speicheradresse, auf die die Variable zeigt, 1 wird

bedeutet, dass die Variable keine Referenz ist

refcount=1
is_ref=0

定义变量 $b ,把 $a 的引用赋给 $b$b = &$a;

$b = &$a;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
Nach dem Login kopieren

输出

a: (refcount=2, is_ref=1)=1
b: (refcount=2, is_ref=1)=1
Nach dem Login kopieren

refcount=2 表示该变量指向的内存地址的引用个数变为2
is_ref=1 表示该变量是引用

Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code)

对变量 $a 进行写操作 $a = 2;

$a = 2;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
Nach dem Login kopieren
Nach dem Login kopieren

输出

a: (refcount=2, is_ref=1)=2
b: (refcount=2, is_ref=1)=2
Nach dem Login kopieren

因为变量 $a 和变量 $b 指向相同的内存地址,其实引用。
对变量 $a 进行写操作时,会直接修改指向的内存空间的值,因此变量 $b 的值会跟着一起改变。

Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code)

三、当变量时引用时,unset()只会取消引用,不会销毁内存空间

$a = 1;
$b = &$a;

// unset 只会取消引用,不会销毁内存空间
unset($b);

echo $a;
Nach dem Login kopieren

输出

1
Nach dem Login kopieren
Nach dem Login kopieren

定义变量 $a ,并将 $a 的引用赋给变量  $b

$a = 1;
$b = &$a;
Nach dem Login kopieren

Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code)

销毁 $b

unset($b);
Nach dem Login kopieren

Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code)

输出 $a

虽然销毁的 $b,但是 $a 的引用和内存空间依旧存在。

echo $a;
Nach dem Login kopieren

输出

1
Nach dem Login kopieren
Nach dem Login kopieren

四、php中对象本身就是引用赋值

class Person
{
    public $age = 1;
}

$p1 = new Person;
xdebug_debug_zval('p1');

$p2 = $p1;
xdebug_debug_zval('p1');
xdebug_debug_zval('p2');

$p2->age = 2;
xdebug_debug_zval('p1');
xdebug_debug_zval('p2');
Nach dem Login kopieren
p1: (refcount=1, is_ref=0)=class Person { public $age = (refcount=2, is_ref=0)=1 }
p1: (refcount=2, is_ref=0)=class Person { public $age = (refcount=2, is_ref=0)=1 }
p2: (refcount=2, is_ref=0)=class Person { public $age = (refcount=2, is_ref=0)=1 }
p1: (refcount=2, is_ref=0)=class Person { public $age = (refcount=1, is_ref=0)=2 }
p2: (refcount=2, is_ref=0)=class Person { public $age = (refcount=1, is_ref=0)=2 }
Nach dem Login kopieren

实例化对象 $p1 = new Person;

$p1 = new Person;
xdebug_debug_zval('p1');
Nach dem Login kopieren

输出

p1: (refcount=1, is_ref=0)=class Person { public $age = (refcount=2, is_ref=0)=1 }
Nach dem Login kopieren

refcount=1 表示该变量指向的内存地址的引用个数变为1
is_ref=0 表示该变量不是引用

$p1 赋给 $p2

$p2 = $p1;
xdebug_debug_zval('p1');
xdebug_debug_zval('p2');
Nach dem Login kopieren

输出

p1: (refcount=2, is_ref=0)=class Person { public $age = (refcount=2, is_ref=0)=1 }
p2: (refcount=2, is_ref=0)=class Person { public $age = (refcount=2, is_ref=0)=1 }
Nach dem Login kopieren

refcount=2 表示该变量指向的内存地址的引用个数变为2

Detaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code)

$p2 中的属性 age 进行写操作

$p2->age = 2;
xdebug_debug_zval('p1');
xdebug_debug_zval('p2');
Nach dem Login kopieren

输出

p1: (refcount=2, is_ref=0)=class Person { public $age = (refcount=1, is_ref=0)=2 }
p2: (refcount=2, is_ref=0)=class Person { public $age = (refcount=1, is_ref=0)=2 }
Nach dem Login kopieren

因为php中对象本身就是引用赋值。对 $p2 中的属性 age 进行写操作时,会直接修改指向的内存空间的值,因此变量 $p1age 属性的值会跟着一起改变。

五、实战例题分析

/**
 * 写出如下程序的输出结果
 *
 * $d = ['a', 'b', 'c'];
 *
 * foreach($d as $k => $v)
 * {
 *    $v = &$d[$k];
 * }
 * 
 * 程序运行时,每一次循环结束后变量 $d 的值是什么?请解释。
 * 程序执行完成后,变量 $d 的值是什么?请解释。
 */
Nach dem Login kopieren

1. 第一次循环

推算出进入 foreach$v$d[$k] 的值

$k = 0
$v = 'a'
$d[$k] = $d[0] = 'a'
Nach dem Login kopieren

此时,$v$d[0] 在内存中分别开辟了一块空间

![$v 和 $d[0] 在内存中分别开辟了一块空间](http://md.ws65535.top/xsj/201...

$v = &$d[0] 改变了 $v 指向的内存地址

$v = &$d[0]
Nach dem Login kopieren

![$v = &$d[0] 改变了 $val 指向的内存地址](http://md.ws65535.top/xsj/201...

第一次循环后 $d 的值:

['a', 'b', 'c']
Nach dem Login kopieren

2. 第二次循环

进入 foreach$v 被赋值为 'b',此时$v指向的内存地址与 $d[0] 相同,且为引用,因此 $d[0] 的值被修改为 'b'

$v = 'b'  => $d[0] = 'b'

![$v = ‘b’  => $d[0] = ‘b’](http://md.ws65535.top/xsj/201...

推算出进入 foreach$d[$k] 的值

$k = 1
$d[$k] = $d[1] = 'b'
Nach dem Login kopieren

![$d[2] = ‘b’](http://md.ws65535.top/xsj/201...

$v = &$d[1] 改变了 $v 指向的内存地址

$v = &$d[1]
Nach dem Login kopieren

![$v = &$d[1]](http://md.ws65535.top/xsj/201...

第二次循环后 $d 的值

['b', 'b', 'c']
Nach dem Login kopieren

3. 第三次循环

进入 foreach$v 被赋值为 'c',此时$v指向的内存地址与 $d[1] 相同,且为引用,因此 $d[1] 的值被修改为 'c'

$v = 'c'  => $d[1] = 'c'

![$v = ‘c’  => $d[1] = ‘c’](http://md.ws65535.top/xsj/201...

推算出进入 foreach$d[$k] 的值

$k = 2
$d[2] = 'c'
Nach dem Login kopieren

![$d[2] = ‘c’](http://md.ws65535.top/xsj/201...

$v = &$d[2] 改变了 $v 指向的内存地址

$v = &$d[2]
Nach dem Login kopieren

![$v = &$d[2]](http://md.ws65535.top/xsj/201...

第三次循环后 $d 的值

['b', 'c', 'c']
Nach dem Login kopieren

4. 实测

$d = ['a', 'b', 'c'];

foreach ($d as $k=>$v)
{
    $v = &$d[$k];
    print_r($d);
}

print_r($d);
Nach dem Login kopieren

输出:

Array
(
    [0] => a
    [1] => b
    [2] => c
)
Array
(
    [0] => b
    [1] => b
    [2] => c
)
Array
(
    [0] => b
    [1] => c
    [2] => c
)
Array
(
    [0] => b
    [1] => c
    [2] => c
)
Nach dem Login kopieren

相关推荐:

php 传值赋值与引用赋值的区别_PHP教程

PHP变量赋值、代入给JavaScript中的变量,赋值javascript

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in die Referenzzuweisung und Wertzuweisung von PHP-Variablen (Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage