XRL  3.0.0
Simple XML-RPC Library (both client and server)
CallableObject.php
1 <?php
2 /*
3  * This file is part of XRL, a simple XML-RPC Library for PHP.
4  *
5  * Copyright (c) 2012, XRL Team. All rights reserved.
6  * XRL is licensed under the 3-clause BSD License.
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11 
12 namespace fpoirotte\XRL;
13 
24 {
26  protected $callableObj;
27 
29  protected $representation;
30 
32  private static $patched;
33 
51  public function __construct($callable)
52  {
53  if (!is_callable($callable, false, $representation)) {
54  throw new \InvalidArgumentException('Not a valid callable');
55  }
56 
57  if (!self::$patched) {
58  self::$patched = true;
59  // @codeCoverageIgnoreStart
60  // Adds support for references to invoke() on PHP 5.6.0+.
61  if (version_compare(PHP_VERSION, '5.6.0', '>=') &&
62  function_exists('runkit_method_redefine')) {
63  runkit_method_redefine(
64  __CLASS__,
65  '__invoke',
66  '&...$args',
67  'return call_user_func_array($this->callableObj, $args);'
68  );
69  }
70  // @codeCoverageIgnoreEnd
71  }
72 
73  // This happens for anonymous functions
74  // created with create_function().
75  if (is_string($callable) && $representation == "") {
76  $representation = $callable;
77  }
78 
79  $this->callableObj = $callable;
80  $this->representation = $representation;
81  }
82 
84  public function getCallable()
85  {
86  return $this->callableObj;
87  }
88 
90  public function getRepresentation()
91  {
92  return $this->representation;
93  }
94 
96  public function invokeArgs(array &$args)
97  {
98  $newArgs = array();
99  foreach ($args as &$arg) {
100  $newArgs[] =& $arg;
101  }
102  return call_user_func_array($this->callableObj, $newArgs);
103  }
104 
106  public function __invoke()
107  {
108  return call_user_func_array($this->callableObj, func_get_args());
109  }
110 
112  public function __toString()
113  {
114  return $this->representation;
115  }
116 
118  public function getReflector()
119  {
120  $parts = explode('::', $this->representation);
121 
122  // Did we wrap a function?
123  if (count($parts) == 1) {
124  return new \ReflectionFunction($this->callableObj);
125  }
126 
127  // Did we wrap a Closure or some invokable object?
128  if (!is_array($this->callableObj)) {
129  $callable = array($this->callableObj, $parts[1]);
130  } else {
131  $callable = $this->callableObj;
132  }
133  return new \ReflectionMethod($callable[0], $callable[1]);
134  }
135 }
$callableObj
Inner callable object, as used by PHP.
static $patched
Work-around for __invoke() with references in PHP 5.6.0+.
Interface for something that can be called.
$representation
Human representation of the inner callable.
Class used to represent anything that is callable.