php之引用

1 篇文章 0 订阅

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指向同一个对象,并且unsetnull其中一个,另个不变。

变量引用

<?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"
}
***************************************************/

总结:

  1. 所有的引用都是一样,当unset其中一个,并不影响另一个。当null其中一个,两个都null。
  2. 对象赋值比较特殊,$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的数据拷贝,重新申请一块内存进行存储。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值