null和unset区别
变量是个地址值,类似于0x1288。方便识别与编程,给了一个标识,即变量名。
变量、参数、函数引用如下:
$a = &$b; //地址寄存器中有两个格子,放了两个值是相同的,
//(这个值直接指向变量的值)
//并给他们一个标志为a,一个标志为b
$a = null; //此时 a 和 b 同时指向的地址寄存器的值被赋于 null。
unset($a); //此时 a 在地址寄存器中的格子中的值被清空。
对象引用如下:
$a = &$b; //地址寄存器中有两个格子,放了两个值是相同的,
//(这个值不直接指向变量的值,可以参考最后面的图。)
//并给他们一个标志为a,一个标志为b
所有的引用都是一样,当unset其中一个,并不影响另一个。当null其中一个,两个都null。
对象赋值比较特殊,`$a=$b;`则对象a和b指向同一个对象,并且unset和null其中一个,另个不变。
变量引用
<?php
$a="A";
$b =&$a;
$b="E";
echo $a;
echo $b;
echo "\n";
unset($b); //替换成null,下面两个的值都会变成null;
echo $a;
echo $b;
echo "\n";
/*********************以上例程会输出:****************
AA
EE
E
Notice: Undefined variable: b in C:\Users\leon\Desktop\count.php on line 15
***************************************************/
参数引用
//参数引用和变量引用一模一样
<?php
function test(&$a){
$a=$a+100;
}
$b=1;
echo $b;
test($b);
echo "\n";
echo $b;
echo "\n";
function test2(&$a2){
unset($a2); //替换成null,下面两个的值都会变成null;
}
$b=1;
echo $b;
test2($b);
echo "\n";
echo $b;
/*********************以上例程会输出:****************
1
101
1
1
***************************************************/
函数引用
<?php
function &test(){
static $b=0;//申明一个静态变量
$b=$b+1;
echo $b;
return $b;
}
$a=test();//这条语句会输出 $b的值 为1
$a=5; $a=test();//这条语句会输出 $b的值 为2
$a=&test();//这条语句会输出 $b的值 为3
$a=5; $a=test();//这条语句会输出 $b的值 为6
unset($a); //替换成null,下面两个的值都会变成null;
test();
/*********************以上例程会输出:****************
12367
***************************************************/
对象引用
<?php
error_reporting(0);
class a{
var $abc="A";
}
$b=new a;
$c=& $b;
var_dump($b);
var_dump($c);
unset($b); //替换成null,下面两个的值都会变成null;
var_dump($b);
var_dump($c);
$x=new a;
$y=$x;
var_dump($x);
var_dump($y);
unset($x); //替换成null,下面x的值都会变成null,y值还是老样子;
var_dump($x);
var_dump($y);
/*********************以上例程会输出:****************
class a#1 (1) {
public $abc =>
string(1) "A"
}
class a#1 (1) {
public $abc =>
string(1) "A"
}
NULL
class a#1 (1) {
public $abc =>
string(1) "A"
}
class a#2 (1) {
public $abc =>
string(1) "A"
}
class a#2 (1) {
public $abc =>
string(1) "A"
}
NULL
class a#2 (1) {
public $abc =>
string(1) "A"
}
***************************************************/
总结:
- 所有的引用都是一样,当unset其中一个,并不影响另一个。当null其中一个,两个都null。
- 对象赋值比较特殊,
$a=$b;
则对象a和b指向同一个对象,并且unset和null其中一个,另个不变。
<?php
// Assignment of an object
Class Object{
public $foo="bar";
};
$objectVar = new Object();
$reference =& $objectVar;
$assignment = $objectVar
//
// $objectVar --->+---------+
// |(handle1)----+
// $reference --->+---------+ |
// |
// +---------+ |
// $assignment -->|(handle1)----+
// +---------+ |
// |
// v
// Object(1):foo="bar"
//
?>
<?php
$objectVar->foo = "qux";
print_r( $objectVar );
print_r( $reference );
print_r( $assignment );
//
// $objectVar --->+---------+
// |(handle1)----+
// $reference --->+---------+ |
// |
// +---------+ |
// $assignment -->|(handle1)----+
// +---------+ |
// |
// v
// Object(1):foo="qux"
//
?>
<?php
$objectVar = null;
print_r($objectVar);
print_r($reference);
print_r($assignment);
//
// $objectVar --->+---------+
// | NULL |
// $reference --->+---------+
//
// +---------+
// $assignment -->|(handle1)----+
// +---------+ |
// |
// v
// Object(1):foo="qux"
Tips:
php中对于地址的指向(类似指针)功能不是由用户自己来实现的,是由Zend核心实现的,php中引用采用的是“写时拷贝”的原理,就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的。
通俗的讲 1:如果有下面的代码 $a="ABC"; $b=$a;
其实此时$a与$b
都是指向同一内存地址,而并不是$a与$b
占用不同的内存。
如果在上面的代码基础上再加上如下代码 $a="EFG";
由于$a与$b
所指向的内存的数据要重新写一次了,此时Zend核心会自动判断,自动为$b
生产一个$a
的数据拷贝,重新申请一块内存进行存储。