PHP常用魔术方法
一、魔术方法
// 类
class A
{
// 类属性
protected static $A_property;
// 实例属性
protected $a_property;
// 类方法
public static function A_action(){}
// 实例方法
public function a_action(){}
}
// 类实例
new A()
// 调用静态属性
A::$A_property
// 调用类实例属性
(new A())->property
// 调用静态方法
A::A_action()
// 调用类实例方法
(new A())->a_action()
请明白以下针对什么的,是实例属性或实例方法?
1. __contruct()
创建实例的时候调用此方法
1. new class_name
2. __destroct()
销毁实例的时候调用此方法
1. unset( new class_name )
2. 脚本结束
3. __set()
对一个未定义或者无权限的实例属性赋值时调用此实例方法
1. (new class_name)->action = 2
4. __get()
当调用一个未定义或者无权限的实例属性时访问此实例方法
1. echo (new class_name)->action
5. __isset()
当在 一个未定义或无权限的实例属性上调用isset()函数时调用此实例方法
1. isset( (new class_name)->not_exist_property )
6. __unset()
当在一个未定义或无权限的实例属性上调用unset()函数时调用此实例方法
1. unset( (new class_name)->not_exist_property )
7. __toString()
打印对象时,调用此实例方法
1. echo (new class_name())
8. ___clone()
复制对象时,调用此实例方法
注意,有人会想到会不会像变量赋值那样会进行深拷贝,所以才有此方法
1. clone (new class_name())
9. __call()
调用一个未定义或者无权限的实例方法时访问此实例方法
注意,这里是实例方法不是实例属性
1. (new class_name())->not_exist_action()
10. __callStatic()
调用一个未定义或者无权限的类方法时访问此实例方法
注意,这里是类方法
1. class_name::not_exist_action()
11.__invoke()
可以让实例像函数那样调用
1. (new class_name)($var)
12.__sleep()
可以用来打包对象,定制对象的熟悉
简单的说,对 对象使用serialize函数调用此方法
注意,必须要有 return 返回数组 用于定制对象属性
1. serialize(new class_name())
13.__wakeup()
当用unserialize解压 serialize打包的对象时调用此方法
1. unserialize()
14.__debugInfo()
var_dump打印对象时,调用此实例方法
1. var_dump( new class_name() )
15.__autoload()
自动加载调用此方法,自我感觉属于鸡肋,因为现在已经有自动加载机制,没必要去写
二、code
class A
{
public $public='public';
private $private = 'private';
protected $protected = 'protected';
public function __construct()
{
echo 'enter __construct($name)'.PHP_EOL;
}
public function __destruct()
{
echo 'enter __destruct($name)'.PHP_EOL;
}
public function __get($name)
{
echo 'enter __get($name)'.PHP_EOL;
echo '参数$name='.$name.PHP_EOL;
}
public function __set($name, $value)
{
echo 'enter __set($name, $value)'.PHP_EOL;
echo '参数$name='.$name.', $value='.$value.PHP_EOL;
}
public function __isset($name)
{
echo 'enter __isset($name)'.PHP_EOL;
echo '参数$name='.$name.PHP_EOL;
}
public function __unset($name)
{
echo 'enter __unset($name)'.PHP_EOL;
echo '参数$name='.$name.PHP_EOL;
}
public function __clone()
{
echo 'enter __clone($name)'.PHP_EOL;
}
public function __toString()
{
echo 'enter __toString($name)'.PHP_EOL;
return '类名为'.__CLASS__.'的对象'.PHP_EOL;
}
public function __call($name, $arguments)
{
echo 'enter __call($name)'.PHP_EOL;
echo '参数$name='.$name.', $arguments=';
print_r($arguments).PHP_EOL;
}
public static function __callStatic($name, $arguments)
{
echo 'enter __callStatic($name)'.PHP_EOL;
echo '参数$name='.$name.', $arguments=';
print_r($arguments).PHP_EOL;
}
public function __invoke($args)
{
echo 'enter __invoke($name)'.PHP_EOL;
echo '参数$name='.$args.PHP_EOL;
}
public function __sleep()
{
echo 'enter __sleep($name)'.PHP_EOL;
return ['public', 'protected', 'private'];
}
public function __wakeup()
{
echo 'enter __wakeup($name)'.PHP_EOL;
}
public function __debugInfo()
{
echo 'enter __debugInfo($name)'.PHP_EOL;
}
public function info(){
echo '测试解序列化'.$this->public, $this->private, $this->protected.PHP_EOL;
}
}
// __construct 创建对象时调用
$a = new A();
// __get($name) 当调用一个未定义或者无权限的实例属性时访问此实例方法
$a->gg.PHP_EOL;
// __set($name, $value) 对一个未定义或者无权限的实例属性赋值时调用此实例方法
$a->cc=2222;
// __isset($name) 当在一个未定义或无权限的实例属性上调用isset()函数时调用此实例方法
isset($a->aa);
// __unset($name) 当在一个未定义或无权限的实例属性上调用unset()函数时调用此实例方法
unset($a->aa);
// __clone() 使用clone值拷贝对象时,调用此实例方法
$b = clone $a;
// __toString 打印对象时,调用此实例方法
echo $b;
// __call 调用未定义或者无权限实例方法调用此实例方法
$a->get('test');
// __callStatic 调用未定义的静态方法
A::get('test');
// __invoke 是用函数式的调用实例对象,调用此实例方法
$a(5);
// __sleep 要序列化对象之前,调用此实例方法,可使用return用于筛选属性是否序列化
$tmp = serialize($a);
// __wakeup 解序列化之前,调用此实例方法
$tmp = unserialize($tmp);
$tmp->info();
// __debugInfo var_dump打印对象时,调用此实例方法
var_dump($a);
// 脚本结束,对象销毁的时候调用__destruct($name)
/* result:
enter __construct($name)
enter __get($name)
参数$name=gg
enter __set($name, $value)
参数$name=cc, $value=2222
enter __isset($name)
参数$name=aa
enter __unset($name)
参数$name=aa
enter __clone($name)
enter __toString($name)
类名为A的对象
enter __call($name)
参数$name=get, $arguments=Array
(
[0] => test
)
enter __callStatic($name)
参数$name=get, $arguments=Array
(
[0] => test
)
enter __invoke($name)
参数$name=5
enter __sleep($name)
enter __wakeup($name)
测试解序列化publicprivateprotected
enter __debugInfo($name)
object(A)#1 (0) {
}
enter __destruct($name)
enter __destruct($name)
enter __destruct($name)
*/