将函数代码动态加载到类中

时间:2014-02-07 22:49:38

标签: php

我正在尝试编写可以动态加载外部函数代码的类代码 用作类的方法。我明白我可以使用扩展和创建 儿童对象,但似乎有一种更简单的方法可以解决这个问题。

关键是要限制必需的代码量 用于执行特定功能。并将所有功能代码保存在单独的文件中 这可能是必需的。

class _DEMO
{
    public  $_addOn = '';
    public function __construct()
    {
        require_once('DEMOAdd.php');
        $this->addOn = addOn;
    }
}

DEMOAdd.php

function addOn($_input)
{
    return 'getting '.$_input;
}

如何将其加载到_DEMO类中?以上产生致命错误。

print $_test->addOn('something');

在JavaScript中,可以为变量分配函数。我意识到这一点 不是JavaScript,但我怀疑PHP中有类似的功能。

我也知道PHP中的变量变量,但是我无法围绕这个概念进行思考。

回应这个建议

当另一位开发人员查看您的代码时,不清楚此类的特定角色是什么。相反,他必须检查类中引用的许多文件和外部函数。如果他能看一下班级并且看到“哦,那个班级做到这一点,那就更好”。这甚至是面向对象编程的核心方面。

我同意你的看法。我正在开发一个项目,我是所有东西的唯一开发者,html,javascript,css, 和PHP。我最近一直在使用类定义,但过去编写过很多过程代码。目前 project的代码被分成几个类def文件,因此代码可以在不同的上下文中重用。我的 考虑的是,如果来自网页的查询只需要500行代码,为什么要加载1500行代码来服务 请求。此外,这是一个cms系统,用户数量非常有限(目前只有我),所以音量 交通不是问题。但是如果用户负载较大,则每个用户需要额外的代码,因此需要额外的代码 服务器内存需求显着增加。 cms web界面用于管理直接修改代码的内容 会非常困难。是的,我正在重新发明轮子。 Firestone,General,Nokian等等也是如此。

谢谢大家的答案

我想我的答案可以分配给变量的匿名函数,重新设置php手册

$_var = function($_input)
                {
                 return "getting ".$_input;
                }
print $_var('something'); // I have to look back at the manual to varify this line's syntax... yep it looks good.

3 个答案:

答案 0 :(得分:0)

使用继承。您可以像这样扩展_DEMO类:

 class _DEMO_ADD extends _DEMO {
   ...
   function addOn(....) {
        ...
   }

请参阅docs on extends

答案 1 :(得分:0)

正确设计应用程序

首先。您尝试做的事情违反了清洁面向对象设计的基本方面。为什么即使使用类只是为了调用外部函数?如果你想继续坚持功能编程。

The point is to limit to bare essentials the amount of code that has to be used to perform a particular function. And keep all the function code in separate files that can be required.

良好设计的尝试不仅(仅)您编写的代码量,而是如何实现某项任务。如果一个班级适合解决你的问题,那就使用一个班级。

当另一位开发人员查看您的代码时,不清楚此类的特定角色是什么。相反,他必须检查类中引用的许多文件和外部函数。如果他能看一下班级并且看到“哦,那个班级做到这一点,那就更好”。 这甚至是面向对象编程的核心方面

好。足够的话题。既然你特别提出这个问题,我会就此提出一些建议尽管我不推荐它,并建议重新考虑你的设计


动态方法调用

要调用已在其他地方定义的函数,我们将使用魔术方法__call($methodname, $args)。每当您尝试访问不存在的类方法时,都会调用此方法。

在这个__call()方法中,我们将检查是否存在具有该方法名称的函数,我们试图调用。如果不是,我们可以抛出异常,否则我们将使用call_user_func_array()执行该函数。

<强>的functions.php

<?php

function addOn($input){
    echo "This function is procedural and takes the param: " . $input;
}

<强> MyClass.php

<?php

class MyClass{

    // This will get called whenever a method on this class
    // is called that does not exist
    public function __call($name, $args)
    {
        // Let's check if a function called like the method we wanted
        // to call exists somewhere
        if(!function_exists($name))
        {
            // No? So let's raise an Exception
            throw new Exception("The function you called " . $name . " does not exist");
        }
        // Such a function seems to exist so call it and pass
        // the arguments
        call_user_func_array($name, $args);
    }

    public function __construct()
    {   
        // Call undefined method
        $this->addOn('My Input');
    }

}

<强>的index.php

<?php

include 'functions.php';
include 'MyClass.php';

$cls = new MyClass();

答案 2 :(得分:0)

虽然如此,但有一些限制......

<?php

class SomeClass
{
    private $_funcs = array();

    public function setFunc($name,$func)
    {
        $this->_funcs[$name] = $func;
    }

    public function __call($name, $param)
    {
        if(!function_exists($name))
        {
            if(isset($this->_funcs[$name]))
                $this->_funcs[$name]();
            else echo "NO $name <br />";
        }
    }

    public function dummy()
    {
        echo 'DUMMY<br />';
    }
}

然后让我们测试一下:

$sc = new SomeClass();
$sc->haha();
$sc->dummy();
$sc->setFunc('foo',function(){echo 'Hello New World!';});
// blah blah blah...
// blah blah blah...
// blah blah blah...
// blah blah blah...
// blah blah blah...
$sc->foo();

我想到的一个限制是如何确定是否要从$ sc级别返回结果。

结果应该是基于上面的代码:

NO haha 
DUMMY
Hello New World!

注意:我知道这不是最好的做法,OP,你应该也知道。我刚刚回答了OP的问题。

编辑:为了能够确定函数是否应该返回某些内容,请尝试利用函数名称(如r_sum)和前缀r_来确定它是否需要返回一些内容。

示例:

public function __call($name, $param)
{
    if(!function_exists($name))
    {
        if(isset($this->_funcs[$name]))
        {
            if(strpos($name, 'r_')===0)
                return $this->_funcs[$name](); // execute and return
            else
                $this->_funcs[$name](); // just execute
        }
        else echo "NO $name <br />";
    }
}

但是现在,我差点忘了的另一个问题是,你无法通过新的funcs访问类属性。

<强> SUGGESTION

将您的相似或相关功能组合成一个静态类,以便随时随地重复使用您的代码。

//APP contains functions designed closely to work with your CMS
// example
APP::abort();
// HTML contains functions like getting page title, external reso, etc
// example
echo HTML::getTitle();
// ROUTE contains many routing reqs that you may need
// example
ROUTE::to('heaven');
// many more...