将行为方法合并到PHP类

时间:2014-06-26 12:09:54

标签: php oop abstract

假设我有以下行为和标准类:

abstract class MyBehavior {
     function testFunction(){
         return 'test';
     }
}

class TestClass {
     var $use = array('MyBehavior');

     function __construct(){
         // do something to give me access to function testFunction through
         // $this->testFunction();
     }
}

$test = new TestClass();

正如我评论的那样,我希望MyCehavior方法在TestClass($ test-> testFunction();)中可用而不“扩展”类......

这可能吗?

编辑:感谢所有回复,我有答案,或者至少我需要知道我的选择是什么,谢谢!我只能给出一个正确的答案,所以我要回答第一个问题。

4 个答案:

答案 0 :(得分:6)

<?php

trait MyBehavior {

    public function testFunction() 
    {
        return 'test';
    }

}

class TestClass {

    use MyBehavior;

    function __construct()
    {
        echo $this->testFunction();
    }

}

$test = new TestClass();

您可以使用trait将所需行为添加到课程中。自PHP&gt; = 5.4.0以来存在特征,并且是在不实际使用继承的情况下扩展类的简洁方法。 但要小心:

如果误用,特质会比他们帮助你更多。安东尼费雷拉写了一篇关于特质缺点的非常好的博文。所以 you should definitely give it a read

答案 1 :(得分:3)

如果你使用&gt; = PHP 5.4你可以使用特征,但是这个例子不会做任何事情,因为构造函数不能返回值:

trait MyBehavior 
{
     public function testFunction()
     {
         return 'test';
     }
}

class TestClass 
{
    use MyBehavior;

    public function __construct() 
    {
        $this->testFunction();
    }
}

$test = new TestClass();

答案 2 :(得分:2)

特质真的是要走的路。你可以在没有特质的情况下一起破解。你必须使MyBehavior不抽象才能使用:

class TestClass {

    protected $use = ['MyBehavior'];
    protected $_behaviors = [];

    public function __construct() {
        foreach ($this->use as $behavior) {
            $this->_behaviors[] = new $behavior;
        }
    }

    public function __call($name, $args) {
        foreach ($this->_behaviors as $behavior) {
            if (method_exists($behavior, $name)) {
                return call_user_func_array([$behavior, $name], $args);
            }
        }
    }

}

虽然不是很漂亮。

答案 3 :(得分:0)

有点棘手,但你也可以这样做:

abstract class MyBehavior 
{
     function testFunction()
     {
         return 'test';
     }
}

class TestClass {
     var $cls = array('MyBehavior');

     function __construct(){
         echo call_user_func(array($this->cls[0], 'testFunction'));
     }
}

$test = new TestClass();

Example online