Let's say i have the following behavior and standard class:
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();
As i commented, i would like the MyBehavior method to be available inside TestClass ($test->testFunction();) without "extending" the class...
Is this possible?
EDIT: Thanks for all the responses, I have my answer, or at least i need to know what my options are, so thanks! I can only give one right answer, so I'm going with the first response.
<?php
trait MyBehavior {
public function testFunction()
{
return 'test';
}
}
class TestClass {
use MyBehavior;
function __construct()
{
echo $this->testFunction();
}
}
$test = new TestClass();
You could use a trait to add your desired behavior to a class. Traits exist since PHP >= 5.4.0 and are a neat way to extend classes without actually making use of inheritance. But be careful:
If misused, traits will be in your way more than they help you. Anthony Ferrera wrote a really good blogpost about the downsides of traits. So you should definitely give it a read.
If you are using >= PHP 5.4 you can use traits but this example won't do anything as constructors can't return values:
trait MyBehavior
{
public function testFunction()
{
return 'test';
}
}
class TestClass
{
use MyBehavior;
public function __construct()
{
$this->testFunction();
}
}
$test = new TestClass();
Traits really are the way to go. You can hack something together without traits though. You have to make MyBehavior
not-abstract for this to work:
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);
}
}
}
}
Not very pretty though.
A bit tricky but you could do something like this too:
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();