fork download
  1. <?php
  2. class Composable {
  3. private $behaviors = array();
  4.  
  5. public function __call($name, $arguments) {
  6. foreach ($this->behaviors as $behavior) {
  7. if ($behavior->provides($name)) {
  8. return $behavior->invoke($this, $name, $arguments);
  9. }
  10. }
  11.  
  12. throw new Exception("No method $name and no behavior that implements it!");
  13. }
  14.  
  15. public function attach($behavior) {
  16. $this->behaviors[] = $behavior;
  17. }
  18. }
  19.  
  20. class User extends Composable {
  21. }
  22.  
  23. abstract class Behavior {
  24. public function provides($name) {
  25. return method_exists($this, $name);
  26. }
  27.  
  28. public function invoke($target, $name, $arguments) {
  29. array_unshift($arguments, $target);
  30. return call_user_func_array(array($this, $name), $arguments);
  31. }
  32. }
  33.  
  34. class GrouppableBehavior extends Behavior {
  35. public function join(User $user, $groupName) {
  36. echo "The user has joined group $groupName.";
  37. }
  38. }
  39.  
  40. $user1 = new User;
  41. $user2 = new User;
  42.  
  43. $user1->attach(new GrouppableBehavior);
  44. $user1->join('Test Group');
  45. $user2->join('Test Group');
  46.  
Runtime error #stdin #stdout 0.02s 13064KB
stdin
Standard input is empty
stdout
The user has joined group Test Group.
Fatal error: Uncaught exception 'Exception' with message 'No method join and no behavior that implements it!' in /home/xQlLMW/prog.php:12
Stack trace:
#0 [internal function]: Composable->__call('join', Array)
#1 /home/xQlLMW/prog.php(45): User->join('Test Group')
#2 {main}
  thrown in /home/xQlLMW/prog.php on line 12