public function __call($method, $args = array()) { $params = array(); foreach ($args as $arg) { // argument already encoded, perhaps via encodeBinary if ($arg instanceof PhpXmlRpc\Value) { $params[] = $arg; continue; } // serialize all objects first if (is_object($arg)) { $arg = serialize($arg); } $params[] = $this->encoder->encode($arg); } $req = new PhpXmlRpc\Request($method, $params); $result = $this->client->send($req); if ($result === 0) { throw new Eventum_RPC_Exception($this->client->errstr); } if (is_object($result) && $result->faultCode()) { throw new Eventum_RPC_Exception($result->faultString()); } $value = $this->encoder->decode($result->value()); return $value; }
/** * Perform request to wubook api * * @param $method * @param $args array, NOTICE: order is important here * @param bool $passToken true if you want pass token as first parameter * @param bool $passPropertyId true if you want pass property id as second parameter * @param bool $tryAcquireNewToken * * @return mixed|Value|string * @internal param bool|true $useToken true if you want use token from config */ public function request($method, array $args, $passToken = true, $passPropertyId = true, $tryAcquireNewToken = true) { if (!in_array($method, $this->methodWhitelist)) { throw new MethodNotAllowedException($this->methodWhitelist, 'Method "' . $method . '" not allowed, allowed: ' . join(', ', $this->methodWhitelist)); } $requestArgs = $passToken ? [$this->tokenProvider->getToken()] : []; if ($passPropertyId) { $requestArgs[] = (string) $this->propertyId; } $encoder = new Encoder(); $requestData = []; foreach (array_merge($requestArgs, $args) as $arg) { $requestData[] = $encoder->encode($arg); } $server = new \PhpXmlRpc\Client($this->apiUrl); $request = new Request($method, $requestData); $response = $server->send($request); $isResponseOK = !empty($response->value()) && (int) $response->value()->me['array'][0]->scalarval() == 0; if (!$isResponseOK && $tryAcquireNewToken) { if ($this->tokenHandler->isCurrentTokenValid()) { return $response; } $this->tokenHandler->acquireToken(); return self::request($method, $args, $passToken, $passPropertyId, false); } return $response; }
/** * Forward an xmlrpc request to another server, and return to client the response received. * * DO NOT RUN AS IS IN PRODUCTION - this is an open relay !!! * * @param PhpXmlRpc\Request $req (see method docs below for a description of the expected parameters) * * @return PhpXmlRpc\Response */ function forward_request($req) { $encoder = new \PhpXmlRpc\Encoder(); // create client $timeout = 0; $url = $encoder->decode($req->getParam(0)); $client = new PhpXmlRpc\Client($url); if ($req->getNumParams() > 3) { // we have to set some options onto the client. // Note that if we do not untaint the received values, warnings might be generated... $options = $encoder->decode($req->getParam(3)); foreach ($options as $key => $val) { switch ($key) { case 'Cookie': break; case 'Credentials': break; case 'RequestCompression': $client->setRequestCompression($val); break; case 'SSLVerifyHost': $client->setSSLVerifyHost($val); break; case 'SSLVerifyPeer': $client->setSSLVerifyPeer($val); break; case 'Timeout': $timeout = (int) $val; break; } // switch } } // build call for remote server /// @todo find a way to forward client info (such as IP) to server, either /// - as xml comments in the payload, or /// - using std http header conventions, such as X-forwarded-for... $reqMethod = $encoder->decode($req->getParam(1)); $pars = $req->getParam(2); $req = new PhpXmlRpc\Request($reqMethod); foreach ($pars as $par) { $req->addParam($par); } // add debug info into response we give back to caller PhpXmlRpc\Server::xmlrpc_debugmsg("Sending to server {$url} the payload: " . $req->serialize()); return $client->send($req, $timeout); }
<h1>Getstatename demo</h1> <h2>Send a U.S. state number to the server and get back the state name</h2> <h3>The code demonstrates usage of automatic encoding/decoding of php variables into xmlrpc values</h3> <?php include_once __DIR__ . "/../../src/Autoloader.php"; PhpXmlRpc\Autoloader::register(); if (isset($_POST["stateno"]) && $_POST["stateno"] != "") { $stateNo = (int) $_POST["stateno"]; $encoder = new PhpXmlRpc\Encoder(); $req = new PhpXmlRpc\Request('examples.getStateName', array($encoder->encode($stateNo))); print "Sending the following request:<pre>\n\n" . htmlentities($req->serialize()) . "\n\n</pre>Debug info of server data follows...\n\n"; $client = new PhpXmlRpc\Client("http://phpxmlrpc.sourceforge.net/server.php"); $client->setDebug(1); $r = $client->send($req); if (!$r->faultCode()) { $v = $r->value(); print "<br/>State number <b>" . $stateNo . "</b> is <b>" . htmlspecialchars($encoder->decode($v)) . "</b><br/>"; } else { print "An error occurred: "; print "Code: " . htmlspecialchars($r->faultCode()) . " Reason: '" . htmlspecialchars($r->faultString()) . "'</pre><br/>"; } } else { $stateNo = ""; } print "<form action=\"getstatename.php\" method=\"POST\">\n<input name=\"stateno\" value=\"" . $stateNo . "\"><input type=\"submit\" value=\"go\" name=\"submit\"></form>\n<p>Enter a state number to query its name</p>"; ?> </body> </html>
<h1>Introspect demo</h1> <h2>Query server for available methods and their description</h2> <h3>The code demonstrates usage of multicall and introspection methods</h3> <?php include_once __DIR__ . "/../../src/Autoloader.php"; PhpXmlRpc\Autoloader::register(); function display_error($r) { print "An error occurred: "; print "Code: " . $r->faultCode() . " Reason: '" . $r->faultString() . "'<br/>"; } $client = new PhpXmlRpc\Client("http://phpxmlrpc.sourceforge.net/server.php"); // First off, let's retrieve the list of methods available on the remote server print "<h3>methods available at http://" . $client->server . $client->path . "</h3>\n"; $req = new PhpXmlRpc\Request('system.listMethods'); $resp = $client->send($req); if ($resp->faultCode()) { display_error($resp); } else { $v = $resp->value(); // Then, retrieve the signature and help text of each available method foreach ($v as $methodName) { print "<h4>" . $methodName->scalarval() . "</h4>\n"; // build messages first, add params later $m1 = new PhpXmlRpc\Request('system.methodHelp'); $m2 = new PhpXmlRpc\Request('system.methodSignature'); $val = new PhpXmlRpc\Value($methodName->scalarval(), "string"); $m1->addParam($val); $m2->addParam($val); // Send multiple requests in one http call. // If server does not support multicall, client will automatically fall back to 2 separate calls
When you press <kbd>Send</kbd> this page will reload, showing you the XML-RPC request sent to the host server, the XML-RPC response received and the internal evaluation done by the PHP implementation.</p> <p>You can find the source to this page here: <a href="mail.php?showSource=1">mail.php</a><br/> And the source to a functionally identical mail-by-XML-RPC server in the file <a href="../server/server.php?showSource=1">server.php</a> included with the library (look for the 'mail_send' method)</p> <?php include_once __DIR__ . "/../../src/Autoloader.php"; PhpXmlRpc\Autoloader::register(); if (isset($_POST["mailto"]) && $_POST["mailto"]) { $server = "http://phpxmlrpc.sourceforge.net/server.php"; $req = new PhpXmlRpc\Request('mail.send', array(new PhpXmlRpc\Value($_POST["mailto"]), new PhpXmlRpc\Value($_POST["mailsub"]), new PhpXmlRpc\Value($_POST["mailmsg"]), new PhpXmlRpc\Value($_POST["mailfrom"]), new PhpXmlRpc\Value($_POST["mailcc"]), new PhpXmlRpc\Value($_POST["mailbcc"]), new PhpXmlRpc\Value("text/plain"))); $client = new PhpXmlRpc\Client($server); $client->setDebug(2); $resp = $client->send($req); if (!$resp->faultCode()) { print "Mail sent OK<br/>\n"; } else { print "<fonr color=\"red\">"; print "Mail send failed<br/>\n"; print "Fault: "; print "Code: " . htmlspecialchars($resp->faultCode()) . " Reason: '" . htmlspecialchars($resp->faultString()) . "'<br/>"; print "</font><br/>"; } } ?> <form method="POST"> From <input size="60" name="mailfrom" value=""/><br/> <hr/> To <input size="60" name="mailto" value=""/><br/>
<h1>Webservice wrappper demo</h1> <h2>Wrap methods exposed by server into php functions</h2> <h3>The code demonstrates usage of some the most automagic client usage possible:<br/> 1) client that returns php values instead of xmlrpc value objects<br/> 2) wrapping of remote methods into php functions<br/> See also proxy.php for an alternative take </h3> <?php include_once __DIR__ . "/../../src/Autoloader.php"; PhpXmlRpc\Autoloader::register(); $client = new PhpXmlRpc\Client("http://phpxmlrpc.sourceforge.net/server.php"); $client->return_type = 'phpvals'; // let client give us back php values instead of xmlrpcvals $resp = $client->send(new PhpXmlRpc\Request('system.listMethods')); if ($resp->faultCode()) { echo "<p>Server methods list could not be retrieved: error {$resp->faultCode()} '" . htmlspecialchars($resp->faultString()) . "'</p>\n"; } else { echo "<p>Server methods list retrieved, now wrapping it up...</p>\n<ul>\n"; flush(); $callable = false; $wrapper = new PhpXmlRpc\Wrapper(); foreach ($resp->value() as $methodName) { // $resp->value is an array of strings if ($methodName == 'examples.getStateName') { $callable = $wrapper->wrapXmlrpcMethod($client, $methodName); if ($callable) { echo "<li>Remote server method " . htmlspecialchars($methodName) . " wrapped into php function</li>\n"; } else { echo "<li>Remote server method " . htmlspecialchars($methodName) . " could not be wrapped!</li>\n";