假设我有以下行为和标准类:
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();)中可用而不“扩展”类......
这可能吗?
编辑:感谢所有回复,我有答案,或者至少我需要知道我的选择是什么,谢谢!我只能给出一个正确的答案,所以我要回答第一个问题。
答案 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();