本文测试环境为 php5.5.12
一、__get 、__set
将对象的属性进行接管。
一般来说,总是把类的属性定义为private,但是对属性的读取和赋值操作非常频繁,在php5+,预定义__set() 和__get()来获取和赋值其属性。即私有成员的设置和取值操作。
这两个方法需要手动添加到类中。如下:
public function __set($name,$value){ $this->name=$value; } public function __get($name){ return $this->name; }
注意:网上目前有一些文章列举出这两个方法可以设置成private和static,本人在此表示,不要相信,因为在老版本的php中这么使用不会有什么问题,但是在新版本中,会提示warning错误,提示“Warning:The magic method __get() must have public visibility and cannot be static in......”
完整示例如下:
<?php namespace Libs; class Person { public $name; public $age; public $gender; public function __set($property_name,$val) { echo "您调用了魔术方法__set,对私有属性{$property_name}进行了赋值{$val}的操作<br/>"; $this->$property_name = $val; } public function __get($property_name) { echo "您调用了魔术方法__get,取到了私有属性{$property_name}的值<br/>"; return $this->$property_name; } }
调用:
$p = new Person(); $p->name = "Jason"; $p->gender = "man"; $p->age=21; echo $p->name;
推荐阅读: php __set __get __isset __unset用法防被忽悠分析
二、__call 、__callStatic
用来控制php对象的方法/静态方法调用.
为了避免当调用的方法不存在时产生错误,可以使用__call()方法来避免,该方法在调用的方法不存在时会自动调用,程序仍然会继续执行下去。
示例如下使用
<?php namespace Libs; class Person { public function __call($function_name,$args) { echo "您调用了不存在的方法$function_name<br/>"; echo "传递的参数是:"; var_dump($args); } } $p = new Person(); $p->getCountry("Json","21","1");
输出结果:
您调用了不存在的方法getCountry 传递的参数是: array (size=3) 0 => string 'Json' (length=4) 1 => string '21' (length=2) 2 => string '1' (length=1)
当调用一个类的不存在的静态方法时,我们不使用__call() 而是使用__callStatic()
这里有一个需要注意的地方,__callStatic的属性必须为public+static
示例如下:
<?php namespace Libs; class Person { public static function __callstatic($function_name,$args) { echo "您调用了不存在的静态方法$function_name<br/>"; echo "传递的参数是:"; var_dump($args); } } $p = new Person(); $p::getCountry("Json","21","1");
输出为:
您调用了不存在的静态方法getCountry 传递的参数是: array (size=3) 0 => string 'Json' (length=4) 1 => string '21' (length=2) 2 => string '1' (length=1)
推荐阅读:PHP魔术方法之__call与__callStatic方法
三、__toString
将php对象转换为字符串。
当我们调试程序时,如果想用echo 打印一个对象,在没有定义__toString()是会报错的。
例如下面的代码:
<?php namespace Libs; class Person { public function test() { } } $p = new Person(); echo $p;
报错如下
( ! ) Catchable fatal error: Object of class LibsPerson could not be converted to string in ...... | ||||
---|---|---|---|---|
Call Stack | ||||
# | Time | Memory | Function | Location |
1 | 0.0009 | 244264 | {main}( ) | ..2.php:0 |
如果类定义了__toString()方法,就能在测试时,echo打印对象体,对象会自动调用他所属类定义的toString方法,格式化输出这个对象所包含的数据。
示例如下
<?php namespace Libs; class Person { private $name; public function __construct() { $this->name="Hello World!"; } public function __toString() { return __CLASS__."'s property name is ".$this->name; } } $p = new Person(); echo $p;
打印输出
LibsPerson's property name is Hello World!
推荐阅读:php面向对象之__toString()
四、__invoke
将php对象当成函数。
官网给出的定义:
mixed __invoke([$...])
当尝试以调用函数的方式调用一个对象时,__invoke()方法会被自动调用。
Note:本特性只在PHP5.3.0及以上版本有效。
代码如下
<?php class CallableClass { function __invoke($x) { var_dump($x); } } $obj = new CallableClass; $obj(5); var_dump(is_callable($obj)); ?>
输出结果
int(5) bool(true)