魔术方法

所有其他魔术方法都必须是公共的,否则无效。

构造方法:__construct

自动输出于首部

  • 出发时机:在每次创建新对象时调用此方法,该方法无返回值
  • 作用:初始化一批参数,定义后new类()中传值
<?php

class test
{
    public $user = '小明';

    public function __construct($config = [],$tip='')
    {
        isset($config['user']) ? $this->user = $config['user'] : '';
    }
}


$test = new test();
echo $test->user;		//小明

$config['user'] = '小黑';
$test = new test($config);
echo $test->user;		//小黑

析构方法 __destruct()

PHP将在对象被销毁前(即从内存中清除前)调用这个方法。默认情况下,PHP仅仅释放对象属性所占用的内存并销毁对象相关的资源,析构函数允许你在使用一个对象之后执行任意代码来清除内存。当PHP决定你的脚本不再与对象相关时,析构函数将被调用。

  • 没有参数
<?php

class test
{
    public $name = '小明';
  
    public function __construct()
    {
        $this->name = "小黑";
    }

    public function __destruct()
    {
        echo "再见" . $this->name, "<br>";
    }
}


$test = new test();		//再见小黑

__get

方法有一个参数,表示要调用的变量名。方法有一个参数,表示要调用的变量名。

  • 当程序试图调用一个未定义不可见的成员变量时,
<?php
  
class test
{
    private $type; // 或者   protected $type;   
    //tip:为使进入__get方法中	
    public function __get($property)
    {
        if (isset($this->$property)) {
            echo '变量' . $property . '的值为:' . $this->$property . '<br>';
        } else {
            echo '变量' . $property . '未定义,初始化为<br>';
            $this->$property=111;
        }
    }
}

$test = new test();
$test->type;			//变量type未定义,初始化为
$test->type;			//变量type的值为:111

__SET

__set()方法包含两个参数,分别表示变量名称和变量值,两个参数都不可省略。

  • 当程序试图写入一个不存在或者不可见的成员变量时
<?php

class test
{
    protected  $type ;

    public function __set($name, $value)
    {
        if (isset($this->$name)) {
            $this->$name = $value;
            echo '变量' . $name . '赋值为:' . $value . '<br>';
        } else {
            $this->$name = $value;
            echo '变量' . $name . '被初始化为:' . $value . '<br>';
        }
    }
}

$test = new test();
$test->type = 'DIY';			//变量type被初始化为:DIY
$test->type = 'YID';			//变量type赋值为:YID

__isset

在类外部使用isset(),测定成员是否存在时自动调用。

  • 当程序试图调用一个未定义不可见的成员变量时
<?php

class test
{
    public $sex = '女';
    private $name = '男';
    private $age = '18';


    public function __isset($content)
    {
        echo isset($this->$content) ? 1 : 0, ": ";
        echo "当在类外部使用isset()函数测定私有成员{$content}时,自动调用";
    }
}

$test = new test();
echo isset($test->sex), "<br>";			//1
echo isset($test->name), "<br>";		//1: 当在类外部使用isset()函数测定私有成员name时,自动调用
echo isset($test->age), "<br>";			//1: 当在类外部使用isset()函数测定私有成员age时,自动调用
echo isset($test->other), "<br>";		//0: 当在类外部使用isset()函数测定私有成员other时,自动调用

__unset

在类外部使用unset(),销毁成员时自动调用。

  • 当程序试图销毁一个未定义不可见的成员变量时
<?php

class test
{
    public $sex = '女';
    private $name = '男';
    private $age = '18';


    public function __unset($content)
    {
        echo "当在类外部使用unset()函数销毁私有成员{$content}时,自动调用","<br>";
    }
}

$test = new test();
unset($test->sex);			
echo  $test->sex;			//Notice: Undefined property: test::$sex

unset($test->name);			//当在类外部使用unset()函数销毁私有成员name时,自动调用
unset($test->age);			//当在类外部使用unset()函数销毁私有成员age时,自动调用
unset($test->other);		//当在类外部使用unset()函数销毁私有成员other时,自动调用

__call与__callStatic

在类外部使用unset(),销毁成员时自动调用。

  • 当程序试图调用一个未定义不可见的方法时
  • 如果方法不存在就去父类中找这个方法,如果父类中也不存在就去调用本类的__call()方法
  • 可配合call_user_func、call_user_func_array实现加工后连贯操作等
  • __callStatic在PHP5.3.0以上版本有效
<?php

class test
{
    function __call($method, $arg_array)
    {
        var_dump($method);
        var_dump($arg_array);
    }

    static  function __callStatic($method, $arg_array)
    {
        var_dump($method);
        var_dump($arg_array);
    }

}

$test = new test();
$test->func('a', 'b', [1, 2, 3]);
$test::func('a', 'b', [1, 2, 3]);

//输出相同:
//:string 'func' (length=4)
//:array (size=3)
  0 => string 'a' (length=1)
  1 => string 'b' (length=1)
  2 => 
    array (size=3)
      0 => int 1
      1 => int 2
      2 => int 3
<?php

class test
{
    private $value;
    function __construct($value)
    {
        $this->value = $value;
    }

    function __call($function, $args)
    {
        $this->value = call_user_func($function, $this->value, $args[0]);
        return $this;
    }

    function strlen()
    {
        return strlen($this->value);
    }

}

$str = new test(" ab AB 0 ");
echo $str->trim(' ')->strlen();							//7

__invoke

当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。

  • 本特性只在 PHP 5.3.0 及以上版本有效。
<?php

class test
{
    function __invoke()
    {
        var_dump(func_get_args());		    //array (size=1)  0 => string 'a' (length=1)
        echo '这可是一个对象哦';			//这可是一个对象哦
    }
}

$test = new test();
$test('a');

__clone

如果想复制一个对象则需要使用clone方法,在调用此方法是对象会自动调用__clone魔术方法,

  • 如果在对象复制需要执行某些初始化操作,可以在__clone方法实现。
  • 如果禁止克隆可以,私有化__clone方法。
<?php

class test
{
    public $ID ;
  
    function setID($num)
    {
        $this->ID = $num;
    }

    function getID()
    {
        return $this->ID;
    }
  
    public function __clone()
    {
        $this->status=1;
    }
}

$test1 = new test();
$test11->setID("12345");
echo $test1->status, "<br />";							//0
$test2 = clone $test1;
echo $test2->status, "<br />";							//1
$test2->setID("67890");


echo "drone1 ID: " . $test1->getID() . "<br />";			//drone1 ID: 12345
echo "drone2 ID: " . $test2->getID() . "<br />";			//drone2 ID: 67890
echo "drone1 ID: " . $test1->getID() . "<br />";			//drone1 ID: 12345

__toString

在将一个对象转化成字符串时自动调用,比如使用echo打印对象时。

  • PHP 5.2.0之前,__toString方法只有结合使用echo() 或 print()时 才能生效。PHP 5.2.0之后,则可以在任何字符串环境生效(例如通过printf(),使用%s修饰符)
  • 从PHP 5.2.0,如果将一个未定义__toString方法的对象 转换为字符串,会报出一个E_RECOVERABLE_ERROR错误。
<?php

class test
{
    public function __toString()
    {
        return "对象不能输出哦";
    }
}

$test = new test;
echo $test;						//对象不能输出哦

__debugInfo

打印所需调试信息,var_dump()打印对象,print_r()打印__debugInfo()内容。

  • 该方法在PHP 5.6.0及其以上版本才可以用,
<?php
  
class test
{
    private $prop;

    public function __construct($val)
    {
        $this->prop = $val;
    }

    public function __debugInfo()
    {
        $this->prop = 100;
        return [
            'propSquared' => $this->prop**2,
        ];
    }
}

var_dump(new test(6));						/*object(C)[1]
  										  		private 'prop' => int 6     */
print_r(new test(6));						//C Object ( [propSquared] => 10000 )
Licensed under 京ICP备17003353号-3