xml-rpc远程调用

从网上找来的XML-RPC库,对于开发小型的外部通讯接口很有用,把这个代码保存为xml-rpc.inc.php
  1. <?php
  2. /*
  3. 从网上找来的XML-RPC库,对于开发小型的外部通讯接口很有用
  4. */
  5. function & XML_serialize($data$level = 0, $prior_key = NULL){
  6.     #assumes a hash, keys are the variable names
  7.     $xml_serialized_string = "";
  8.     while(list($key$value) = each($data)){
  9.         $inline = false;
  10.         $numeric_array = false;
  11.         $attributes = "";
  12.         #echo "My current key is '$key', called with prior key '$prior_key'<br>";
  13.         if(!strstr($key" attr")){ #if it's not an attribute
  14.             if(array_key_exists("$key attr"$data)){
  15.                 while(list($attr_name$attr_value) = each($data["$key attr"])){
  16.                     #echo "Found attribute $attribute_name with value $attribute_value<br>";
  17.                     $attr_value = &htmlspecialchars($attr_value, ENT_QUOTES);
  18.                     $attributes .= " $attr_name=/"$attr_value/"";
  19.                 }
  20.             }
  21.             if(is_numeric($key)){
  22.                 #echo "My current key ($key) is numeric. My parent key is '$prior_key'<br>";
  23.                 $key = $prior_key;
  24.             }else{
  25.                 #you can't have numeric keys at two levels in a row, so this is ok
  26.                 #echo "Checking to see if a numeric key exists in data.";
  27.                 if(is_array($valueand array_key_exists(0, $value)){
  28.                 #   echo " It does! Calling myself as a result of a numeric array.<br>";
  29.                     $numeric_array = true;
  30.                     $xml_serialized_string .= XML_serialize($value$level$key);
  31.                 }
  32.                 #echo "<br>";
  33.             }
  34.             if(!$numeric_array){
  35.                 $xml_serialized_string .= str_repeat("/t"$level) . "<$key$attributes>";
  36.                 if(is_array($value)){
  37.                     $xml_serialized_string .= "/r/n" . XML_serialize($value$level+1);
  38.                 }else{
  39.                     $inline = true;
  40.                     $xml_serialized_string .= htmlspecialchars($value);
  41.                 }
  42.                 $xml_serialized_string .= (!$inline ? str_repeat("/t"$level) : "") . "</$key>/r/n";
  43.             }
  44.         }else{
  45.             #echo "Skipping attribute record for key $key<bR>";
  46.         }
  47.     }
  48.     if($level == 0){
  49.         $xml_serialized_string = "<?xml version=/"1.0/" ?>/r/n" . $xml_serialized_string;
  50.         return $xml_serialized_string;
  51.     }else{
  52.         return $xml_serialized_string;
  53.     }
  54. }
  55. class XML {
  56.     var $parser; #a reference to the XML parser
  57.     var $document; #the entire XML structure built up so far
  58.     var $current; #a pointer to the current item - what is this
  59.     var $parent; #a pointer to the current parent - the parent will be an array
  60.     var $parents; #an array of the most recent parent at each level
  61.     var $last_opened_tag;
  62.     function XML($data=null){
  63.         $this->parser = xml_parser_create();
  64.         xml_parser_set_option ($this->parser, XML_OPTION_CASE_FOLDING, 0);
  65.         xml_set_object($this->parser, $this);
  66.         xml_set_element_handler($this->parser, "open""close");
  67.         xml_set_character_data_handler($this->parser, "data");
  68. #       register_shutdown_function(array($this'destruct'));
  69.     }
  70.     function destruct(){
  71.         xml_parser_free($this->parser);
  72.     }
  73.     function parse($data){
  74.         $this->document = array();
  75.         $this->parent = $this->document;
  76.         $this->parents = array();
  77.         $this->last_opened_tag = NULL;
  78.         xml_parse($this->parser, $data);
  79.         return $this->document;
  80.     }
  81.     function open($parser$tag$attributes){
  82.         #echo "Opening tag $tag<br>/n";
  83.         $this->data = "";
  84.         $this->last_opened_tag = $tag; #tag is a string
  85.         if(array_key_exists($tag$this->parent)){
  86.             #echo "There's already an instance of '$tag' at the current level ($level)<br>/n";
  87.             if(is_array($this->parent[$tag]) and array_key_exists(0, $this->parent[$tag])){ #if the keys are numeric
  88.                 #need to make sure they're numeric (account for attributes)
  89.                 $key = count_numeric_items($this->parent[$tag]);
  90.                 #echo "There are $key instances: the keys are numeric.<br>/n";
  91.             }else{
  92.                 #echo "There is only one instance. Shifting everything around<br>/n";
  93.                 $temp = $this->parent[$tag];
  94.                 unset($this->parent[$tag]);
  95.                 $this->parent[$tag][0] = $temp;
  96.                 if(array_key_exists("$tag attr"$this->parent)){
  97.                     #shift the attributes around too if they exist
  98.                     $temp = $this->parent["$tag attr"];
  99.                     unset($this->parent["$tag attr"]);
  100.                     $this->parent[$tag]["0 attr"] = $temp;
  101.                 }
  102.                 $key = 1;
  103.             }
  104.             $this->parent = $this->parent[$tag];
  105.         }else{
  106.             $key = $tag;
  107.         }
  108.         if($attributes){
  109.             $this->parent["$key attr"] = $attributes;
  110.         }
  111.         $this->parent[$key] = array();
  112.         $this->parent = $this->parent[$key];
  113.         array_unshift($this->parents, $this->parent);
  114.     }
  115.     function data($parser$data){
  116.         #echo "Data is '", htmlspecialchars($data), "'<br>/n";
  117.         if($this->last_opened_tag != NULL){
  118.             $this->data .= $data;
  119.         }
  120.     }
  121.     function close($parser$tag){
  122.         #echo "Close tag $tag<br>/n";
  123.         if($this->last_opened_tag == $tag){
  124.             $this->parent = $this->data;
  125.             $this->last_opened_tag = NULL;
  126.         }
  127.         array_shift($this->parents);
  128.         $this->parent = $this->parents[0];
  129.     }
  130. }
  131. function & XML_unserialize($xml){
  132.     $xml_parser = new XML();
  133.     $data = $xml_parser->parse($xml);
  134.     $xml_parser->destruct();
  135.     return $data;
  136. }
  137. function & XMLRPC_parse($request){
  138.     if(defined('XMLRPC_DEBUG'and XMLRPC_DEBUG){
  139.         XMLRPC_debug('XMLRPC_parse'"<p>Received the following raw request:</p>" . XMLRPC_show($request'print_r', true));
  140.     }
  141.     $data = &XML_unserialize($request);
  142.     if(defined('XMLRPC_DEBUG'and XMLRPC_DEBUG){
  143.         XMLRPC_debug('XMLRPC_parse'"<p>Returning the following parsed request:</p>" . XMLRPC_show($data'print_r', true));
  144.     }
  145.     return $data;
  146. }
  147. function & XMLRPC_prepare($data$type = NULL){
  148.     if(is_array($data)){
  149.         $num_elements = count($data);
  150.         if((array_key_exists(0, $dataor !$num_elementsand $type != 'struct'){ #it's an array
  151.             if(!$num_elements){ #if the array is emptyempty
  152.                 $returnvalue =  array('array' => array('data' => NULL));
  153.             }else{
  154.                 $returnvalue['array']['data']['value'] = array();
  155.                 $temp = $returnvalue['array']['data']['value'];
  156.                 $count = count_numeric_items($data);
  157.                 for($n=0; $n<$count$n++){
  158.                     $type = NULL;
  159.                     if(array_key_exists("$n type"$data)){
  160.                         $type = $data["$n type"];
  161.                     }
  162.                     $temp[$n] = XMLRPC_prepare($data[$n], $type);
  163.                 }
  164.             }
  165.         }else{ #it's a struct
  166.             if(!$num_elements){ #if the struct is emptyempty
  167.                 $returnvalue = array('struct' => NULL);
  168.             }else{
  169.                 $returnvalue['struct']['member'] = array();
  170.                 $temp = $returnvalue['struct']['member'];
  171.                 while(list($key$value) = each($data)){
  172.                     if(substr($key, -5) != ' type'){ #if it's not a type specifier
  173.                         $type = NULL;
  174.                         if(array_key_exists("$key type"$data)){
  175.                             $type = $data["$key type"];
  176.                         }
  177.                         $temp[] = array('name' => $key'value' => XMLRPC_prepare($value$type));
  178.                     }
  179.                 }
  180.             }
  181.         }
  182.     }else{ #it's a scalar
  183.         if(!$type){
  184.             if(is_int($data)){
  185.                 $returnvalue['int'] = $data;
  186.                 return $returnvalue;
  187.             }elseif(is_float($data)){
  188.                 $returnvalue['double'] = $data;
  189.                 return $returnvalue;
  190.             }elseif(is_bool($data)){
  191.                 $returnvalue['boolean'] = ($data ? 1 : 0);
  192.                 return $returnvalue;
  193.             }elseif(preg_match('/^/d{8}T/d{2}:/d{2}:/d{2}$/'$data$matches)){ #it's a date
  194.                 $returnvalue['dateTime.iso8601'] = $data;
  195.                 return $returnvalue;
  196.             }elseif(is_string($data)){
  197.                 $returnvalue['string'] = htmlspecialchars($data);
  198.                 return $returnvalue;
  199.             }
  200.         }else{
  201.             $returnvalue[$type] = htmlspecialchars($data);
  202.         }
  203.     }
  204.     return $returnvalue;
  205. }
  206. function & XMLRPC_adjustValue($current_node){
  207.     if(is_array($current_node)){
  208.         if(isset($current_node['array'])){
  209.             if(!is_array($current_node['array']['data'])){
  210.                 #If there are no elements, return an emptyempty array
  211.                 return array();
  212.             }else{
  213.                 #echo "Getting rid of array -> data -> value<br>/n";
  214.                 $temp = $current_node['array']['data']['value'];
  215.                 if(is_array($tempand array_key_exists(0, $temp)){
  216.                     $count = count($temp);
  217.                     for($n=0;$n<$count;$n++){
  218.                         $temp2[$n] = &XMLRPC_adjustValue($temp[$n]);
  219.                     }
  220.                     $temp = $temp2;
  221.                 }else{
  222.                     $temp2 = &XMLRPC_adjustValue($temp);
  223.                     $temp = array($temp2);
  224.                     #I do the temp assignment because it avoids copying,
  225.                     # since I can put a reference in the array
  226.                     #PHP's reference model is a bit silly, and I can't just say:
  227.                     # $temp = array(&XMLRPC_adjustValue($temp));
  228.                 }
  229.             }
  230.         }elseif(isset($current_node['struct'])){
  231.             if(!is_array($current_node['struct'])){
  232.                 #If there are no members, return an emptyempty array
  233.                 return array();
  234.             }else{
  235.                 #echo "Getting rid of struct -> member<br>/n";
  236.                 $temp = $current_node['struct']['member'];
  237.                 if(is_array($tempand array_key_exists(0, $temp)){
  238.                     $count = count($temp);
  239.                     for($n=0;$n<$count;$n++){
  240.                         #echo "Passing name {$temp[$n][name]}. Value is: " . show($temp[$n][value], var_dump, true) . "<br>/n";
  241.                         $temp2[$temp[$n]['name']] = &XMLRPC_adjustValue($temp[$n]['value']);
  242.                         #echo "adjustValue(): After assigning, the value is " . show($temp2[$temp[$n]['name']], var_dump, true) . "<br>/n";
  243.                     }
  244.                 }else{
  245.                     #echo "Passing name $temp[name]<br>/n";
  246.                     $temp2[$temp['name']] = &XMLRPC_adjustValue($temp['value']);
  247.                 }
  248.                 $temp = $temp2;
  249.             }
  250.         }else{
  251.             $types = array('string''int''i4''double''dateTime.iso8601''base64''boolean');
  252.             $fell_through = true;
  253.             foreach($types as $type){
  254.                 if(array_key_exists($type$current_node)){
  255.                     #echo "Getting rid of '$type'<br>/n";
  256.                     $temp = $current_node[$type];
  257.                     #echo "adjustValue(): The current node is set with a type of $type<br>/n";
  258.                     $fell_through = false;
  259.                     break;
  260.                 }
  261.             }
  262.             if($fell_through){
  263.                 $type = 'string';
  264.                 #echo "Fell through! Type is $type<br>/n";
  265.             }
  266.             switch ($type){
  267.                 case 'int'case 'i4'$temp = (int)$temp;    break;
  268.                 case 'string':         $temp = (string)$tempbreak;
  269.                 case 'double':         $temp = (double)$tempbreak;
  270.                 case 'boolean':        $temp = (bool)$temp;   break;
  271.             }
  272.         }
  273.     }else{
  274.         $temp = (string)$current_node;
  275.     }
  276.     return $temp;
  277. }
  278. function XMLRPC_getParams($request){
  279.     if(!is_array($request['methodCall']['params'])){
  280.         #If there are no parameters, return an emptyempty array
  281.         return array();
  282.     }else{
  283.         #echo "Getting rid of methodCall -> params -> param<br>/n";
  284.         $temp = $request['methodCall']['params']['param'];
  285.         if(is_array($tempand array_key_exists(0, $temp)){
  286.             $count = count($temp);
  287.             for($n = 0; $n < $count$n++){
  288.                 #echo "Serializing parameter $n<br>";
  289.                 $temp2[$n] = &XMLRPC_adjustValue($temp[$n]['value']);
  290.             }
  291.         }else{
  292.             $temp2[0] = &XMLRPC_adjustValue($temp['value']);
  293.         }
  294.         $temp = $temp2;
  295.         return $temp;
  296.     }
  297. }
  298. function XMLRPC_getMethodName($methodCall){
  299.     #returns the method name
  300.     return $methodCall['methodCall']['methodName'];
  301. }
  302. function XMLRPC_request($site$location$methodName$params = NULL, $user_agent = NULL){
  303.     $site = explode(':'$site);
  304.     if(isset($site[1]) and is_numeric($site[1])){
  305.         $port = $site[1];
  306.     }else{
  307.         $port = 80;
  308.     }
  309.     $site = $site[0];
  310.     $data["methodCall"]["methodName"] = $methodName;
  311.     $param_count = count($params);
  312.     if(!$param_count){
  313.         $data["methodCall"]["params"] = NULL;
  314.     }else{
  315.         for($n = 0; $n<$param_count$n++){
  316.             $data["methodCall"]["params"]["param"][$n]["value"] = $params[$n];
  317.         }
  318.     }
  319.     $data = XML_serialize($data);
  320.     if(defined('XMLRPC_DEBUG'and XMLRPC_DEBUG){
  321.         XMLRPC_debug('XMLRPC_request'"<p>Received the following parameter list to send:</p>" . XMLRPC_show($params'print_r', true));
  322.     }
  323.     $conn = fsockopen ($site$port); #open the connection
  324.     if(!$conn){ #if the connection was not opened successfully
  325.         if(defined('XMLRPC_DEBUG'and XMLRPC_DEBUG){
  326.             XMLRPC_debug('XMLRPC_request'"<p>Connection failed: Couldn't make the connection to $site.</p>");
  327.         }
  328.         return array(false, array('faultCode'=>10532, 'faultString'=>"Connection failed: Couldn't make the connection to $site."));
  329.     }else{
  330.         $headers =
  331.             "POST $location HTTP/1.0/r/n" .
  332.             "Host: $site/r/n" .
  333.             "Connection: close/r/n" .
  334.             ($user_agent ? "User-Agent: $user_agent/r/n" : '') .
  335.             "Content-Type: text/xml/r/n" .
  336.             "Content-Length: " . strlen($data) . "/r/n/r/n";
  337.         fputs($conn"$headers");
  338.         fputs($conn$data);
  339.         if(defined('XMLRPC_DEBUG'and XMLRPC_DEBUG){
  340.             XMLRPC_debug('XMLRPC_request'"<p>Sent the following request:</p>/n/n" . XMLRPC_show($headers . $data'print_r', true));
  341.         }
  342.         #socket_set_blocking ($conn, false);
  343.         $response = "";
  344.         while(!feof($conn)){
  345.             $response .= fgets($conn, 1024);
  346.         }
  347.         fclose($conn);
  348.         #strip headers off of response
  349.         $data = XML_unserialize(substr($responsestrpos($response"/r/n/r/n")+4));
  350.         if(defined('XMLRPC_DEBUG'and XMLRPC_DEBUG){
  351.             XMLRPC_debug('XMLRPC_request'"<p>Received the following response:</p>/n/n" . XMLRPC_show($response'print_r', true) . "<p>Which was serialized into the following data:</p>/n/n" . XMLRPC_show($data'print_r', true));
  352.         }
  353.         if(isset($data['methodResponse']['fault'])){
  354.             $return =  array(false, XMLRPC_adjustValue($data['methodResponse']['fault']['value']));
  355.             if(defined('XMLRPC_DEBUG'and XMLRPC_DEBUG){
  356.                 XMLRPC_debug('XMLRPC_request'"<p>Returning:</p>/n/n" . XMLRPC_show($return'var_dump', true));
  357.             }
  358.             return $return;
  359.         }else{
  360.             $return = array(true, XMLRPC_adjustValue($data['methodResponse']['params']['param']['value']));
  361.             if(defined('XMLRPC_DEBUG'and XMLRPC_DEBUG){
  362.                 XMLRPC_debug('XMLRPC_request'"<p>Returning:</p>/n/n" . XMLRPC_show($return'var_dump', true));
  363.             }
  364.             return $return;
  365.         }
  366.     }
  367. }
  368. function XMLRPC_response($return_value$server = NULL){
  369.     $data["methodResponse"]["params"]["param"]["value"] = $return_value;
  370.     $return = XML_serialize($data);
  371.     if(defined('XMLRPC_DEBUG'and XMLRPC_DEBUG){
  372.         XMLRPC_debug('XMLRPC_response'"<p>Received the following data to return:</p>/n/n" . XMLRPC_show($return_value'print_r', true));
  373.     }
  374.     header("Connection: close");
  375.     header("Content-Length: " . strlen($return));
  376.     header("Content-Type: text/xml");
  377.     header("Date: " . date("r"));
  378.     if($server){
  379.         header("Server: $server");
  380.     }
  381.     if(defined('XMLRPC_DEBUG'and XMLRPC_DEBUG){
  382.         XMLRPC_debug('XMLRPC_response'"<p>Sent the following response:</p>/n/n" . XMLRPC_show($return'print_r', true));
  383.     }
  384.     echo $return;
  385. }
  386. function XMLRPC_error($faultCode$faultString$server = NULL){
  387.     $array["methodResponse"]["fault"]["value"]["struct"]["member"] = array();
  388.     $temp = $array["methodResponse"]["fault"]["value"]["struct"]["member"];
  389.     $temp[0]["name"] = "faultCode";
  390.     $temp[0]["value"]["int"] = $faultCode;
  391.     $temp[1]["name"] = "faultString";
  392.     $temp[1]["value"]["string"] = $faultString;
  393.     $return = XML_serialize($array);
  394.     header("Connection: close");
  395.     header("Content-Length: " . strlen($return));
  396.     header("Content-Type: text/xml");
  397.     header("Date: " . date("r"));
  398.     if($server){
  399.         header("Server: $server");
  400.     }
  401.     if(defined('XMLRPC_DEBUG'and XMLRPC_DEBUG){
  402.         XMLRPC_debug('XMLRPC_error'"<p>Sent the following error response:</p>/n/n" . XMLRPC_show($return'print_r', true));
  403.     }
  404.     echo $return;
  405. }
  406. function XMLRPC_convert_timestamp_to_iso8601($timestamp){
  407.     #takes a unix timestamp and converts it to iso8601 required by XMLRPC
  408.     #an example iso8601 datetime is "20010822T03:14:33"
  409.     return date("Ymd/TH:i:s"$timestamp);
  410. }
  411. function XMLRPC_convert_iso8601_to_timestamp($iso8601){
  412.     return strtotime($iso8601);
  413. }
  414. function count_numeric_items($array){
  415.     return is_array($array) ? count(array_filter(array_keys($array), 'is_numeric')) : 0;
  416. }
  417. function XMLRPC_debug($function_name$debug_message){
  418.     $GLOBALS['XMLRPC_DEBUG_INFO'][] = array($function_name$debug_message);
  419. }
  420. function XMLRPC_debug_print(){
  421.     if($GLOBALS['XMLRPC_DEBUG_INFO']){
  422.         echo "<table border=/"1/" width=/"100%/">/n";
  423.         foreach($GLOBALS['XMLRPC_DEBUG_INFO'as $debug){
  424.             echo "<tr><th style=/"vertical-align: top/">$debug[0]</th><td>$debug[1]</td></tr>/n";
  425.         }
  426.         echo "</table>/n";
  427.         unset($GLOBALS['XMLRPC_DEBUG_INFO']);
  428.     }else{
  429.         echo "<p>No debugging information available yet.</p>";
  430.     }
  431. }
  432. function XMLRPC_show($data$func = "print_r"$return_str = false){
  433.     ob_start();
  434.     $func($data);
  435.     $output = ob_get_contents();
  436.     ob_end_clean();
  437.     if($return_str){
  438.         return "<pre>" . htmlspecialchars($output) . "</pre>/n";
  439.     }else{
  440.         echo "<pre>", htmlspecialchars($output), "</pre>/n";
  441.     }
  442. }
  443. ?>

服务端程序例子,server.php

  1. <?
  2. include 'xml-rpc.inc.php';
  3. //定义可被远程调用的方法
  4. $xmlrpc_methods=array();
  5. $xmlrpc_methods['insertRecords']='insertRecords';
  6. //获得用户传入的方法名和参数
  7. $xmlrpc_request = XMLRPC_parse($HTTP_RAW_POST_DATA); 
  8. $methodName = XMLRPC_getMethodName($xmlrpc_request); 
  9. $params = XMLRPC_getParams($xmlrpc_request); 
  10. if (!isset($xmlrpc_methods[$methodName])){
  11.     XMLRPC_error('1',"你所调用的方法不存在");
  12. }else {
  13.     $xmlrpc_methods[$methodName]($params);
  14. }
  15. function insertRecords($params){
  16.     if (emptyempty($params)){
  17.         XMLRPC_error('2',"参数出错");
  18.     }
  19.     XMLRPC_response(XMLRPC_prepare('http://www.emtit.com'));
  20. }
  21. ?>

PHP客户端调用服务端方法例子

  1. <?php
  2. include_once 'xml-rpc.inc';
  3. $params=array(2,3);
  4. $result=XMLRPC_request("127.0.0.1","/services/server.php","insertRecords",$params);//服务端文件放在services文件夹下
  5. print_r($result);
  6. ?>

结果会显示www.emtiit.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值