如何防止调用不存在的方法而出错,这里介绍一下使用__call魔术重载方法的使用,通过该方法,我们可以动态的创建一些特殊用途的方法。
__call方法原型如下:
mixed __call(string $name,array $arguments)
当调用一个不可访问的方法(如未定义,或者不可见时), __call()就会被调用。
其中$name参数是要调用的方法名称.$arguments参数是一个数组,包含者要传递给方法的参数。
如下所示:
<?php class HandsonBoy { public function __call($name, $arguments) { switch (count($arguments)) { case 2: echo $arguments[0] * $arguments[1], PHP_EOL; break; case 3: echo array_sum($arguments), PHP_EOL; break; default: echo '参数不对', PHP_EOL; break; } } } $a = new HandsonBoy(); $a->make(5, 6);//结果输出:30
以上代码模拟了类似其他语言中的根据参数类型进行重载,跟__call配套的魔方方法是__callStatic 。
当然,使用魔术方法"防止调用不存在的方法面报错",并不是魔术方法的本质。实际上,魔术方法使得方法的动态创建变为可能。
这在MVC等框架设计中是很有用的语法,假设一个控制器调用了不存在的方法,那么只要定义了__call魔术方法,就能很友好地处理这种情况。
以下代码通过使用_callStatic这一魔术方法进行方法的动态创建和延迟绑定,实现一个简单的ORM模型:
<?php abstract class ActiveRecord { protected static $table; public $select; static function __callStatic($method, $args) { $field = preg_replace('/^findBy(\w*)$/', '$1', $method); $query = "SELECT * FROM " . static::$table . " WHERE " .self::uncamelize($field) . "='$args[0]'"; return self::createDomain($query); } private static function createDomain($query) { $class = get_called_class(); $domain = new $class(); $domain->select = $query; return $domain; } private static function uncamelize($camelCaps, $separator = '_') { return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $separator . "$2", $camelCaps)); } } class User extends ActiveRecord { protected static $table = 'user'; } echo '<pre>'; print_r(User::findByUserName('phpernote')->select); //输出:SELECT * FROM user WHERE user_name='phpernote'