需要特征的方法用于特定类

时间:2014-09-08 12:05:13

标签: php oop traits

http://hacklang.org/tutorial/ - 参见上一个练习(24)。

...
trait T {
    require extends C;
...

你将如何在PHP中实现这一目标?

我想在PHP单元测试中使用它,如下所示:

class EventsTest extends TrafficWebTestCase
{
    use EntityRepositoryMock;
    use ValidatorMock;
    use EventsDataProviderTrait;

特质的一个例子:

trait ValidatorMock
{
...
protected function getValidatorMock($validateObject, $return = [])
{
    if (!method_exists($this, 'getMockForAbstractClass')) {
        throw new InvalidTraitUseException();
    }

    $this->validatorMock = $this->getMockForAbstractClass(
        'Symfony\Component\Validator\Validator\ValidatorInterface'
    );

    $this->validatorMock->expects($this->once())
        ->method('validate')
        ->with($this->equalTo($validateObject))
        ->willReturn($return);

    return $this->validatorMock;
}

这些特性可以创建一些特定的模拟或做其他只与单元测试相关的内容。在这些特征中,我使用了\ PHPUnit_Framework_TestCase中的方法,因此我想检查特征是否在有效的上下文中使用。

1 个答案:

答案 0 :(得分:1)

我想你想要这样的东西:

trait T
{
    public function __construct()
    {
        if (!($this instanceof C)) {
            die('Not an instance of C');
        }
        echo "Everything fine here<br />";

        $this->someMethod();
    }


}

class C
{
    public function someMethod()
    {
        echo "required method<br />";
    }

}

class A extends C
{
    use T;

    public function doSomething()
    {

    }
}

class B
{
    use T;

    public function doSomething()
    {

    }
}

$a = new A();
$b = new B();

使用instanceof可以检查对象是否扩展了某个类。

对于以下代码,结果将是:

Everything fine here
required method
Not an instance of C

更复杂的代码(无需检入构造函数):

trait T
{

    public function myFunction()
    {
        $this->checkHierarchy();

        echo "normal actions<br />";

    }

    public function secondFunction()
    {
        $this->checkHierarchy('D');

        echo "normal actions<br />";

    }

    private function checkHierarchy($className = 'C')
    {
        if (!($this instanceof $className)) {
            throw new \Exception('Not an instance of ' . $className . "<br />");
        }
        echo "Everything fine here<br />";
    }


}

class C
{
    public function someMethod()
    {
        echo "required method<br />";
    }

}

class A extends C
{
    use T;

    public function doSomething()
    {

    }

    public function __construct()
    {
        echo "aaa<br />";
    }
}

class B
{
    use T;

    public function doSomething()
    {

    }

    public function __construct()
    {
        echo "bbb<br />";

    }
}


$a = new A();
try {
    $a->myFunction();
} catch (\Exception $e) {
    echo $e->getMessage();
}

try {
    $a->secondFunction();
} catch (\Exception $e) {
    echo $e->getMessage();
}
$b = new B();
try {
    $b->myFunction();
} catch (\Exception $e) {
    echo $e->getMessage();
}