1、&参考(https://www.cnblogs.com/chrdai/p/11061174.html)在PHP中,将变量$a赋值给$b实际上是将两个变量指向同一个内存地址.$a=range(1,100000);var_dump(memory_get_usage());//int(6698184)$b=$a;var_dump(memory_get_usage());//int(6698184)$a=range(1,200000);var_dump(memory_get_usage());//int(17184024)从上面可以看出,当$b=$a时,内存空间并没有重新分配给$b,而是两个变量指向同一个内存地址。而重新分配$a时,就是重新为$a开辟一块内存空间。变量之间的引用赋值就是将变量指向同一个内存地址。当任何一个变量的值发生变化时,这两个变量所指向的内存地址都会更改为新分配的内存地址。$a=range(1,100000);var_dump(memory_get_usage());//int(6698208)$b=&$a;var_dump(memory_get_usage());//整数(6698208)$a=范围(1,100000);var_dump(memory_get_usage());//int(6698208)对引用变量的unset操作只会解引用,不会破坏内存空间。$a=1;$b=&$a;unset($b);echo$a;对象引用:A类{public$name=1;函数getName(){echo$this->name;}}$a=新A;$b=$a;//$b和$a指向同一个内存空间地址$b->name=2;$a->getName();//2个变量引用示例:$d=['a','b','c'];foreach($das$k=>$v){$v=&$d[$k];}//最终程序执行后$d的值是?第一次遍历:$d[0]被引用并赋值给$v,两者都指向相同值的内存地址'a'。第二次遍历:$d[1]通过引用赋值给$v,由于之前$v和$d[0]都指向同一个地址,这次循环将$d[0]和$v都修改$d[1]的值b。第三次遍历:$d[2]被引用并赋值给$v,$v和$d[1]之前都指向同一个地址,所以本次循环将$d[1]和$v都修改为$d[2]的值c。所以最后$d=['b','c','c']函数引用functiont(&$a){$a++;}$a=1;t($a);echo$a;//2通过引用传递给函数的参数必须是变量名,不能是确定的值,否则会报错。函数&t(){静态$a=0;$a++;回声$a;返回$a;}$b=t();//输出:1$b=5;$b=t();//输出:2$b=&t();//输出3.$b=3$b=5;//$a=5$b=t();//输出:6$b=t()调用的函数不是引用调用函数,和普通函数调用一样。$b=&t()的形式是函数的引用调用。由于静态变量在函数结束后不会被销毁的特性,第一次调用函数时输出1,第二次调用函数时输出2。第三次是按引用调用函数,就是把return后的变量$a的地址和$b的内存地址指向同一个地址。因此,将5赋值给$b后,再次调用该函数会输出6。//官方示例:classtalker{private$data='Hi';publicfunction&get(){返回$this->data;}publicfunctionout(){echo$this->data;}}$a=newtalker();$b=&$a->get();$a->out();$b='How';$a->out();$b='are';$a->out();$b='you';$a->out();//最终输出:HiHowareare2,PHPCopy-on-Write中的COW(Copy-on-Write)机制,即就是,writeinvariables输入的时候,会复制一份内存,这是内存优化的常用方法。通过变量赋值的方式给变量赋值时,并没有为新变量分配新的内存,而是使用一个计数器来共享内存。只有当其中一个变量的值发生变化时,新的内存才会分配给变量的变量。常见的场景包括:变量的多次赋值;函数的参数传递,函数体中实际参数的修改等。3.静态变量静态变量只存在于局部函数作用域内,只有在函数第一次执行时才创建。函数执行后,静态变量的值不会丢失。函数t(){静态$a=1;$a++;echo$a;}t();//2t();//3t();//44、==和===的区别都是用来判断等号前后的值是否相等。不同的是===判断的是值是否相等,也是判断值的类型是否相等。只有当值和数据类型相同时,===才返回true,否则返回false。而==如果值相等则返回true,不管数据类型是否相同。$a=0;$b='';var_dump($a==$b);//布尔值truevar_dump($a===$b);//booleanfalse5,isset和empty的区别empty():当变量不存在或变量的值为false时返回true,否则返回false。$a='';$b=0;$c=false;$d=1;$e='0';$f='0.0';$g=null;var_dump(isset($m));//booleanfalsevar_dump(isset($a));//布尔值truevar_dump(isset($b));//布尔值truevar_dump(isset($c));//布尔值truevar_dump(isset($d));//布尔值truevar_dump(isset($e));//布尔值truevar_dump(isset($f));//布尔值truevar_dump(isset($g));//布尔值falsevar_dump(empty($m));//布尔值truevar_dump(empty($a));//布尔值truevar_dump(empty($b));//布尔值truevar_dump(empty($c));//布尔值truevar_dump(empty($d));//布尔值falsevar_dump(empty($e));//布尔值truevar_dump(empty($f));//布尔值falsevar_dump(empty($g));//booleantrue6,magicfunction(magicmethod)Magicmethod必须声明为public__construct():这个方法在对象被实例化时自动调用。__destruct():当对对象的所有引用都被删除或对象真正被销毁时执行。classA{function__construct(){echo'我被自动执行了!';}}$a=newA;B类{public$name;公共函数__construct($name){$this->name=$name;echo'你的名字是:'.$this->name;}publicfunction__destruct(){echo'对象被销毁';}}$b=newB('Jeccy');__call($name,$arguments):调用一个不可访问的对象(方法不存在或被定义时,方法被保护或私有),它会被调用。$name是不可访问的方法名,$arguments是访问时传递的参数。B类{公共$name=22;受保护的函数getName(){echo$this->name;}函数__call($name,$arguments){var_dump($name);var_dump($参数);}}$b=newB;$b->getName(1,2);//字符串'getName'数组([0]=>1[1]=>2)$b->getAge(3,4);//string'getAge'Array([0]=>3[1]=>4)callStatic($name,$arguments):当访问一个不可访问的(方法不存在或定义为受保护的,私有的)方法时静态上下文,将被调用。$name是不可访问的方法名,$arguments是访问时传递的参数。B类{公共静态函数__callStatic($name,$arguments){echo$name.'
';var_dump($参数);}}$b=newB;B::getAge('静态方法');//getAgeArray([0]=>staticmethod)__get($name):当服务不可访问(不存在或设置为非公共)属性时,它将被调用。$name是被访问的属性的名称。B类{private$name='jeccy';公共$age=2;保护$性别=1;publicfunction__get($name){echo'property'.$name.'不存在或无法访问
';}}$b=新B;echo$b->名字;//属性名不存在或无法访问echo$b->age;//2echo$b->性别;//属性sex不存在或无法访问Accessedecho$b->address;//属性地址不存在或不可访问__set(string$name,mixed$value):给不可访问的属性赋值时调用。$name是不可访问属性的名称;$value是分配给属性的值。B类{private$name='jeccy';公共$age=2;保护$性别=1;公共函数__set($name,$value){$this->$name=$value;}publicfunctiongetInfo(){echo'name='.$this->name.',';echo'age='.$this->age.',';echo'sex='.$this->sex;echo'sex='.$this->sex;}}$b=newB;$b->name='mark';$b->age=3;$b->sex=2;$b->address=2;$b->getInfo();//name=mark,age=3,sex=2,address=2*__isset(string$name):当isset()或empty()被不可访问的属性调用时,该方法将被调用。$name是要访问的属性名称。B类{private$name='jeccy';公共$age=2;保护$性别=1;公共函数__isset($name){echoisset($this->$name)?$名字。存在
':$name.'不存在
';}publicfunctiongetInfo(){echo'name='.$this->name.',';echo'age='.$this->age.',';echo'sex='.$this->sex;}}$b=newB;isset($b->name);//name属性存在isset($b->age);//age属性可以访问,所以__isset()方法不会被调用isset($b->sex);//sex属性存在isset($b->address);//address属性不存在_unset(string$name):当对一个不可访问的属性调用unset()时调用。参数$name是指要访问的变量名。B类{private$name='jeccy';公共$age=2;保护$性别=1;公共函数__unset($name){unset($this->$name);}publicfunctiongetInfo(){var_dump($this);}}$b=newB;unset($b->name);//名字存在unset($b->age);//age属性可以访问,所以__isset()方法不会被调用unset($b->sex);//性别存在unset($b->address);//地址不存在$b->getInfo();//D:wamp64wwwmineaa.php:14:object(_B_)[_1_]__sleep():在类外的对象上使用serialize()方法时调用该方法。它可以用来对对象中的属性进行处理操作,比如数据处理,或者只返回需要序列化的属性。此方法返回一个数组,其中包含需要序列化的属性。B类{private$name='jeccy';公共$age=2;保护$性别=1;publicfunction__sleep(){returnarray('sex','age','name');}}$b=newB;echoserialize($b);//O:1:"B":3:{s:6:"*sex";i:1;s:3:"age";i:2;s:7:"Bname";s:5:"jeccy";}7、静态属性和静态方法(参考:https://www.cnblogs.com/chrdai/p/6863090.html)
