动态重新定义PHP类函数?

时间:2015-10-07 17:09:30

标签: php oop

我试图弄清楚如何动态导入大量PHP类函数。例如......

class Entity
{
    public function __construct($type)
    {
    require_once $type."_functions.php"
    }

    // ...

}

$person = new Entity("human");
$person->sayhi();
$cow = new Entity("cow");
$cow->sayhi();

human_functions.php:

class Entity redefines Entity
    {
    public function sayhi()
        {
        echo "Hello world!";
        }
    }

cow_functions.php:

class Entity redefines Entity
    {
    public function sayhi()
        {
        echo "Moo!";
        }
    }

我发现了一些可能性,例如classkit_method_redefine()runkit_method_redefine()("实验",他们无论如何也无法修改当前正在运行的类)。我现在正在使用PHP 5.3.3,因此我无法使用Traits(不确定这是否是我正在寻找的)。我成功重新定义了处理程序变量,如下所示:

// Example 2:
class OtherEntity { /* Code Here */ }
class Entity
    {
    public function __construct($type)
        {
        global $foo;
        unset($foo);
        $foo = new OtherEntity();
        }
    }

$foo = new Entity();

但是,这感觉就像一个非常 hacky方法。更重要的是,如果我没有命名类<{1}}的每个实例,那么它将无效。我试图做什么有解决方法吗?

注意:我知道我可以扩展一个类,但是在我启动实体类的情况下,没有安全的方法可以提前知道需要启动哪个子类用。也许我可以编写一种方法,例如:

$foo

感谢您的帮助!

2 个答案:

答案 0 :(得分:5)

以下是您可以尝试的可能解决方案的想法。让CowHuman类扩展Entity类。但是,Entity类将使用factory基于值是否安全来实例化对象。让我们更详细地看一下这个:

/*
 * Class Entity should not be able to be instantiated.
 * It should contain a factory to instantiate the
 * appropriate entity and an abstract function declaring 
 * the method that each entity will need to implement.
 */
abstract class Entity {

    public static function factory($type) {
        return (is_subclass_of($type, "Entity")) ? new $type() : FALSE;
    }

    abstract public function sayHi();

}

/*
 * Human class extends Entity and implements the
 * abstract method from Entity.
 */
class Human extends Entity {

    public function sayHi() {
        echo "Hello World!";
    }

}

/*
 * Cow class extends Entity and implements the
 * abstract method from Entity.
 */
class Cow extends Entity {

    public function sayHi() {
        echo "Moo!";
    }

}

现在使用此方法,调用工厂方法,如果一切正常,它将实例化将扩展Entity的正确类。

$person = Entity::factory("Human");
$person->sayHi();

$cow = Entity::factory("Cow");
$cow->sayHi();

使用,is_subclass_of()会确保您的安全,因为如果传入的值不是扩展Entity的类,则会返回FALSE的值。

如果您想查看上面的代码,请复制上面的php代码并在phpfiddle.org上测试一下。

答案 1 :(得分:1)

您可以做的一件事是创建HumanCow作为Entity的子类。执行new Entity("Human")后,您可以将新创建​​的Human对象存储在 Entity实例中。

然后,您可以使用__call将方法调用重定向到&#34;子元素&#34;。

class Entity{
    private $child;

    public function __construct($type){
        $this->child = new $type;
    }

    public function __call($func, $params=array()){
        $method = method_exists($this, $func)
            ? [$this, $func] : [$this->child, $func];
        return call_user_func_array($method, $params);
    }
}

class Human extends Entity{
    public function __construct(){}

    public function sayhi(){
        echo "Hello world!";
    }
}

class Cow extends Entity{
    public function __construct(){}

    public function sayhi(){    
        echo "Moo!";
    }
}

$person = new Entity("Human");
$person->sayhi();

$cow = new Entity("Cow");
$cow->sayhi();

唯一的缺点是$person$cow都是Entity个对象。