【问题标题】:How do I create a dynamic method in PHP?如何在 PHP 中创建动态方法?
【发布时间】:2010-03-29 14:26:42
【问题描述】:
我正在尝试使用一些动态方法扩展我的 ActiveRecord 类。我希望能够从我的控制器运行它
$user = User::find_by_username(param);
$user = User::find_by_email(param);
我读过一些关于重载的文章,并认为这是关键。我的 AR 类中有一个 static $_attributes,在这种情况下,我通过复数我的模型(用户 = 用户)来获得表名。
我该怎么做?所有模型都扩展了 ActiveRecord 类。
【问题讨论】:
标签:
php
activerecord
overloading
【解决方案1】:
你必须使用__callStatic() magic method,它作为 PHP5.3 提供
public static function __callStatic($name, $arguments) {
/*
Use strpos to see if $name begins with 'find_by'
If so, use strstr to get everything after 'find_by_'
call_user_func_array to regular find method with found part and $arguments
return result
*/
}
【解决方案2】:
这也可能有用,它更复杂,但它允许真正的动态函数访问成员变量。
class DynamicFunction {
var $functionPointer;
var $mv = "The Member Variable";
function __construct() {
$this->functionPointer = function($arg) {
return sprintf("I am the default closure, argument is %s\n", $arg);
};
}
function changeFunction($functionSource) {
$functionSource = str_replace('$this', '$_this', $functionSource);
$_this = clone $this;
$f = '$this->functionPointer = function($arg) use ($_this) {' . PHP_EOL;
$f.= $functionSource . PHP_EOL . "};";
eval($f);
}
function __call($method, $args) {
if ( $this->{$method} instanceof Closure ) {
return call_user_func_array($this->{$method},$args);
} else {
throw new Exception("Invalid Function");
}
}
}
if (!empty($argc) && !strcmp(basename($argv[0]), basename(__FILE__))) {
$dfstring1 = 'return sprintf("I am dynamic function 1, argument is %s, member variables is %s\n", $arg, $this->mv);';
$dfstring2 = 'return sprintf("I am dynamic function 2, argument is %s, member variables is %s\n", $arg, $this->mv);';
$df = new DynamicFunction();
$df->changeFunction($dfstring1);
echo $df->functionPointer("Rabbit");
$df->changeFunction($dfstring2);
$df->mv = "A different var";
echo $df->functionPointer("Cow");
};