XRL  latest
Simple XML-RPC Library (both client and server)
Server.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 
15 
66 {
68  protected $XRLFunctions;
69 
71  protected $XRLEncoder;
72 
74  protected $XRLDecoder;
75 
76 
95  public function __construct(
96  \fpoirotte\XRL\EncoderInterface $encoder = null,
97  \fpoirotte\XRL\DecoderInterface $decoder = null
98  ) {
99  if ($encoder === null) {
100  $encoder = new \fpoirotte\XRL\NativeEncoder(
101  new \fpoirotte\XRL\Encoder(null, false, true)
102  );
103  }
104 
105  if ($decoder === null) {
106  $decoder = new \fpoirotte\XRL\NativeDecoder(
107  new \fpoirotte\XRL\Decoder(null, true)
108  );
109  }
110 
111  $this->XRLEncoder = $encoder;
112  $this->XRLDecoder = $decoder;
113  $this->XRLFunctions = array();
114  }
115 
137  public function __set($func, $callback)
138  {
139  $this->XRLFunctions[$func] = new \fpoirotte\XRL\CallableObject($callback);
140  }
141 
147  public function offsetSet($func, $callback)
148  {
149  $this->XRLFunctions[$func] = new \fpoirotte\XRL\CallableObject($callback);
150  }
151 
172  public function __get($func)
173  {
174  return $this->XRLFunctions[$func];
175  }
176 
182  public function offsetGet($func)
183  {
184  return $this->XRLFunctions[$func];
185  }
186 
199  public function __isset($func)
200  {
201  return isset($this->XRLFunctions[$func]);
202  }
203 
209  public function offsetExists($func)
210  {
211  return isset($this->XRLFunctions[$func]);
212  }
213 
225  public function __unset($func)
226  {
227  unset($this->XRLFunctions[$func]);
228  }
229 
235  public function offsetUnset($func)
236  {
237  unset($this->XRLFunctions[$func]);
238  }
239 
248  public function count()
249  {
250  return count($this->XRLFunctions);
251  }
252 
261  public function getIterator()
262  {
263  return new \ArrayIterator($this->XRLFunctions);
264  }
265 
290  public function expose($other, $prefix = '')
291  {
292  if (!is_string($other) && !is_object($other)) {
293  throw new \InvalidArgumentException('Invalid adoption');
294  }
295 
296  if (!is_string($prefix)) {
297  throw new \InvalidArgumentException('Invalid prefix');
298  }
299 
300  $prefix = rtrim($prefix, '.');
301  if ($prefix !== '') {
302  $prefix .= '.';
303  }
304 
305  if (is_object($other)) {
306  // An object was passed.
307  $class = get_class($other);
308  foreach (get_class_methods($class) as $method) {
309  // Only adopt public methods of the object,
310  // excluding the constructor and static methods.
311  // To also register static methods, call this method
312  // a second time with get_class($other).
313  $reflector = new \ReflectionMethod($class, $method);
314  if ($reflector->isPublic() && !$reflector->isConstructor() &&
315  !$reflector->isStatic()) {
316  $this[$prefix . $method] = array($other, $method);
317  }
318  }
319  } else {
320  // A class was passed.
321  foreach (get_class_methods($other) as $method) {
322  // Only adopt methods which are both public and static.
323  $reflector = new \ReflectionMethod($other, $method);
324  if ($reflector->isPublic() && $reflector->isStatic()) {
325  $this[$prefix . $method] = array($other, $method);
326  }
327  }
328  }
329  }
330 
352  public function handle($URI = null)
353  {
354  if ($URI === null) {
355  $URI = 'php://input';
356  }
357 
358  try {
359  $request = $this->XRLDecoder->decodeRequest($URI);
360  $procedure = $request->getProcedure();
361  // Necessary to keep references.
362  $params = $request->getParams();
363 
364  $result = $this->call($procedure, $params);
365  $response = $this->XRLEncoder->encodeResponse($result);
366  } catch (\Exception $result) {
367  $response = $this->XRLEncoder->encodeError($result);
368  }
369 
370  return new \fpoirotte\XRL\Response($response);
371  }
372 
385  public function call($procedure, array $params)
386  {
387  if (!is_string($procedure)) {
388  throw new \BadFunctionCallException('Expected a string');
389  }
390 
391  if (!isset($this->XRLFunctions[$procedure])) {
392  throw new \fpoirotte\XRL\Faults\MethodNotFoundException();
393  }
394 
395  $callable = $this->XRLFunctions[$procedure];
396  return $callable(...$params);
397  }
398 }
Interface to provide accessing objects as arrays.
Definition: ArrayAccess.php:10
Interface for an XML-RPC decoder.
Interface for an XML-RPC encoder.
$XRLEncoder
Encoder for the request.
Definition: Server.php:71
Interface to create an external Iterator.
An XML-RPC encoder that can produce either compact documents or pretty documents. ...
Definition: Encoder.php:21
handle($URI=null)
Definition: Server.php:352
An exception that is used to represent XML-RPC errors.
Definition: Exception.php:21
call($procedure, array $params)
Definition: Server.php:385
A simple XML-RPC server.
Definition: Server.php:65
offsetSet($func, $callback)
Definition: Server.php:147
$XRLFunctions
Registered "procedures".
Definition: Server.php:68
A decoder that can process XML-RPC requests and responses, with optional XML validation.
Definition: Decoder.php:21
$XRLDecoder
Decoder for the response.
Definition: Server.php:74
__construct(\fpoirotte\XRL\EncoderInterface $encoder=null,\fpoirotte\XRL\DecoderInterface $decoder=null)
Definition: Server.php:95
expose($other, $prefix= '')
Definition: Server.php:290
Classes implementing Countable can be used with the count() function.
Definition: Countable.php:11
__set($func, $callback)
Definition: Server.php:137