如何防止调用不存在的方法而出错,这里介绍一下使用__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('feishuai')->select);
//输出:SELECT * FROM user WHERE user_name='feishuai'