3 XmlRpcServer
::setContentType("text/xml");
4 XmlRpcServer
::capture();
7 * XMLRPC Server, very KISS
10 * NOTE: requires ext/xmlrpc
15 * class Handler extends XmlRpcRequestHandlerStub {
16 * public function xmlrpcPing(array $values) {
21 * XmlRpcServer::factory("namespace")->registerHandler(new Handler);
22 * XmlRpcServer::run();
23 * } catch (Exception $ex) {
24 * XmlRpcServer::error($ex->getCode(), $ex->getMessage());
28 * @copyright Michael Wallner, <mike@iworks.at>
29 * @license BSD, revised
34 class XmlRpcServer
extends HttpResponse
41 public static $encoding = "iso-8859-1";
51 * RPC handler attached to this server instance
53 * @var XmlRpcRequestHandler
57 private static $xmlreq;
58 private static $xmlrpc;
59 private static $refcnt = 0;
60 private static $handle = array();
63 * Create a new XmlRpcServer instance
65 * @param string $namespace
66 * @param string $encoding
68 public function __construct($namespace)
70 $this->namespace = $namespace;
77 public function __destruct()
79 if (self
::$refcnt && !--self
::$refcnt) {
80 xmlrpc_server_destroy(self
::$xmlrpc);
87 * @param string $namespace
88 * @return XmlRpcServer
90 public static function factory($namespace)
92 return new XmlRpcServer($namespace);
96 * Run all servers and send response
98 * @param array $options
100 public static function run(array $options = null)
102 self
::initialize(false, true);
103 self
::setContentType("text/xml; charset=". self
::$encoding);
104 echo xmlrpc_server_call_method(self
::$xmlrpc, self
::$xmlreq, null,
105 array("encoding" => self
::$encoding) +
(array) $options);
109 * Test hook; call instead of XmlRpcServer::run()
111 * @param string $method
112 * @param array $params
113 * @param array $request_options
114 * @param array $response_options
116 public static function test($method, array $params, array $request_options = null, array $response_options = null)
118 self
::$xmlreq = xmlrpc_encode_request($method, $params, $request_options);
119 self
::run($response_options);
123 * Optional XMLRPC error handler
128 public static function error($code, $msg, array $options = null)
130 echo xmlrpc_encode(array("faultCode" => $code, "faultString" => $msg),
131 array("encoding" => self
::$encoding) +
(array) $options);
135 * Register a single method
137 * @param string $name
138 * @param mixed $callback
139 * @param mixed $dispatch
142 public function registerMethod($name, $callback, $dispatch = null, array $spec = null)
144 if (!is_callable($callback, false, $cb_name)) {
145 throw new Exception("$cb_name is not a valid callback");
147 if (isset($dispatch)) {
148 if (!is_callable($dispatch, false, $cb_name)) {
149 throw new Exception("$cb_name is not a valid callback");
151 xmlrpc_server_register_method(self
::$xmlrpc, $name, $dispatch);
152 self
::$handle[$name] = $callback;
154 xmlrpc_server_register_method(self
::$xmlrpc, $name, $callback);
158 xmlrpc_server_add_introspection_data(self
::$xmlrpc, $spec);
163 * Register an XmlRpcRequestHandler for this server instance
165 * @param XmlRpcRequestHandler $handler
167 public function registerHandler(XmlRpcRequestHandler
$handler)
169 $this->handler
= $handler;
171 foreach (get_class_methods($handler) as $method) {
172 if (!strncmp($method, "xmlrpc", 6)) {
173 $this->registerMethod(
174 $this->method($method, $handler->getNamespace()),
175 array($handler, $method), array($this, "dispatch"));
179 $handler->getIntrospectionData($spec);
180 if (is_array($spec)) {
181 xmlrpc_server_add_introspection_data(self
::$xmlrpc, $spec);
185 private function method($method, $namespace = null)
187 if (!strlen($namespace)) {
188 $namespace = strlen($this->namespace) ?
$this->namespace : "xmlrpc";
190 return $namespace .".". strtolower($method[6]) . substr($method, 7);
193 private function dispatch($method, array $params = null)
195 if (array_key_exists($method, self
::$handle)) {
196 return call_user_func(self
::$handle[$method], $params);
198 throw new Exception("Unknown XMLRPC method: $method");
201 private static function initialize($server = true, $data = false)
204 if (!self
::$xmlreq && !(self
::$xmlreq = http_get_request_body())) {
205 throw new Exception("Failed to fetch XMLRPC request body");
209 if (!self
::$xmlrpc && !(self
::$xmlrpc = xmlrpc_server_create())) {
210 throw new Exception("Failed to initialize XMLRPC server");
218 * XmlRpcRequestHandler
220 * Define XMLRPC methods with an "xmlrpc" prefix, eg:
222 * class IntOp implements XmlRpcRequestHandler {
223 * public function getNamespace() {
226 * public function getInstrospectionData(array &$spec = null) {
228 * // XMLRPC method name: int.sumValues
229 * public function xmlrpcSumValues(array $values) {
230 * return array_sum($values);
235 interface XmlRpcRequestHandler
237 public function getNamespace();
238 public function getIntrospectionData(array &$spec = null);
242 * XmlRpcRequestHandlerStub
244 abstract class XmlRpcRequestHandlerStub
implements XmlRpcRequestHandler
246 public function getNamespace()
249 public function getIntrospectionData(array &$spec = null)