//魔术方法都是有触发条件的
__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo() 等方法在 PHP 中被称为"魔术方法"(Magic methods)。
//构造函数 __construct()
public function __construct($data)
{
$this->a=5000;
echo $data;
// $a = 'sss';
// echo $a;
}
//析构函数 结束时候执行__destruct()
public function __destruct()
{
echo 'sss';
}
}
//给一个不能访问或者是不存在的属性赋值
public function __set($name,$value)
{
//echo $name,$value;
$this->$name=$value;
//echo '<hr>';
}
//获取一个不存在或者不能访问的属性
public function __get($name)
{
//echo $name;
return $this->father;
}
<?php
class MethodTest
{
public function __call($name, $arguments)
{
// 注意: $name 的值区分大小写
// 在对象中调用一个不可访问方法时,__call() 会被调用。
var_dump($arguments);
echo "Calling object method '$name' "
. implode(', ', $arguments). "\n";
}
/** PHP 5.3.0之后版本 */
public static function __callStatic($name, $arguments)
{
//用静态方式中调用一个不可访问方法时,__callStatic() 会被调用。
// 注意: $name 的值区分大小写
echo "Calling static method '$name' "
. implode(', ', $arguments). "\n";
}
}
$obj = new MethodTest;
$obj->runTest('in object context');
echo '<hr>';
MethodTest::runTest('in static context'); // PHP 5.3.0之后版本
?>
<?php
class PropertyTest {
/** 被重载的数据保存在此 */
private $data = array();
/** 重载不能被用在已经定义的属性 */
public $declared = 1;
/** 只有从类外部访问这个属性时,重载才会发生 */
private $hidden = 2;
public function __set($name, $value)
{
echo "Setting '$name' to '$value'";
echo "<hr>";
$this->data[$name] = $value;
}
public function __get($name)
{
echo "Getting '$name'";
echo "<hr>";
}
//当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。
public function __isset($name)
{
echo "Is '$name' set?";
echo "<hr>";
return isset($this->data[$name]);
}
//当对不可访问属性调用 unset() 时,__unset() 会被调用
public function __unset($name)
{
echo "Unsetting '$name'";
echo "<hr>";
unset($this->data[$name]);
}
}
$obj = new PropertyTest;
$obj->a = 1;
echo $obj->a;
var_dump(isset($obj->a));
echo "<hr>";
unset($obj->a);
var_dump(isset($obj->a));
?>
__construct PHP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。
__destruct PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,如 C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。
在对象中调用一个不可访问方法时,__call() 会被调用。
用静态方式中调用一个不可访问方法时,__callStatic() 会被调用。
在给不可访问属性赋值时,__set() 会被调用。
读取不可访问属性的值时,__get() 会被调用。
当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。
当对不可访问属性调用 unset() 时,__unset() 会被调用。
serialize() 函数会检查类中是否存在一个魔术方法 __sleep()。如果存在,该方***先被调用,然后才执行序列化操作。此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。如果该方法未返回任何内容,则 NULL 被序列化,并产生一个 E_NOTICE 级别的错误。
与之相反,unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源。
__wakeup() 经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。
__toString() 方法用于一个类被当成字符串时应怎样回应。例如 echo $obj; 应该显示些什么。此方法必须返回一个字符串,否则将发出一条 E_RECOVERABLE_ERROR 级别的致命错误。
当尝试以调用函数的方式调用一个对象时,__invoke() 方***被自动调用。
自 PHP 5.1.0 起当调用 var_export() 导出类时,此静态 方***被调用。 本方法的唯一参数是一个数组,其中包含按 array('property' => value, ...) 格式排列的类属性。
对象复制可以通过 clone 关键字来完成(如果可能,这将调用对象的 __clone() 方法)。对象中的 __clone() 方法不能被直接调用。
$copy_of_object = clone $object;
当对象被复制后,PHP 5 会对对象的所有属性执行一个浅复制(shallow copy)。所有的引用属性 仍然会是一个指向原来的变量的引用。
This method is called by var_dump() when dumping an object to get the properties that should be shown. If the method isn't defined on an object, then all public, protected and private properties will be shown.
This feature was added in PHP 5.6.0.
Example #5 Using __debugInfo()