积累一下 PHP 魔术方法

xyj2156 PHP 2018-05-18

这里记录下 PHP中所有的 魔术方法

到现在为止我知道魔术方法

__construct(), __destruct(), __call(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __clone();

下面例子使用的类

<?php


class A
{
        public $c= 12;
    public function __construct()
    {
        echo 'consturt';
    }
    
    public function __destruct()
    {
        echo '✔';
    }

    public function __call($name, $argument)
    {
        echo '<pre>';
        echo $name;
        print_r($argument);
    }

    public function __isset($name)
    {
        echo '正在判断', $name, '是不是存在。';
    }

    public function __unset($name)
    {
        echo '正在删除', $name, '属性';
    }

    public function __get($name)
    {
        echo '正在尝试获取', $name, '属性';
    }

    public function __set($name, $val)
    {
        echo '正在尝试设置', $name, '属性, 值是';
        print_r($val);
    }

    public function __sleep()
    {
        echo '我要睡觉了';
                return [];
    }

    public function __wakeup()
    {
        echo '谁,谁,谁把我弄醒的?';
    }

    public function __clone()
    {
        echo '我不要被克隆。';
    }

    public function __toString()
    {
        echo '自定义变成字符串';
                return '';
    }

    public function __invoke()
    {
        echo '我是类,竟然拿我当函数了。';
    }

        public static function __callStatic($name, $arg)
        {
                echo '调用不存在的静态方法', $name, '参数是:';
                print_r($arg);
        }

        public function __set_state ()
        {
                echo '正在用var_export导出后 eval 我';
        }

        public function __debugInfo()
        {
                echo '正在用var_dump 输出 我';
                return [
                     'name' => 'jief'
               ];
        }
}

class B
{
    public function B()
    {
        echo '不是 consturt';
    }
    
    public function __destruct()
    {
        echo '✖';
    }
}
__construct() ; 构造函数, 实例化类完成后自动调用,其实还可以写一个和类一样的名字的方法,在以前,构造函数就是这么干的, 不推荐这么干。

使用 new A; new B 时;
上面会输出 consturt(A 构造) (A 析构) 不是 consturt(B “类”构造) (B析构);

__destruct(); 析构函数,销毁对象前调用这个函数。

上面已经显示了。

下面删除掉 析构和构造函数

__call() 调用 类中没有定义的方法的时候 会被自动调用。

$a = new A; $a -> b(1, 2, 3, 4); 输出:

b(函数名)
下面是参数数组
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
)
__get() 获取不存在的属性或者 私有和受保护的 属性时,自动调用。
$a = new A;
$b = $a -> b;

输出 "正在尝试获取b属性"
__set() 设置不存在的属性或者 私有和受保护的属性是,自动调用。
$a = new A;
$a -> b = 78;

输出 "正在尝试设置b属性, 值是78";
__isset() 判断 不存在的属性或者 私有和受保护的属性是,自动调用。
$a = new A;
isset($a -> b);

输出 "正在判断b是不是存在。";
__unset() 删除 不存在的属性或者 私有和受保护的属性是,自动调用。
$a = new A;
isset($a -> b);

输出 "正在删除b属性";
__sleep() 序列化 类时 自动调用;返回一个数组,包含可以被序列化的私有属性,或者受保护的属性。
$a = new A;
echo serialize($a);
var_dump($b);

输出 '我要睡觉了 string(12) "O:1:"A":0:{}"';
__wakeup() 反序列化时候被调用
$a = new A;
$c = serialize($a);
print_r(unserialize($c));

输出:
我要睡觉了谁,谁,谁把我弄醒的?A Object
(
    [c] => 12
)
__toString() 尝试转换成字符串的时候 自动被调用
$a = new A;
echo $a;

输出:自定义变成字符串
__invoke() 尝试把类当作函数被调用的时候 自动被调用
$a = new A;
$a();

输出:我是类,竟然拿我当函数了。
__clone() 当类被克隆的时候 自动调用
$a = new A;
clone($a);

输出:我不要被克隆。

介绍完熟悉的 说一下我不熟悉的,这才是我的目的。

__callStatic(), __set_state(), __debugInfo()

官方文档地址:

__callStatic :http://php.net/manual/zh/language.oop5.overloading.php#object.callstatic

__set_state:http://php.net/manual/zh/language.oop5.magic.php#object.set-state

__debugInfo:http://php.net/manual/zh/language.oop5.magic.php#object.debuginfo

__callStatic 调用不存在的时方法 被自动调用 ,这儿需要注意的是,有这个方法,但是没有设置为静态,也会被调用。
$a = new A;
$a::b(1,2,3,4);

输出:调用不存在的静态方法b参数是:Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)
__set_state 当调用 var_export() 导出类时,此静态 方法会被调用。
$a = new A;
$a -> c = 3;
$c = var_export($a, true);

echo $c;
eval('$d = '.$c.';');

var_dump($d);

输出:A::__set_state(array(
   'c' => 3,
))正在用var_export导出后 eval 我NULL
__debugInfo 使用 var_dump 时 自动使用 这个函数返回的数组内容 替换掉 显示的属性。
$a = new A;
var_dump($a);

正在用var_dump 输出 我object(A)#1 (1) {
  ["name"]=>
  string(4) "jief"
}

PS

知识在于积累。

PREV
palcon 框架中使用关联查询时定义条件和字段
NEXT
phalcon 模型 新发现

评论(0)

评论已关闭