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()); // int(6698208)$a = range(1,100000);var_dump(memory_get_usage()); // int(6698208)

        对于援用的变量执行 unset操作,也只会勾销援用,而不会销毁内存空间。

$a = 1;$b = & $a;unset($b);echo $a;

        对象的援用

class A {    public $name = 1;    function getName(){        echo $this->name;    }}$a = new A;$b = $a; // $b 与 $a 指向同一个内存空间地址$b->name = 2;$a->getName(); // 2

变量援用示例:

$d = ['a', 'b', 'c'];foreach($d as $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']

        函数援用

function t(&$a){    $a++;}$a = 1;t($a);echo $a; // 2

        通过援用的模式传递给函数参数,必须是一个变量名,而不能是一个确定的值,否则会报错。

function &t(){    static $a = 0;    $a++;    echo $a;    return $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的内存地址指向同一个地址。因而,在给 $b赋值为5后,再次调用函数,就会输入6。

//官网示例:class talker{    private $data = 'Hi';    public function & get()    {        return $this->data;    }    public function out()    {        echo $this->data;    }}$a = new talker();$b = &$a->get();$a->out();$b = 'How';$a->out();$b = 'are';$a->out();$b = 'you';$a->out();//最终输入:HiHowareare

2,PHP中的 COW ( Copy-on-Write写时复制 ) 机制
        写时复制,即在变量进行写入时,才会复制一份内存,这是内存优化的罕用伎俩。
        在通过变量赋值的形式赋值变量时,不会申请新的内存给新的变量,只是应用一个计数器来共用内存。只有当其中某一个变量的值发生变化时,才会调配新的内存给变量的变量。
        罕用场景有:变量的屡次赋值;函数的参数传递,并在函数体内批改实参等。

3,动态变量
        动态变量仅在部分函数作用域中存在,且仅在函数第一次执行时创立,当函数执行结束之后,动态变量的值不会失落。

function t(){    static $a = 1;    $a++;    echo $a;}t(); // 2t(); // 3t(); // 4

4,== 与 === 的区别
        两者均用于判断等号前后的值是否相等,区别在于 ===在判断值相等与否的同时,还会判断值的类型是否相等,仅当值与数据类型均雷同时,===才会返回 true,其余状况就返回 false。而 ==在值相等的状况下就会返回 true,无论数据类型是否雷同。

$a = 0;$b = '';var_dump($a == $b); // boolean truevar_dump($a === $b); // boolean false

5,isset 和 empty 的区别
isset():变量存在且值不为 NULL就返回 true,反之返回 false
empty():变量不存在或者变量值为 false时就返回 true,反之返回 false

$a = '';$b = 0;$c = false;$d = 1;$e = '0';$f = '0.0';$g = null;var_dump(isset($m)); // boolean falsevar_dump(isset($a)); // boolean truevar_dump(isset($b)); // boolean truevar_dump(isset($c)); // boolean truevar_dump(isset($d)); // boolean truevar_dump(isset($e)); // boolean truevar_dump(isset($f)); // boolean truevar_dump(isset($g)); // boolean falsevar_dump(empty($m)); // boolean truevar_dump(empty($a)); // boolean truevar_dump(empty($b)); // boolean truevar_dump(empty($c)); // boolean truevar_dump(empty($d)); // boolean falsevar_dump(empty($e)); // boolean truevar_dump(empty($f)); // boolean falsevar_dump(empty($g)); // boolean true

6,魔术函数(魔术办法) 魔术办法都必须被申明为public

  • __construct():该办法在对象被实例化时会主动调用。
  • __destruct():当对象的所有援用被删除或者当对象被事实销毁时执行。
class A {    function __construct()    {        echo '我被主动执行了!';    }}$a = new A;class B {    public $name;        public function __construct($name){        $this->name = $name;        echo '你的名字是:'.$this->name;    }        public function __destruct(){        echo '对象被销毁了';    }}$b = new B('Jeccy');
  • __call($name, $arguments):在对象中调用一个不可拜访(办法不存在或被定义为 protectedprivate)的办法时,会被调用。$name为不可拜访的办法名,$arguments为拜访时传的参数。
class B {    public $name=22;    protected function getName()    {        echo $this->name;    }    function __call($name, $arguments){        var_dump($name);        var_dump($arguments);    }}$b = new B;$b->getName(1,2); // string 'getName'  Array ( [0] => 1 [1] => 2 )$b->getAge(3,4); // string 'getAge'  Array ( [0] => 3 [1] => 4 )
  • callStatic($name, $arguments):在动态上下文中拜访一个不可拜访(办法不存在或被定义为 protectedprivate)的办法时,会被调用。$name为不可拜访的办法名,$arguments为拜访时传的参数。
class B {    public static function __callStatic($name, $arguments)    {        echo $name.'<br>';        var_dump($arguments);    }}$b = new B;B::getAge('static method');// getAge Array ( [0] => static method )
  • __get($name):服务不可拜访(不存在或设置为非public)属性时,会被调用。$name为拜访的属性的名称。
class B {    private $name = 'jeccy';    public $age = 2;    protected $sex = 1;    public function __get($name)    {        echo '属性'.$name.'不存在或不可被拜访<br>';    }}$b = new B;echo $b->name; // 属性name不存在或不可被拜访echo $b->age;  // 2echo $b->sex;  // 属性sex不存在或不可被拜访echo $b->address; // 属性address不存在或不可被拜访
  • __set(string $name, mixed $value):在给不可拜访的属性赋值时,会被调用。$name为不可拜访的属性的名称;$value为给属性赋的值。
class B {    private $name = 'jeccy';    public $age = 2;    protected $sex = 1;    public function __set($name, $value)    {        $this->$name = $value;    }    public function getInfo()    {        echo 'name='.$this->name.',';        echo 'age='.$this->age.',';        echo 'sex='.$this->sex;        echo 'sex='.$this->sex;    }}$b = new B;$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为拜访的属性名。

class B {    private $name = 'jeccy';    public $age = 2;    protected $sex = 1;    public function __isset($name)    {        echo isset($this->$name) ? $name.'存在<br>' : $name.'不存在<br>';    }    public function getInfo()    {        echo 'name='.$this->name.',';        echo 'age='.$this->age.',';        echo 'sex='.$this->sex;    }}$b = new B;isset($b->name); // name属性存在isset($b->age); // age属性能够拜访,故不会调用 __isset() 办法isset($b->sex); // sex属性存在isset($b->address); // address属性不存在
  • _unset(string $name):当对不可拜访属性调用unset()时,会被调用。参数 $name是指要拜访的变量名称。
class B {    private $name = 'jeccy';    public $age = 2;    protected $sex = 1;    public function __unset($name)    {        unset($this->$name);    }    public function getInfo()    {        var_dump($this);    }}$b = new B;unset($b->name); // name存在unset($b->age); // age属性能够拜访,故不会调用 __isset() 办法unset($b->sex); // sex存在unset($b->address); // address不存在$b->getInfo(); // D:wamp64wwwmineaa.php:14: object(_B_)[_1_]

7,动态属性和静态方法(参考:https://www.cnblogs.com/chrdai/p/6863090.html)