XRL  2.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 
48  public function __construct($callable)
49  {
50  if (!is_callable($callable, false, $representation)) {
51  throw new \InvalidArgumentException('Not a valid callable');
52  }
53 
54  // This happens for anonymous functions
55  // created with create_function().
56  if (is_string($callable) && $representation == "") {
57  $representation = $callable;
58  }
59 
60  $this->callableObj = $callable;
61  $this->representation = $representation;
62  }
63 
65  public function getCallable()
66  {
67  return $this->callableObj;
68  }
69 
71  public function getRepresentation()
72  {
73  return $this->representation;
74  }
75 
77  public function invoke()
78  {
79  // HACK: we use debug_backtrace() to get (and pass along)
80  // references for call_user_func_array().
81 
82  if (version_compare(PHP_VERSION, '5.4', '>=')) {
83  // Starting with PHP 5.4.0, it is possible to limit
84  // the number of stack frames returned.
85  $bt = debug_backtrace(0, 1);
86  } elseif (version_compare(PHP_VERSION, '5.3.6', '>=')) {
87  // Starting with PHP 5.3.6, the first argument
88  // to debug_backtrace() is a bitmask of options.
89  $bt = debug_backtrace(0);
90  } else {
91  $bt = debug_backtrace(false);
92  }
93 
94  if (isset($bt[0]['args'])) {
95  $args =& $bt[0]['args'];
96  } else {
97  $args = array();
98  }
99  return call_user_func_array($this->callableObj, $args);
100  }
101 
103  public function invokeArgs(array &$args)
104  {
105  return call_user_func_array($this->callableObj, $args);
106  }
107 
109  public function __invoke()
110  {
111  // HACK: we use debug_backtrace() to get (and pass along)
112  // references for call_user_func_array().
113 
114  if (version_compare(PHP_VERSION, '5.4', '>=')) {
115  // Starting with PHP 5.4.0, it is possible to limit
116  // the number of stack frames returned.
117  $bt = debug_backtrace(0, 1);
118  } elseif (version_compare(PHP_VERSION, '5.3.6', '>=')) {
119  // Starting with PHP 5.3.6, the first argument
120  // to debug_backtrace() is a bitmask of options.
121  $bt = debug_backtrace(0);
122  } else {
123  $bt = debug_backtrace(false);
124  }
125 
126  if (isset($bt[0]['args'])) {
127  $args =& $bt[0]['args'];
128  } else {
129  $args = array();
130  }
131  return call_user_func(array($this, 'invokeArgs'), $args);
132  }
133 
135  public function __toString()
136  {
137  return $this->representation;
138  }
139 
141  public function getReflector()
142  {
143  $parts = explode('::', $this->representation);
144 
145  // Did we wrap a function?
146  if (count($parts) == 1) {
147  return new \ReflectionFunction($this->callableObj);
148  }
149 
150  // Did we wrap a Closure or some invokable object?
151  if (!is_array($this->callableObj)) {
152  $callable = array($this->callableObj, $parts[1]);
153  } else {
154  $callable = $this->callableObj;
155  }
156  return new \ReflectionMethod($callable[0], $callable[1]);
157  }
158 }
$callableObj
Inner callable object, as used by PHP.
Interface for something that can be called.
$representation
Human representation of the inner callable.
Class used to represent anything that is callable.