从外部文件动态加载函数到类中

时间:2009-04-08 06:17:22

标签: php class

是否可以在php中加载一个函数,比如从外部文件中加入一个类。 我正在尝试为辅助函数创建一个加载器,以便我可以调用:

$registry->helper->load('external_helper_function_file');

之后它应该能够像这样调用文件中的函数:

$registry->helper->function();

感谢您的帮助

3 个答案:

答案 0 :(得分:7)

撇开意见,这是一个很好的OOP设计。即使使用PHP的当前版本,它也是可能的,尽管不像PHP5.3那样干净。

class Helper {
    /* ... */
    function load($file) {
      include_once($file);
    }
    function __call($functionName, $args) {
       if(function_exists($functionName))  
         return call_user_func_array($functionName, $args);
    }

}

答案 1 :(得分:2)

好的,1,我同意这是不礼貌的行为。另外,在5.3中,您可以使用带有__call魔术字的新闭包语法将运算符用作函数(JS样式)。

现在,如果我们想提供一种方法,我可以考虑使用create_fnuction,与__call魔法混合使用。

基本上,你使用正则表达式模式将函数转换为兼容的字符串,并将minmin作为私有成员。而不是使用__call方法来获取它们。我正在做一个小型演示。

好的,这是班级。我从几周前看到的类中获得灵感,该类使用闭包来实现JS风格的对象:

/**
 * supplies an interface with which you can load external functions into an existing object
 * 
 * the functions supplied to this class will recive the classes referance as a first argument, and as 
 * a second argument they will recive an array of supplied arguments.
 * 
 * @author arieh glazer <arieh.glazer@gmail.com>
 * @license MIT like 
 */
class Function_Loader{
    /**
     * @param array holder of genarated functions
     * @access protected
     */
    protected $_funcs = array();

    /**
     * loads functions for an external file into the object
     * 
     * a note- the file must not contain php tags.
     * 
     * @param string $source a file's loaction
     * 
     * @access public
     */
    public function load($source){
        $ptrn = '/function[\s]+([a-zA-Z0-9_-]*)[\s]*\((.*)\)[\s]*{([\w\s\D]+)}[\s]*/iU';
        $source = file_get_contents($source);
        preg_match_all($ptrn,$source,$matches);
        $names = $matches[1];
        $vars = $matches[2];
        $funcs = $matches[3];
        for ($i=0,$l=count($names);$i<$l;$i++){
            $this->_funcs[$names[$i]] = create_function($vars[$i],$funcs[$i]);
        }
    }

    public function __call($name,$args){
        if (isset($this->_funcs[$name])) $this->_funcs[$name]($this,$args);
        else throw new Exception("No Such Method $name");
    }
}

限制 - 第1,源不能有任何php标签。 2,功能永远是公开的。 3 - 我们只能模仿$ this。我所做的是作为第一个参数传递$ this,第二个是参数数组(这是第四个限制)。此外,您将无法从班级内访问非公开成员和方法。 源文件的示例:

function a($self,$arr=array()){
    //assuming the object has a member called str
    echo $self->str;
}

对我来说这是一个有趣的练习,但总的来说是一个不好的练习

答案 2 :(得分:0)

所以你不仅要include一个文件,而且要include它进入一个对象的范围?

...

我认为你这是错误的做法。如果registry对象具有一系列具有自己的函数的辅助成员,则更有意义。最终结果可能如下所示:

$registry->aHelper->aFunction();
$registry->aDifferentHelper->aDifferentFunction();

仔细使用{}语法,您应该能够动态地将成员对象添加到上帝对象。

此时值得注意的是god object几乎不变anti-pattern。如果您需要全局这些函数,请使用bootstrapping include技术,然后将其置于全局范围内。如果你需要传递那些数据,那么要么根据需要将它传递给函数,要么将它存储在数据库中并在其他地方检索它。

我知道上帝对象真的看起来是个好主意,但我保证你以后会弄得一团糟。