


This article brings you a detailed introduction (code) about reference assignment and value assignment of PHP variables. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you. .
1. Use memory_get_usage() to check PHP memory usage
1. Pass value assignment
// 定义一个变量 $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());
Output result:
int(989768) int(989856) int(1855608)
Define a Variable $a = range(0, 10000);
##$b = $a;
Modify a$a = range(0, 10000);
COW was first used in Unix systems to optimize thread and memory usage, and was later widely used in various programming languages, such as C's STL, etc.
In the PHP kernel, COW is also the main memory optimization method.
When assigning a value to a variable through variable assignment, new memory will not be allocated to store the value of the new variable, but the memory will simply be shared through a counter. Only when the value of the variable pointed to by one of the references changes, new space is allocated to save the value content to reduce memory usage.
In many scenarios, PHP uses COW for memory optimization. For example: multiple assignments of variables, passing function parameters, and modifying actual parameters in the function body, etc.
// 定义一个变量
$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());
Output result:
int(989760) int(989848) int(989840)
Define a variable$a = range(0, 10000);
Define variable b and assign the reference of variable a to b $b = &$a;
$a = range(0, 10000);
2. Use
to view the reference status of variables
xdebug_debug_zval( ) Used to display variable information. The xdebug extension needs to be installed. 1. Pass-by-value assignment
$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');
Output result:
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)=1Define variables
$a = 1;
<pre class="brush:php;toolbar:false">$a = 1;
xdebug_debug_zval('a');</pre>Output
a: (refcount=1, is_ref=0)=1refcount=1
means that the number of references to the memory address pointed to by the variable becomes 1is_ref=0
means that the variable Instead of quoting
$b and assign the value of $a
to $b
, $b = $a;
$b = $a;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
Output
a: (refcount=2, is_ref=0)=1 b: (refcount=2, is_ref=0)=1refcount=2
indicates that the variable points to The number of references to the memory address becomes 2is_ref=0
, indicating that the variable is not a reference
## Write operation to variable
$a = 2;
<pre class="brush:php;toolbar:false">$a = 2;
xdebug_debug_zval('a');
xdebug_debug_zval('b');</pre>
Outputa: (refcount=1, is_ref=0)=2
b: (refcount=1, is_ref=0)=1
Because of the COW mechanism, the variable When $a
performs a write operation, a new memory space will be allocated for variable$a to store the value of variable
$a.
At this time, the number of references to the memory addresses pointed to by $a
and
$b becomes 1.
2. Reference assignment
$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');
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
Define variables
$a = 1;
<pre class="brush:php;toolbar:false">$a = 1;
xdebug_debug_zval('a');</pre>
Outputa: (refcount=1, is_ref=0)=1
refcount=1
Indicates that the number of references to the memory address pointed to by the variable becomes 1is_ref=0
Indicates that the variable is not a reference
输出 输出 因为变量 输出 虽然销毁的 输出 输出 输出 输出 因为php中对象本身就是引用赋值。对 此时, ![$v 和 $d[0] 在内存中分别开辟了一块空间](http://md.ws65535.top/xsj/201... ![$v = &$d[0] 改变了 $val 指向的内存地址](http://md.ws65535.top/xsj/201... ![$v = ‘b’ => $d[0] = ‘b’](http://md.ws65535.top/xsj/201... ![$d[2] = ‘b’](http://md.ws65535.top/xsj/201... ![$v = &$d[1]](http://md.ws65535.top/xsj/201... ![$v = ‘c’ => $d[1] = ‘c’](http://md.ws65535.top/xsj/201... ![$d[2] = ‘c’](http://md.ws65535.top/xsj/201... ![$v = &$d[2]](http://md.ws65535.top/xsj/201... 相关推荐:定义变量
$b
,把 $a
的引用赋给 $b
, $b = &$a;
$b = &$a;
xdebug_debug_zval('a');
xdebug_debug_zval('b');
a: (refcount=2, is_ref=1)=1
b: (refcount=2, is_ref=1)=1
refcount=2
表示该变量指向的内存地址的引用个数变为2is_ref=1
表示该变量是引用对变量
<pre class="brush:php;toolbar:false">$a = 2;
xdebug_debug_zval('a');
xdebug_debug_zval('b');</pre>
$a
进行写操作 $a = 2;
a: (refcount=2, is_ref=1)=2
b: (refcount=2, is_ref=1)=2
$a
和变量 $b
指向相同的内存地址,其实引用。
对变量 $a
进行写操作时,会直接修改指向的内存空间的值,因此变量 $b
的值会跟着一起改变。三、当变量时引用时,unset()只会取消引用,不会销毁内存空间
$a = 1;
$b = &$a;
// unset 只会取消引用,不会销毁内存空间
unset($b);
echo $a;
1
定义变量
$a
,并将 $a
的引用赋给变量 $b
$a = 1;
$b = &$a;
销毁
$b
unset($b);
输出
$a
$b
,但是 $a
的引用和内存空间依旧存在。echo $a;
1
四、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');
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 }
实例化对象
$p1 = new Person;
$p1 = new Person;
xdebug_debug_zval('p1');
p1: (refcount=1, is_ref=0)=class Person { public $age = (refcount=2, is_ref=0)=1 }
refcount=1
表示该变量指向的内存地址的引用个数变为1is_ref=0
表示该变量不是引用把
$p1
赋给 $p2
$p2 = $p1;
xdebug_debug_zval('p1');
xdebug_debug_zval('p2');
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 }
refcount=2
表示该变量指向的内存地址的引用个数变为2对
$p2
中的属性 age
进行写操作$p2->age = 2;
xdebug_debug_zval('p1');
xdebug_debug_zval('p2');
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 }
$p2
中的属性 age
进行写操作时,会直接修改指向的内存空间的值,因此变量 $p1
的 age
属性的值会跟着一起改变。五、实战例题分析
/**
* 写出如下程序的输出结果
*
* $d = ['a', 'b', 'c'];
*
* foreach($d as $k => $v)
* {
* $v = &$d[$k];
* }
*
* 程序运行时,每一次循环结束后变量 $d 的值是什么?请解释。
* 程序执行完成后,变量 $d 的值是什么?请解释。
*/
1. 第一次循环
推算出进入
foreach
时 $v
、$d[$k]
的值$k = 0
$v = 'a'
$d[$k] = $d[0] = 'a'
$v
和 $d[0]
在内存中分别开辟了一块空间$v = &$d[0]
改变了 $v 指向的内存地址$v = &$d[0]
第一次循环后 $d 的值:
['a', 'b', 'c']
2. 第二次循环
进入
foreach
时 $v
被赋值为 'b',此时$v
指向的内存地址与 $d[0]
相同,且为引用,因此 $d[0]
的值被修改为 'b'$v = 'b'
=> $d[0] = 'b'
推算出进入
foreach
时 $d[$k]
的值$k = 1
$d[$k] = $d[1] = 'b'
$v = &$d[1]
改变了 $v 指向的内存地址$v = &$d[1]
第二次循环后
$d
的值['b', 'b', 'c']
3. 第三次循环
进入
foreach
时 $v
被赋值为 'c',此时$v
指向的内存地址与 $d[1]
相同,且为引用,因此 $d[1]
的值被修改为 'c'$v = 'c'
=> $d[1] = 'c'
推算出进入
foreach
时 $d[$k]
的值$k = 2
$d[2] = 'c'
$v = &$d[2]
改变了 $v 指向的内存地址$v = &$d[2]
第三次循环后
$d
的值['b', 'c', 'c']
4. 实测
$d = ['a', 'b', 'c'];
foreach ($d as $k=>$v)
{
$v = &$d[$k];
print_r($d);
}
print_r($d);
输出:
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
)
The above is the detailed content of Detailed introduction to reference assignment and value assignment of PHP variables (code). For more information, please follow other related articles on the PHP Chinese website!

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

方法:1、用“str_replace(" ","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\ \;||\xc2\xa0)/","其他字符",$str)”语句。

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

在PHP中,可以利用implode()函数的第一个参数来设置没有分隔符,该函数的第一个参数用于规定数组元素之间放置的内容,默认是空字符串,也可将第一个参数设置为空,语法为“implode(数组)”或者“implode("",数组)”。

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

SublimeText3 Linux new version
SublimeText3 Linux latest version

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

WebStorm Mac version
Useful JavaScript development tools

SublimeText3 English version
Recommended: Win version, supports code prompts!
