PHP 魔法方法之__call和__callStatic

来源:互联网 发布:vb程序代码 编辑:程序博客网 时间:2024/06/10 08:58

__call和__callStatic方法

__call和__callStatic方法都可用于防止调用不存在的方法而出现报错,但也能用于方法的动态创建,这在MVC等框架设计中是很有用的语法。


__call方法原型如下:

mixed __call( string $name , array $arguments )

当调用一个不可访问的方法(如未定义,或者不可见)时,__call() 会被调用。其中$name 参数是要调用的方法名称。$arguments 参数是一个数组,包括着要传递给方法的参数。如下所示:

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->make(5);$a->make(5,6);

__callStatic方法用法和 __call一样,但它用于静态方法中。下面这段代码通过使用__callStatic 进行方法的动态创建和延迟绑定,实现一个简单的ORM模型。

<?phpabstract class ActiveRecord{    protected static $table;    protected $fieldvalues;    public $select;    static function findById($id){        $query = "select * from "            .static::$table            ." where id=$id";        return self::createDomain($query);    }    function __get($fieldname){        return $this->fieldvalues[$fieldname];    }    static function __callStatic($method, $args){        $field = preg_replace('/^findBy(\w*)$/','${1}',$method);        $query = "select * from "            .static::$table            ." where $field='$args[0]'";        return self::createDomain($query);    }    private static function createDomain($query){        $klass = get_called_class();        $domain = new $klass();        $domain ->fieldvalues = array();        $domain ->select = $query;        foreach($klass::$fields as $field => $type){            $domain ->fieldvalues[$field] = 'TODO: set from sql result';        }        return $domain;    }}class Customer extends ActiveRecord{    protected static $table = 'custdb';    protected static $fields = array(        'id' => 'int',        'email' => 'varchar',        'lastname' => 'varchar'        );}class Sales extends ActiveRecord{    protected static $table = 'salesdb';    protected static $fields = array(        'id' => 'int',        'item' => 'varchar',        'qty' => 'int'        );}assert("select * from custdb where id=123" ==    Customer::findById(123) ->select);assert("TODO: set from sql result" ==    Customer::findById(123) ->email);assert("select * from salesdb where id=321" ==    Sales::findById(321) ->select);assert("select * from custdb where Lastname='Denoncourt'" ==    Customer::findByLastname('Denoncourt') ->select);

参考资料:
《PHP核心技术与最佳实践》


0 0
原创粉丝点击