首页 php教程 php手册 php xml-rpc远程调用

php xml-rpc远程调用

Jun 13, 2016 pm 12:24 PM
php xml-rpc 代码 复制 开发 调用 远程

复制代码 代码如下:


/*
从网上找来的XML-RPC库,对于开发小型的外部通讯接口很有用
*/

function & XML_serialize($data, $level = 0, $prior_key = NULL){
#assumes a hash, keys are the variable names
$xml_serialized_string = "";
while(list($key, $value) = each($data)){
$inline = false;
$numeric_array = false;
$attributes = "";
#echo "My current key is '$key', called with prior key '$prior_key'
";
if(!strstr($key, " attr")){ #if it's not an attribute
if(array_key_exists("$key attr", $data)){
while(list($attr_name, $attr_value) = each($data["$key attr"])){
#echo "Found attribute $attribute_name with value $attribute_value
";
$attr_value = &htmlspecialchars($attr_value, ENT_QUOTES);
$attributes .= " $attr_name=\"$attr_value\"";
}
}

if(is_numeric($key)){
#echo "My current key ($key) is numeric. My parent key is '$prior_key'
";
$key = $prior_key;
}else{
#you can't have numeric keys at two levels in a row, so this is ok
#echo "Checking to see if a numeric key exists in data.";
if(is_array($value) and array_key_exists(0, $value)){
# echo " It does! Calling myself as a result of a numeric array.
";
$numeric_array = true;
$xml_serialized_string .= XML_serialize($value, $level, $key);
}
#echo "
";
}

if(!$numeric_array){
$xml_serialized_string .= str_repeat("\t", $level) . "";

if(is_array($value)){
$xml_serialized_string .= "\r\n" . XML_serialize($value, $level+1);
}else{
$inline = true;
$xml_serialized_string .= htmlspecialchars($value);
}

$xml_serialized_string .= (!$inline ? str_repeat("\t", $level) : "") . "$key>\r\n";
}
}else{
#echo "Skipping attribute record for key $key
";
}
}
if($level == 0){
$xml_serialized_string = "\r\n" . $xml_serialized_string;
return $xml_serialized_string;
}else{
return $xml_serialized_string;
}
}

class XML {
var $parser; #a reference to the XML parser
var $document; #the entire XML structure built up so far
var $current; #a pointer to the current item - what is this
var $parent; #a pointer to the current parent - the parent will be an array
var $parents; #an array of the most recent parent at each level

var $last_opened_tag;

function XML($data=null){
$this->parser = xml_parser_create();

xml_parser_set_option ($this->parser, XML_OPTION_CASE_FOLDING, 0);
xml_set_object($this->parser, $this);
xml_set_element_handler($this->parser, "open", "close");
xml_set_character_data_handler($this->parser, "data");
# register_shutdown_function(array($this, 'destruct'));
}

function destruct(){
xml_parser_free($this->parser);
}

function parse($data){
$this->document = array();
$this->parent = $this->document;
$this->parents = array();
$this->last_opened_tag = NULL;
xml_parse($this->parser, $data);
return $this->document;
}

function open($parser, $tag, $attributes){
#echo "Opening tag $tag
\n";
$this->data = "";
$this->last_opened_tag = $tag; #tag is a string
if(array_key_exists($tag, $this->parent)){
#echo "There's already an instance of '$tag' at the current level ($level)
\n";
if(is_array($this->parent[$tag]) and array_key_exists(0, $this->parent[$tag])){ #if the keys are numeric
#need to make sure they're numeric (account for attributes)
$key = count_numeric_items($this->parent[$tag]);
#echo "There are $key instances: the keys are numeric.
\n";
}else{
#echo "There is only one instance. Shifting everything around
\n";
$temp = $this->parent[$tag];
unset($this->parent[$tag]);
$this->parent[$tag][0] = $temp;

if(array_key_exists("$tag attr", $this->parent)){
#shift the attributes around too if they exist
$temp = $this->parent["$tag attr"];
unset($this->parent["$tag attr"]);
$this->parent[$tag]["0 attr"] = $temp;
}
$key = 1;
}
$this->parent = $this->parent[$tag];
}else{
$key = $tag;
}
if($attributes){
$this->parent["$key attr"] = $attributes;
}

$this->parent[$key] = array();
$this->parent = $this->parent[$key];
array_unshift($this->parents, $this->parent);
}

function data($parser, $data){
#echo "Data is '", htmlspecialchars($data), "'
\n";
if($this->last_opened_tag != NULL){
$this->data .= $data;
}
}

function close($parser, $tag){
#echo "Close tag $tag
\n";
if($this->last_opened_tag == $tag){
$this->parent = $this->data;
$this->last_opened_tag = NULL;
}
array_shift($this->parents);
$this->parent = $this->parents[0];
}
}

function & XML_unserialize($xml){
$xml_parser = new XML();
$data = $xml_parser->parse($xml);
$xml_parser->destruct();
return $data;
}

function & XMLRPC_parse($request){
if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){
XMLRPC_debug('XMLRPC_parse', "

Received the following raw request:

" . XMLRPC_show($request, 'print_r', true));
}
$data = &XML_unserialize($request);
if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){
XMLRPC_debug('XMLRPC_parse', "

Returning the following parsed request:

" . XMLRPC_show($data, 'print_r', true));
}
return $data;
}

function & XMLRPC_prepare($data, $type = NULL){
if(is_array($data)){
$num_elements = count($data);
if((array_key_exists(0, $data) or !$num_elements) and $type != 'struct'){ #it's an array
if(!$num_elements){ #if the array is emptyempty
$returnvalue = array('array' => array('data' => NULL));
}else{
$returnvalue['array']['data']['value'] = array();
$temp = $returnvalue['array']['data']['value'];
$count = count_numeric_items($data);
for($n=0; $n$type = NULL;
if(array_key_exists("$n type", $data)){
$type = $data["$n type"];
}
$temp[$n] = XMLRPC_prepare($data[$n], $type);
}
}
}else{ #it's a struct
if(!$num_elements){ #if the struct is emptyempty
$returnvalue = array('struct' => NULL);
}else{
$returnvalue['struct']['member'] = array();
$temp = $returnvalue['struct']['member'];
while(list($key, $value) = each($data)){
if(substr($key, -5) != ' type'){ #if it's not a type specifier
$type = NULL;
if(array_key_exists("$key type", $data)){
$type = $data["$key type"];
}
$temp[] = array('name' => $key, 'value' => XMLRPC_prepare($value, $type));
}
}
}
}
}else{ #it's a scalar
if(!$type){
if(is_int($data)){
$returnvalue['int'] = $data;
return $returnvalue;
}elseif(is_float($data)){
$returnvalue['double'] = $data;
return $returnvalue;
}elseif(is_bool($data)){
$returnvalue['boolean'] = ($data ? 1 : 0);
return $returnvalue;
}elseif(preg_match('/^\d{8}T\d{2}:\d{2}:\d{2}$/', $data, $matches)){ #it's a date
$returnvalue['dateTime.iso8601'] = $data;
return $returnvalue;
}elseif(is_string($data)){
$returnvalue['string'] = htmlspecialchars($data);
return $returnvalue;
}
}else{
$returnvalue[$type] = htmlspecialchars($data);
}
}
return $returnvalue;
}

function & XMLRPC_adjustValue($current_node){
if(is_array($current_node)){
if(isset($current_node['array'])){
if(!is_array($current_node['array']['data'])){
#If there are no elements, return an emptyempty array
return array();
}else{
#echo "Getting rid of array -> data -> value
\n";
$temp = $current_node['array']['data']['value'];
if(is_array($temp) and array_key_exists(0, $temp)){
$count = count($temp);
for($n=0;$n$temp2[$n] = &XMLRPC_adjustValue($temp[$n]);
}
$temp = $temp2;
}else{
$temp2 = &XMLRPC_adjustValue($temp);
$temp = array($temp2);
#I do the temp assignment because it avoids copying,
# since I can put a reference in the array
#PHP's reference model is a bit silly, and I can't just say:
# $temp = array(&XMLRPC_adjustValue($temp));
}
}
}elseif(isset($current_node['struct'])){
if(!is_array($current_node['struct'])){
#If there are no members, return an emptyempty array
return array();
}else{
#echo "Getting rid of struct -> member
\n";
$temp = $current_node['struct']['member'];
if(is_array($temp) and array_key_exists(0, $temp)){
$count = count($temp);
for($n=0;$n#echo "Passing name {$temp[$n][name]}. Value is: " . show($temp[$n][value], var_dump, true) . "
\n";
$temp2[$temp[$n]['name']] = &XMLRPC_adjustValue($temp[$n]['value']);
#echo "adjustValue(): After assigning, the value is " . show($temp2[$temp[$n]['name']], var_dump, true) . "
\n";
}
}else{
#echo "Passing name $temp[name]
\n";
$temp2[$temp['name']] = &XMLRPC_adjustValue($temp['value']);
}
$temp = $temp2;
}
}else{
$types = array('string', 'int', 'i4', 'double', 'dateTime.iso8601', 'base64', 'boolean');
$fell_through = true;
foreach($types as $type){
if(array_key_exists($type, $current_node)){
#echo "Getting rid of '$type'
\n";
$temp = $current_node[$type];
#echo "adjustValue(): The current node is set with a type of $type
\n";
$fell_through = false;
break;
}
}
if($fell_through){
$type = 'string';
#echo "Fell through! Type is $type
\n";
}
switch ($type){
case 'int': case 'i4': $temp = (int)$temp; break;
case 'string': $temp = (string)$temp; break;
case 'double': $temp = (double)$temp; break;
case 'boolean': $temp = (bool)$temp; break;
}
}
}else{
$temp = (string)$current_node;
}
return $temp;
}

function XMLRPC_getParams($request){
if(!is_array($request['methodCall']['params'])){
#If there are no parameters, return an emptyempty array
return array();
}else{
#echo "Getting rid of methodCall -> params -> param
\n";
$temp = $request['methodCall']['params']['param'];
if(is_array($temp) and array_key_exists(0, $temp)){
$count = count($temp);
for($n = 0; $n #echo "Serializing parameter $n
";
$temp2[$n] = &XMLRPC_adjustValue($temp[$n]['value']);
}
}else{
$temp2[0] = &XMLRPC_adjustValue($temp['value']);
}
$temp = $temp2;
return $temp;
}
}

function XMLRPC_getMethodName($methodCall){
#returns the method name
return $methodCall['methodCall']['methodName'];
}

function XMLRPC_request($site, $location, $methodName, $params = NULL, $user_agent = NULL){
$site = explode(':', $site);
if(isset($site[1]) and is_numeric($site[1])){
$port = $site[1];
}else{
$port = 80;
}
$site = $site[0];

$data["methodCall"]["methodName"] = $methodName;
$param_count = count($params);
if(!$param_count){
$data["methodCall"]["params"] = NULL;
}else{
for($n = 0; $n$data["methodCall"]["params"]["param"][$n]["value"] = $params[$n];
}
}
$data = XML_serialize($data);

if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){
XMLRPC_debug('XMLRPC_request', "

Received the following parameter list to send:

" . XMLRPC_show($params, 'print_r', true));
}
$conn = fsockopen ($site, $port); #open the connection
if(!$conn){ #if the connection was not opened successfully
if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){
XMLRPC_debug('XMLRPC_request', "

Connection failed: Couldn't make the connection to $site.

");
}
return array(false, array('faultCode'=>10532, 'faultString'=>"Connection failed: Couldn't make the connection to $site."));
}else{
$headers =
"POST $location HTTP/1.0\r\n" .
"Host: $site\r\n" .
"Connection: close\r\n" .
($user_agent ? "User-Agent: $user_agent\r\n" : '') .
"Content-Type: text/xml\r\n" .
"Content-Length: " . strlen($data) . "\r\n\r\n";

fputs($conn, "$headers");
fputs($conn, $data);

if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){
XMLRPC_debug('XMLRPC_request', "

Sent the following request:

\n\n" . XMLRPC_show($headers . $data, 'print_r', true));
}

#socket_set_blocking ($conn, false);
$response = "";
while(!feof($conn)){
$response .= fgets($conn, 1024);
}
fclose($conn);

#strip headers off of response
$data = XML_unserialize(substr($response, strpos($response, "\r\n\r\n")+4));

if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){
XMLRPC_debug('XMLRPC_request', "

Received the following response:

\n\n" . XMLRPC_show($response, 'print_r', true) . "

Which was serialized into the following data:

\n\n" . XMLRPC_show($data, 'print_r', true));
}
if(isset($data['methodResponse']['fault'])){
$return = array(false, XMLRPC_adjustValue($data['methodResponse']['fault']['value']));
if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){
XMLRPC_debug('XMLRPC_request', "

Returning:

\n\n" . XMLRPC_show($return, 'var_dump', true));
}
return $return;
}else{
$return = array(true, XMLRPC_adjustValue($data['methodResponse']['params']['param']['value']));
if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){
XMLRPC_debug('XMLRPC_request', "

Returning:

\n\n" . XMLRPC_show($return, 'var_dump', true));
}
return $return;
}
}
}

function XMLRPC_response($return_value, $server = NULL){
$data["methodResponse"]["params"]["param"]["value"] = $return_value;
$return = XML_serialize($data);

if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){
XMLRPC_debug('XMLRPC_response', "

Received the following data to return:

\n\n" . XMLRPC_show($return_value, 'print_r', true));
}

header("Connection: close");
header("Content-Length: " . strlen($return));
header("Content-Type: text/xml");
header("Date: " . date("r"));
if($server){
header("Server: $server");
}

if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){
XMLRPC_debug('XMLRPC_response', "

Sent the following response:

\n\n" . XMLRPC_show($return, 'print_r', true));
}
echo $return;
}

function XMLRPC_error($faultCode, $faultString, $server = NULL){
$array["methodResponse"]["fault"]["value"]["struct"]["member"] = array();
$temp = $array["methodResponse"]["fault"]["value"]["struct"]["member"];
$temp[0]["name"] = "faultCode";
$temp[0]["value"]["int"] = $faultCode;
$temp[1]["name"] = "faultString";
$temp[1]["value"]["string"] = $faultString;

$return = XML_serialize($array);

header("Connection: close");
header("Content-Length: " . strlen($return));
header("Content-Type: text/xml");
header("Date: " . date("r"));
if($server){
header("Server: $server");
}
if(defined('XMLRPC_DEBUG') and XMLRPC_DEBUG){
XMLRPC_debug('XMLRPC_error', "

Sent the following error response:

\n\n" . XMLRPC_show($return, 'print_r', true));
}
echo $return;
}

function XMLRPC_convert_timestamp_to_iso8601($timestamp){
#takes a unix timestamp and converts it to iso8601 required by XMLRPC
#an example iso8601 datetime is "20010822T03:14:33"
return date("Ymd\TH:i:s", $timestamp);
}

function XMLRPC_convert_iso8601_to_timestamp($iso8601){
return strtotime($iso8601);
}

function count_numeric_items($array){
return is_array($array) ? count(array_filter(array_keys($array), 'is_numeric')) : 0;
}

function XMLRPC_debug($function_name, $debug_message){
$GLOBALS['XMLRPC_DEBUG_INFO'][] = array($function_name, $debug_message);
}

function XMLRPC_debug_print(){
if($GLOBALS['XMLRPC_DEBUG_INFO']){
echo "\n";
foreach($GLOBALS['XMLRPC_DEBUG_INFO'] as $debug){
echo "\n";
}
echo "
$debug[0] $debug[1]
\n";
unset($GLOBALS['XMLRPC_DEBUG_INFO']);
}else{
echo "

No debugging information available yet.

";
}
}

function XMLRPC_show($data, $func = "print_r", $return_str = false){
ob_start();
$func($data);
$output = ob_get_contents();
ob_end_clean();
if($return_str){
return "
" . htmlspecialchars($output) . "
登录后复制
\n";
}else{
echo "
", htmlspecialchars($output), "
登录后复制
\n";
}
}

?>

服务端程序例子,server.php

复制代码 代码如下:



include 'xml-rpc.inc.php';
//定义可被远程调用的方法
$xmlrpc_methods=array();
$xmlrpc_methods['insertRecords']='insertRecords';

//获得用户传入的方法名和参数
$xmlrpc_request = XMLRPC_parse($HTTP_RAW_POST_DATA);
$methodName = XMLRPC_getMethodName($xmlrpc_request);
$params = XMLRPC_getParams($xmlrpc_request);

if (!isset($xmlrpc_methods[$methodName])){
XMLRPC_error('1',"你所调用的方法不存在");
}else {
$xmlrpc_methods[$methodName]($params);
}
function insertRecords($params){
if (emptyempty($params)){
XMLRPC_error('2',"参数出错");
}
XMLRPC_response(XMLRPC_prepare('http://www.emtit.com'));
}
?>


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

复制代码 代码如下:


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


结果会显示www.emtiit.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1677
14
CakePHP 教程
1431
52
Laravel 教程
1334
25
PHP教程
1280
29
C# 教程
1257
24
继续使用PHP:耐力的原因 继续使用PHP:耐力的原因 Apr 19, 2025 am 12:23 AM

PHP仍然流行的原因是其易用性、灵活性和强大的生态系统。1)易用性和简单语法使其成为初学者的首选。2)与web开发紧密结合,处理HTTP请求和数据库交互出色。3)庞大的生态系统提供了丰富的工具和库。4)活跃的社区和开源性质使其适应新需求和技术趋势。

如果session_start()被多次调用会发生什么? 如果session_start()被多次调用会发生什么? Apr 25, 2025 am 12:06 AM

多次调用session_start()会导致警告信息和可能的数据覆盖。1)PHP会发出警告,提示session已启动。2)可能导致session数据意外覆盖。3)使用session_status()检查session状态,避免重复调用。

IIS和PHP的兼容性:深度潜水 IIS和PHP的兼容性:深度潜水 Apr 22, 2025 am 12:01 AM

IIS和PHP可以兼容,通过FastCGI实现。1.IIS通过配置文件将.php文件请求转发给FastCGI模块。2.FastCGI模块启动PHP进程处理请求,提高性能和稳定性。3.实际应用中需注意配置细节、错误调试和性能优化。

作曲家:通过AI的帮助开发PHP 作曲家:通过AI的帮助开发PHP Apr 29, 2025 am 12:27 AM

AI可以帮助优化Composer的使用,具体方法包括:1.依赖管理优化:AI分析依赖关系,建议最佳版本组合,减少冲突。2.自动化代码生成:AI生成符合最佳实践的composer.json文件。3.代码质量提升:AI检测潜在问题,提供优化建议,提高代码质量。这些方法通过机器学习和自然语言处理技术实现,帮助开发者提高效率和代码质量。

session_start()函数的意义是什么? session_start()函数的意义是什么? May 03, 2025 am 12:18 AM

session_start()iscucialinphpformanagingusersessions.1)ItInitiateSanewsessionifnoneexists,2)resumesanexistingsessions,and3)setsasesessionCookieforContinuityActinuityAccontinuityAcconActInityAcconActInityAcconAccRequests,EnablingApplicationsApplicationsLikeUseAppericationLikeUseAthenticationalticationaltication and PersersonalizedContentent。

使用Laravel:使用PHP简化Web开发 使用Laravel:使用PHP简化Web开发 Apr 19, 2025 am 12:18 AM

Laravel优化Web开发流程的方法包括:1.使用路由系统管理URL结构;2.利用Blade模板引擎简化视图开发;3.通过队列处理耗时任务;4.使用EloquentORM简化数据库操作;5.遵循最佳实践提高代码质量和可维护性。

PHP和IIS:让他们一起工作 PHP和IIS:让他们一起工作 Apr 21, 2025 am 12:06 AM

在IIS上配置和运行PHP需要以下步骤:1)下载并安装PHP,2)配置IIS并添加FastCGI模块,3)创建并设置应用池,4)创建网站并绑定到应用池。通过这些步骤,你可以在Windows服务器上轻松部署PHP应用,并通过配置扩展和优化性能来提升应用的稳定性和效率。

如何使用MySQL的函数进行数据处理和计算 如何使用MySQL的函数进行数据处理和计算 Apr 29, 2025 pm 04:21 PM

MySQL函数可用于数据处理和计算。1.基本用法包括字符串处理、日期计算和数学运算。2.高级用法涉及结合多个函数实现复杂操作。3.性能优化需避免在WHERE子句中使用函数,并使用GROUPBY和临时表。

See all articles