CLVII. XML-RPC 函数

简介

本类函数可用于编写 XML-RPC 服务端和客户端。可以在 http://www.xmlrpc.com/ 找到更多关于 XML-RPC 的信息,同时可在 http://xmlrpc-epi.sourceforge.net/ 找到更多关于此扩展及其功能的文档。

警告

本扩展模块是实验性的。本模块的行为,包括其函数的名称以及其它任何关于此模块的文档可能会在没有通知的情况下随 PHP 以后的发布而改变。使用本扩展模块风险自担。

需求

要编译本扩展模块不需要外部库文件。

安装

默认情况下在 PHP 中是不能使用 XML-RPC 支持的。你需要使用 --with-xmlrpc[=DIR] 配置选项编译 PHP 才能够使用 XML-RPC 支持。从 PHP 4.1.0 开始附带了此扩展。

运行时配置

这些函数的行为受 php.ini 的影响。

表格 1. XML-RPC 配置选项

名称默认值作用范围更新日志
xmlrpc_errors"0"PHP_INI_SYSTEM从 PHP 4.1.0 起开始存在
xmlrpc_error_number"0"PHP_INI_ALL从 PHP 4.1.0 起开始存在
有关 PHP_INI_* 常量进一步的细节与定义参见附录 G

资源类型

本扩展模块未定义任何资源类型。

预定义常量

本扩展模块未定义任何常量。

目录
xmlrpc_decode_request -- 将 XML 译码为 PHP 本身的类型
xmlrpc_decode -- 将 XML 译码为 PHP 本身的类型
xmlrpc_encode_request -- 为 PHP 的值生成 XML
xmlrpc_encode -- 为 PHP 的值生成 XML
xmlrpc_get_type -- 为 PHP 的值获取 xmlrpc 的类型
xmlrpc_is_fault --  Determines if an array value represents an XMLRPC fault
xmlrpc_parse_method_descriptions -- 将 XML 译码成方法描述的列表
xmlrpc_server_add_introspection_data -- 添加自我描述的文档
xmlrpc_server_call_method -- 解析 XML 请求同时调用方法
xmlrpc_server_create -- 创建一个 xmlrpc 服务端
xmlrpc_server_destroy -- 销毁服务端资源
xmlrpc_server_register_introspection_callback -- 注册一个 PHP 函数用于生成文档
xmlrpc_server_register_method -- 注册一个 PHP 函数用于匹配 xmlrpc 方法名
xmlrpc_set_type -- 为一个 PHP 字符串值设置 xmlrpc 的类型、base64 或日期时间

add a note add a note User Contributed Notes
giunta dot gaetano at sea-aeroportimilano dot it
13-Sep-2006 09:40
If you need to use this extension but are stuck on a server where it can not be installed, the php-xmlrpc library found at http://phpxmlrpc.sourceforge.net includes an emulation layer that aims to be 100% compatible with the API of the native extension (as part of the "extras" package since version 0.2).
This means your code should be able to run unmodified on top of the php-xmlrpc library. Of course performance will be at least an order of magnitude worse...
php dot net et athens musician det net
06-Jul-2006 03:11
The devshed article and tutorial has been moved to the following url as of July 5, 2006

http://www.devshed.com/c/a/PHP/Using-XMLRPC-with-PHP/
keithNO dot SPAMthornhill at gmail dot com
17-May-2006 05:16
for others attempting the same thing, here is what a function would look like if you wanted to send a base64 encoded file from a client and then save it onto the server. the other code necessary to call this function via an RPC is available in other comments so i won't repeat it.

parameters:
1 - name of file
2 - base64 encoded data of file

note the use of $file_data->scalar

<?
  
function sendFile($method_name, $params, $user_data) {
      
$file = "/somedir/" . $params[0];
      
$file_data = $params[1];

      
$fh = @fopen($file, "wb");
       if (
$fh) {
           if (@
fwrite($fh, $file_data->scalar)) {
              
$msg = "success msg";
           } else {
              
$msg = "couldn't write to file";
           }
          
fclose($fh);
           return
$msg;
       } else {
           return
"couldn't open file";
       }
   }
?>
10-Mar-2006 04:47
This XML-RPC Service makes the use XML-RPC very esay.

<?php

/**
* function myfun() returns 
*@return array
*/
function myfunc(){
   return
$some_array;
}

$ws = new XML_RPC_Server();
$ws->registerFunction('myfunc');
$ws->run();

?>

http://www.pure-php.de/node/31

It creates also a simple docu.
http://www.pure-php.com/php/service.php?doc
john # curioussymbols com
19-Oct-2005 07:37
I couldn't make the 'xmlrpc_errors' php.ini setting do anything
noticeable (PHP 4.3.11), so I used the following code to report errors
from my XMLRPC server. Hope it's helpful for someone.

<?php
function return_xmlrpc_error($errno,$errstr,$errfile=NULL,$errline=NULL
      
,$errcontext=NULL){
   global
$xmlrpc_server;
   if(!
$xmlrpc_server)die("Error: $errstr in '$errfile', line '$errline'");

  
header("Content-type: text/xml; charset=UTF-8");
   print(
xmlrpc_encode(array(
      
'faultCode'=>$errno
      
,'faultString'=>"Remote XMLRPC Error from
         "
.$_SERVER['HTTP_HOST'].": $errstr in at $errfile:$errline"
  
)));
   die();
}   
set_error_handler('return_xmlrpc_error');
?>

In my server function, I just trigger_error("message",E_USER_ERROR)]
 if something can't be completed.

Then on the client side,
<?php
       $data
=& xmlrpc_decode($response['body']);

       if(
xmlrpc_is_fault($data)){
          
trigger_error($data['faultString'],E_USER_ERROR);
       }
?>
martin dot rode at programmfabrik dot de
04-Aug-2005 08:28
To connect to a python xmlrpc server I use:

function do_call($host, $port, $request) {
 
   $url = "http://$host:$port/";
   $header[] = "Content-type: text/xml";
   $header[] = "Content-length: ".strlen($request);
  
   $ch = curl_init(); 
   curl_setopt($ch, CURLOPT_URL, $url);
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($ch, CURLOPT_TIMEOUT, 1);
   curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
   curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
  
   $data = curl_exec($ch);     
   if (curl_errno($ch)) {
       print curl_error($ch);
   } else {
       curl_close($ch);
       return $data;
   }
}

$request = xmlrpc_encode_request('add', array(3, 4));
$response = do_call($host, $port, $request);
astrolox at lawyersonline dot co dot uk
22-Mar-2005 08:20
The PHP XML-RPC project at SourceForge makes life a hell of a lot easier. However, the project uses some function names which are identical to thoses provided by the XML-RPC extention.

If you are on a server with XML-RPC extension compiled in but wish to use the PHP based version then you will have to rename some of the functions.

I notice that sourceforce says there is activity on the project in 2005 but the last release was January 12, 2003.

I recommend that you use this not so friendly PHP extention if available. However this sourceforce project is still a good idea if you don't control which extenions are be available on the server.

http://phpxmlrpc.sourceforge.net/
rdude at fuzzelfish dot com
14-Mar-2005 04:57
An easier alternative to the built-in XML-RPC function is available at:
http://phpxmlrpc.sourceforge.net/

PHP XML-RPC is written purely in PHP, so there is no need to recompile to use the experiment XML-RPC extension. PHP XML-RPC is also definitely easier to use, especially if you are creating a server. Documentation is available at the above link.
Jerome Delamarche
14-Oct-2004 05:58
The documentation lacks an example that shows how to send a fault in a response. Here is how to do it:

$args = array("faultCode" => $errcode, "faultString" => $errmsg);
$resp = xmlrpc_encode_request(NULL,$args);
//echo $resp;
php at hendrik-krauss dot de
14-Aug-2004 03:38
On "datetime" values:

If you implement an XML-RPC server with these functions and a client calls a method on your server, sending a datetime as parameter (in ISO 8601 format, as specified at http://www.xmlrpc.com/spec), the PHP XML-RPC will pass your registered server method an object as parameter. That object, for example, looks like:
obj->type="datetime"
obj->scalar="20040420T13:32:40"
obj->timestamp=1082460760

If you do xmlrpc_get_type(obj), it will return "datetime", so presumably that function just returns the value of 'type'. 'scalar' seems to be the on-the-wire representation of the datetime (ISO 8601, exactly as received). 'timestamp' appears to be the ISO value in 'scalar' converted into a normal PHP timestamp (i.e. Unix time_t).

Note on 'scalar': Using a MySQL DB, we did something like  "select blah where start_time >= $obj->scalar ;". That actually worked and returned expected results, so MySQL appears to handle that ISO 8601 format correctly.
swunderlin at REMOVE-telemedia dot ch
09-Jun-2004 06:20
pear hs an XML_RPC package, if you can't recompile your php:
http://pear.php.net/package/XML_RPC
steph at zend dot com
08-Jun-2004 07:04
It took me a while to get a client together without external libraries.  This very basic client/server pair works on my home set-up - hopefully it will save the next xml-rpc virgin some grief.

/* clienttest.php */
<?php
function do_call($host, $port, $request) {
  
  
$fp = fsockopen($host, $port, $errno, $errstr);
  
$query = "POST /home/servertest.php HTTP/1.0\nUser_Agent: My Egg Client\nHost: ".$host."\nContent-Type: text/xml\nContent-Length: ".strlen($request)."\n\n".$request."\n";

   if (!
fputs($fp, $query, strlen($query))) {
      
$errstr = "Write error";
       return
0;
   }

  
$contents = '';
   while (!
feof($fp)) {
      
$contents .= fgets($fp);
   }

  
fclose($fp);
   return
$contents;
}

$host = 'localhost';
$port = 80;
$request = xmlrpc_encode_request('cycle', 'egg');
$response = do_call($host, $port, $request);
/* do something with $response, e.g. print it */
?>

/* servertest.php */
<?php
function lifecycle($method, $params) {
/* $method = 'cycle', $params = (array of) request parameter(s); $data is also passed from xmlrpc_server_call_method, if we had any data to pass */
  
switch($params[0]) {
       case
'egg':
          
$reply = 'All eggs will be birds one day.';
       break;
       default:
          
$reply = 'That must have been an otheregg';
   }
   return
$reply;
}

$server = xmlrpc_server_create();

/* register the 'external' name and then the 'internal' name */
xmlrpc_server_register_method($server, "cycle", "lifecycle");

$request = $HTTP_RAW_POST_DATA; // no you don't need 'always on', and no $_POST doesn't work.

/* the parameters here are 'server, xml-string and user data'.  There's supposed to be an optional 'output options' array too, but I can't get it working :( hence header() call */
$response = xmlrpc_server_call_method($server, $request, null);
header('Content-Type: text/xml');
print
$response;

xmlrpc_server_destroy($server);
?>
mboeren at php dot net
25-Feb-2004 08:34
Just a quick addition to my previous xmlrpc_client class: since you cannot use remote methods containing capital letters or methods from subhandlers (like 'system.listMethods()'), I added a 'call(...)' method to the class.

<?php
  
// this method should be copy/pasted in the
   // xmlrpc_client class

  
function call($function)
   {
      
$return = NULL;
      
$argv = func_get_args();
      
array_shift($argv); // remove function argument
      
$this->__call($function, $argv, &$return);
       return
$return;
   }

  
// now, you can also do
  
$result = $client->call('system.listMethods');
  
$sum = client->call('add', '1', '2');
?>
mboeren at php dot net
24-Feb-2004 11:01
I use the following code (requires the overload extension) to make developing clients easier:

<?php
include("utils/utils.php"); // from xmlrpc-epi utils

/*
Usage:
   $client = new xmlrpc_client("http://localhost:7080");
   print $client->echo('x')."\n";
   print $client->add(1, 3)."\n";

*/
class xmlrpc_client
{
   var
$url;
   var
$urlparts;

   function
xmlrpc_client($url)
   {
      
$this->url = $url;
      
$this->urlparts = parse_url($this->url);
       foreach(array(
'scheme', 'host', 'user', 'pass', 'path',
                    
'query', 'fragment')
               as
$part) {
           if (!isset(
$this->urlparts[$part])) {
              
$this->urlparts[$part] = NULL;
               }
           }
   }

   function
__call($function, $arguments, &$return)
   {
      
$requestprms['host'] = $this->urlparts['host'];
      
$requestprms['port'] = $this->urlparts['port'];
      
$requestprms['uri'] = $this->urlparts['path'];
      
$requestprms['method'] = $function;
      
$requestprms['args'] = $arguments;
      
$requestprms['debug'] = 0;
      
$requestprms['timeout'] = 0;
      
$requestprms['user'] = NULL;
      
$requestprms['pass'] = NULL;
      
$requestprms['secure'] = 0;

      
$result = xu_rpc_http_concise($requestprms);
       if (
is_array($result) && isset($result['faultCode'])) {
           print(
'Error in xmlrpc call \''.$function.'\''."\n");
           print(
'  code  : '.$result['faultCode']."\n");
           print(
'  message: '.$result['faultString']."\n");
           return
false;
           }
      
$return = $result;
       return
true;
   }

}
overload('xmlrpc_client');

?>
Frank
22-Jan-2004 02:32
here's how to install it on windows (so it actually works):

- php.ini > enable "php_xmlrpc.dll" in extensions.
- php.ini > make sure "extension_dir" is set correctly to find the dll in your php installation dir /extensions.
- copy iconv.dll from your php install dir /dlls to a directory in your path (ex: c:/windows).

if you got some errors while launching apache prior to trying this I suggest you reboot your machine first... sounds weird I know, but remember... you're running Windowz.
Have fun
sjtirtha at gmx dot de
22-Aug-2003 01:23
To install xml-rpc feature on Windows, you need to have "php_xmlrpc.dll" on your "/extensions" Folder.
And you need to enable it on "php.ini".

You need also library from http://xmlrpc-epi.sourceforge.net .
to make your code simply.

Look the examples at http://www.devshed.com/Server_Side/PHP/XMLRPCwithPHP/page1.html .
mistcat attyatatat phreaker dootttt net
18-Apr-2003 06:52
Hope this saves somone some frustration:
As of php 4.3.1 and xmlrpc-epi-php-0.51 php would return a content type text/html instead of text/xml in its responses.  this is a bad thing.  Perl's XMLRPC::Lite for instance will not like you if you do this.  Happily the solution is simple:

header("Content-Type: text/xml");

Happy Hunting.

-Nate
daniel(at)lorch.cc
25-Mar-2003 09:21
If you need a tutorial on the XML-RPC-Extension go to devshed:

  http://www.devshed.com/Server_Side/PHP/XMLRPCwithPHP/page1.html
bmichael at goldparrot dot com
09-Feb-2003 01:52
If anyone is interested in making XMLRPC requests directly from the client, I have been able to get xmlrpc to
work with vcXMLRPC javascript backend.

After about 1 week of scanning the market, I found this solution to be the best on Javascript back end.  It uses the Microsoft.HTTP activeX control for IE, or HTTPRequest Object for Mozilla.

You include vc(Virtual Cowboys) vcXMLRPC.js file into your pages and make the rpc calls from with javascript to create the requests.

It works both ways.

Two Notes:

I have tested it on IE 6.02 and you need to change lines in ProcessRequest :
function to read:

  dom = this.getObject("XMLDOM",http.responseText);

and change the getObject function to use the latest ActiveX Control:

 MSXML2.XMLHTTP.3.0  (or 4.0)
 MSXML2.DOMDocument.3.0  (or 4.0)

The controls are found on MSDN in the Web Services -> XML area.

As another note, you DO NOT NEED the rpcproxy.cgi script to use this.  That is a proxy script to get around JS Security.  You can use PHP to build the proxy.  But, I was able to get the CGI working with GCC compiler on Solaris (change the -KPCI, depend and -x03 optimizer settings in the Makefile )
roland at php dot net
29-Jan-2003 06:15
You can find a good howto about the xml-rpc extension at

http://www.devshed.com/Server_Side/PHP/XMLRPCwithPHP/page1.html

It's an easy client / server example - works quite good :-)
nospam at phppatterns dot com
07-Dec-2002 09:45
Note that you do need the iconv module installed to use the XML-RPC extension (see: http://www.php.net/manual/en/ref.iconv.php)
hfuecks at pinkgoblin dot com
26-Sep-2002 09:34
You can pass PHP errors with the XML-RPC extension as described here: http://www.zend.com/lists/php-dev/200107/msg00642.html
steve at orangeNOSPAMimagineering dot com
25-Aug-2002 04:32
There's a handy library by Keith Devens (version 2.2.1) at
http://www.keithdevens.com/software/xmlrpc/

Here is a sample client. It remotely calls sample.sumAndDifference
with two parameters (3 and 5).
It returns:

sum => 8
difference => -2

<?php
include ("kd_xmlrpc.php");
// define("XMLRPC_DEBUG", 0);    // Set to 1 for handy debugging

$method = "sample.sumAndDifference";
$params = XMLRPC_prepare(array(3,5));

$site = "xmlrpc-c.sourceforge.net";
$location = "/api/sample.php";

list(
$success, $result) = XMLRPC_request( $site, $location, $method, $params );

// XMLRPC_debug_print();    // uncomment for debugging

foreach ( $result as $key => $value ) {
         echo(
" $key => $value \n");
}

?>
hfuecks at pinkgoblin dot com
15-Aug-2002 11:32
This extension does not handle the process of making making XML-RPC client requests via HTTP; it only prepares the XML-RPC request payload.

This differs from many other XML-RPC implementations but offers greater flexibility, allowing SSL connections, authentication headers and XML-RPC via other transports like SMTP.
hfuecks at pinkgoblin dot com
29-Jul-2002 04:33
Anyone interested in PHP-GTK talking to an XML-RPC server:

http://www.pinkgoblin.com/gtk2xmlrpc.php
ivanr at webkreator dot com
22-Jun-2002 02:50
For a really easy way to use this XML-RPC extension take a look at

XML-RPC Class Server (http://www.webkreator.com/php/xcs/)

It automatically creates servers out of PHP classes. Creating clients is almost as easy, especially with the recent addition of the overload extension to PHP (see http://www.php.net/manual/en/ref.overload.php).
nic at uklinux dot NOSPAM dot net
25-Apr-2002 12:05
An alternative XML-RPC implementation is available at http://xmlrpc.usefulinc.com - it's written in PHP so you can use it on servers for which you don't have the luxury of rebuilding PHP on.

nic
cmv at php dot net
08-Jan-2002 09:26
"Latest releases" is a bit redundant, since this extension is bundled into PHP (as of 4.1.0).  You don't need to download anything from sourceforge to make this work.  Just compile PHP with the --with-xmlrpc flag.

The site http://xmlrpc-epi.sourceforge.net/ is useful, however, for documentation.
ravan_n at hotmail dot com
27-Dec-2001 07:01
Refer to the below link for documentation / latest releases of the package.

http://xmlrpc-epi.sourceforge.net/main.php?t=php_about