魔术方法的触发条件
魔术方法 | 参数 | 触发条件 | 返回值 |
---|---|---|---|
__construct() | 无 | 称为构造函数,在实例化一个对象的时候,首先会自动执行这个方法 | |
__destruct() | 无 | 称为析构函数,在对象的所有引用被删除或者当对象被显示销毁时执行的魔术方法,反序列化时也是对象,所有最后也会被销毁触发 | |
__sleep() | 在serialize()序列化之前 | ||
__wakeup() | 无 | 反序列化unserialize()之前 | |
__toString() | 无 | 把对象当成字符串来调用,例如echo,die则会触发,而printf_r和var_dump不会触发 | |
__invoke() | 无 | 把对象当成函数来调用会触发 | |
__call() | $arg1,$arg2 | 调用一个不存在的方法时会触发,$agr1 不存在方法的名称,$arg2 不存在方法的参数 | 调用的不存在方法的名称和参数 |
__callStatic() | $arg1,$arg2 | 静态调用或调用成员常量时使用的方法不存在时触发 | 调用的不存在方法的名称和参数 |
__get() | $arg1 | 调用的成员属性不存在时触发 | 不存在的成员属性的名称 |
__set() | $arg1,$arg2 | 给不存在的成员属性赋值时触发 | 不存在的成员属性的名称和赋的值 |
__isset() | $arg1 | 对不可访问属性使用isset() 或empty() 时,isset() 会被触发 | 不存在的成员属性的名称 |
__unset() | $arg1 | 对不可访问属性使用unset() 时会触发 | 不存在的成员属性和名称 |
__cloe() | 无 | 当使用clone关键词拷贝完成一个对象后,新对象会自动调用定义的魔术方法__clone() |
魔术方法的使用案例
__construct()
触发条件:在实例化一个对象的时候,首先会自动执行这个方法
<?php
highlight_file(__FILE__);
class User {
public $username;
public function __construct($username) {
$this->username = $username;
echo "触发了构造函数1次" ;
}
}
$test = new User("benben");
$ser = serialize($test);
unserialize($ser);
?>
真正运行触发__construct
魔术方法的是$test = new User("benben");
运行结果:触发了构造函数1次
__destruct()
触发条件:在对象的所有引用被删除或者当对象被显示销毁时执行的魔术方法,反序列化时是将字符串转换成对象的过程,所有最后也会被销毁触发
<?php
highlight_file(__FILE__);
class User {
public function __destruct()
{
echo "触发了析构函数1次"."<br />" ;
}
}
$test = new User("benben");
$ser = serialize($test);
unserialize($ser);
?>
触发了两次__destruct()
魔术方法,也就是说在new一个对象最终被销毁会触发一次,然后unserialize
反序列化成对象的过程,最终销毁也触发了一次
运行结果:
触发了析构函数1次
触发了析构函数1次
__sleep()
触发条件:在serialize()序列化之前
<?php
highlight_file(__FILE__);
class User {
const SITE = 'uusama';
public $username;
public $nickname;
private $password;
public function __construct($username, $nickname, $password) {
$this->username = $username;
$this->nickname = $nickname;
$this->password = $password;
}
public function __sleep() {
return array('username', 'nickname');
}
}
$user = new User('a', 'b', 'c');
echo serialize($user);
?>
new一个对象先触发__construct()
,然后serialize()
触发了__sleep()
,最后返回一个数组给$uer
,内容只有username和nickname;
结果:O:4:"User":2:{s:8:"username";s:1:"a";s:8:"nickname";s:1:"b";}
__wakeup()
触发条件:在unserialize()
反序列化之前[/font]
<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
const SITE = 'uusama';
public $username;
public $nickname;
private $password;
private $order;
public function __wakeup() {
$this->password = $this->username;
}
}
$user_ser = 'O:4:"User":2:{s:8:"username";s:1:"a";s:8:"nickname";s:1:"b";}';
var_dump(unserialize($user_ser));
?>
unserialize()
触发了__wakeup()
,因此username的值赋给了password
结果:object(User)#1 (4) { ["username"]=> string(1) "a" ["nickname"]=> string(1) "b" ["password":"User":private]=> string(1) "a" ["order":"User":private]=> NULL }
__toString()
触发条件:把对象当成字符串来调用,例如echo,die则会触发,而printf_r和var_dump不会触发
<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
var $benben = "this is test!!";
public function __toString()
{
return '格式不对,输出不了!';
}
}
$test = new User() ;
print_r($test);
echo "<br />";
echo $test;
?>
echo $test
则把对象当做字符串输出了,因此调用了__toString()
方法,
当使用die($test)
也会触发这个魔术方法
结果:
User Object ( [benben] => this is test!! )
格式不对,输出不了!
__invoke()
触发条件:把对象当成函数来调用会触发
<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
var $benben = "this is test!!";
public function __invoke()
{
echo '它不是个函数!';
}
}
$test = new User() ;
echo $test ->benben;
echo "<br />";
echo $test() ->benben;
?>
把$test
这个对象当做函数运行了,则会执行 __invoke()
结果:this is test!! 它不是个函数!
__call()
触发条件:调用一个不存在的方法时会触发,$agr1
不存在方法的名称,$arg2
不存在方法的参数
返回值:调用的不存在方法的名称和参数
<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
public function __call($arg1,$arg2)
{
echo "$arg1,$arg2[0]";
}
}
$test = new User() ;
$test -> callxxx('a');
?>
callxxx()
这个方法不存在,则会调用魔术方法__call()
,返回了callxxx,a
结果:callxxx,a
__callStatic()
触发条件:静态调用或调用成员常量时使用的方法不存在时触发
返回值:调用的不存在方法的名称和参数
<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
public function __callStatic($arg1,$arg2)
{
echo "$arg1,$arg2[0]";
}
}
$test = new User() ;
$test::callxxx('a');
?>
$test::callxxx('a');
中的::
则是静态调用的方法,callxxx()
方法不存在,同时在php中也会警告提醒
Warning: The magic method __callStatic() must have public visibility and be static in /var/www/html/class10/2.php on line 5
结果:callxxx,a
$arg1
是不存在的方法,$arg2
是不存在方法中的参数
__get()
触发条件:调用的成员属性不存在时触发
返回值:不存在的成员属性的名称
<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
public $var1;
public function __get($arg1)
{
echo $arg1;
}
}
$test = new User() ;
$test ->var2;
?>
var2
成员变量不存在,则调用__get()
方法,并返回不存在的成员变量名称
结果:var2
__set()
触发条件:给不存在的成员属性赋值时触发
返回值:不存在的成员属性的名称和赋的值
<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
public $var1;
public function __set($arg1 ,$arg2)
{
echo $arg1.','.$arg2;
}
}
$test = new User() ;
$test ->var2=1;
?>
触发过程同上,返回的是var2是不存在变量名; 给不存在变量赋的值1
结果:var2,1
__isset()
触发条件:对不可访问属性使用isset()
或empty()
时,isset()
会被触发
返回值:不存在的成员属性的名称
<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
private $var;
public function __isset($arg1 )
{
echo $arg1;
}
}
$test = new User() ;
isset($test->var);
?>
使用isset()
方法对不可访问属性$var
进行访问,触发了此魔术方法,并返回了var
结果:var
__unset()
触发条件:对不可访问属性使用unset()
时会触发
返回值:不存在的成员属性和名称
<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
private $var;
public function __unset($arg1 )
{
echo $arg1;
}
}
$test = new User() ;
unset($test->var);
?>
过程同上
结果:var
__clone()
触发条件:当使用clone关键词拷贝完成一个对象后,新对象会自动调用定义的魔术方法__clone()
<?php
highlight_file(__FILE__);
error_reporting(0);
class User {
private $var;
public function __clone( )
{
echo "__clone test";
}
}
$test = new User() ;
$newclass = clone($test)
?>
拷贝了$test
这个对象,触发了__clone()
结果:__clone test
6 条评论
(´இ皿இ`)
૮ ºﻌºა站岗
OωO
666666
a
6