一、XML-RPC实现WebService简单PHP程序示例
Web Service就是为了异构系统的通信而产生的,它基本的思想就是使用基于XML的HTTP的远程调用提供一种标准的机制,而省去建立一种新协议的需求。目前进行Web Service通信有两种协议标准,一种是XML-RPC,另外一种是SOAP。XML-RPC比较简单,出现时间比较早,SOAP比较复杂,主要是一些需要稳定、健壮、安全并且复杂交互的时候使用。
PHP中集成了XML-RPC和SOAP两种协议的访问,都是集中在xmlrpc扩展当中。另外,在PHP的PEAR中,不管是PHP 4还是PHP 5,都已经默认集成了XML-RPC扩展,而且该扩展跟xmlrpc扩展无关,能够独立实现XML-RPC的协议交互。windows下要使用xmlrpc需要在php.ini中打开:extension=php_xmlrpc.dll;下面是一个xml_rpc客户端发送和服务器端接收处理的程序:
客户端发送程序:页面最下方有程序的下载链接。
#基本
error_reporting(E_ALL);
date_default_timezone_set('PRC');
header("Content-type:text/html;charset=utf-8");
#客户端调用实例
$host='localhost';
$port=80;
$uri="/InterFace/InterFace.php";
$token=md5($uri);
$q='测试';
$Client=new Client($host,$port,$uri);
$data=$Client->sendXml('Search',array('token'=>$token,'q'=>$q));
echo "\r\n\r\n";
echo '<pre>';print_r($data);echo '</pre>';
/**********************************Client Class***********************************/
class Client{
private $host;
private $port;
private $serverUri;
public function __construct($host,$port,$uri){
$this->host=$host;
$this->port=$port;
$this->serverUri=$uri;
if(!function_exists("xmlrpc_encode_request")) exit('please install xml-rpc extend first');
}
public function sendXml($fun,$params=array()){
$fp=fsockopen($this->host,$this->port);
$request=xmlrpc_encode_request($fun,$params);
$query = "POST {$this->serverUri} HTTP/1.0\nUser_Agent: XML-RPC Client\nHost: ".$this->host."\nContent-Type: text/xml\nContent-Length:".strlen($request)."\n\n".$request."\n";
if(!fputs($fp, $query, strlen($query))) {
$errstr = "Write error";
echo $errstr;
return false;
}
$contents = "";
while (!feof($fp)){$contents .= fgets($fp);}
fclose($fp);
//显示原始数据
print_r($contents);
return $this->AnalyData($contents);
}
public function AnalyData($contents){
$pos='<?xml version="1.0" encoding="utf-8"?>';
if(strpos($contents,$pos)===false) exit('ERROR_:'.$contents);
$xml = explode($pos, $contents);
$xml = $pos.array_pop($xml);
//测试显示返回数据:
$xml = xmlrpc_decode($xml);
return $xml;
}
}
服务器端接收及处理程序:
#基本配置
error_reporting(E_ALL);
date_default_timezone_set('PRC');
define('ROOTPATH',str_replace('\\','/',dirname(__FILE__)).'/');
$requestXML=file_get_contents('php://input');
//显示服务器接收到的数据
//print_r($requestXML);exit;
//需要打开扩展:extension=php_xmlrpc.dll
if(!function_exists("xmlrpc_server_create"))
{
exit('please install xml-rpc extend first');
}
//创建xmlrpc_server
$xmlrpc_server=xmlrpc_server_create();
xmlrpc_server_register_method($xmlrpc_server,"Search","rpc_server_func");
#数据处理及返回
$xmlrpc_response = xmlrpc_server_call_method($xmlrpc_server, $requestXML, null);
header("Content-Type: text/xml");
xmlrpc_server_destroy($xmlrpc_server);
//处理函数
function rpc_server_func($method, $params)
{
$obj = new $method();
echo $obj->dodata($params);
}
//处理的程序(可统一分离放至单独的处理程序文件夹中
class Search
{
public function dodata($params)
{
return xmlrpc_encode('aaa');
}
}
下图是数据截图,左边是发送后客户端接收到的数据,右图是服务器端返回给客户端的数据:
不过目前XML应用得很少,现在是json的天下,不过在一些老的系统里还是有很多XML的。XMLRPC实现WebService简单PHP程序示例下载见本博客中的资源下载。--publish:July 21, 2016 -Thursday
二、Closure闭包中的bind与bindTo方法的区别
Closure是PHP里的一个final类,其有两个方法(bind和bindTo),在定义一个闭包函数时实际就是定义了一个Closure的实例化对象。所有所有的闭包函数都自带有bind和bindTo方法:
•Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域。
•Closure::bindTo — 复制当前闭包对象,绑定指定的$this对象和类作用域。
看手册上的描述,很难找到bind和bindTo之间的区别,而事实也的确如此,这两个方法除了在调用方式方法(一个使用::调用,一个使用->调用)不同外,生成的闭包是一样的。相比较而言,bindTo方法是一个更简单的写法。例如我们已经定义了一个闭包$closure,此时我们要得到一个绑定类后的闭包对象,我们有以下三种写法:
//匿名函数绑定到类的写法
$newClosure = Closure::bind($closure, new A(), 'A');
$newClosure = $closure::bind($closure, new A(), 'A');
$newClosure = $closure->bindTo(new A(), 'A');
因为闭包函数$closure本身就是一个Closure,$closure也有bind方法,所有第一种、第二种是一样的,而我们从第二种写法可明显看到重复了一个$closure,这完全没有必要,既然是$closure发起调用bind方法,没必要再将自己做为参数传入,所以第三种写法从上到下可以看出是一种更优的调用方法。
在bind和bindTo的使用上,两者并没有多大差别,如下示例:
//闭包函数Closure中对静态与动态属性的调用
Class Student
{
static $name = 'kermit';
private $age = 20;
}
//实例化类,定义匿名函数
$student = new Student();
$getName = function()
{
return self::$name .'--'.$this->age;
};
//将匿名函数绑定到类:
$getNameClosure = $getName::bind($getName, $student, 'Student');
echo $getNameClosure();
echo '<br>';
$otherClosure = $getName->bindTo($student, 'Student');
echo $otherClosure();
包括我对各个步骤进行了var_dump打印查看,两个方法生成的闭包对象功能都一样。另外在一系列使用之后,在bind和bindTo的传参上的一些个人总结如下:
1,bind和bindTo的类参数(即上例中的$student)是一个必传参数,如果传null。则闭包函数中不能使用$this,如果传了一个实例化类,闭包函数中才能使用$this。
2,bind和bindTo的类作用域参数(即上例中的'Student'参数)默认为Static,如果使用默认值,则闭包函数中不能使用self调用,如果传了类名,则可以使用self.
3,如果闭包函数存在调用类的private或protected属性或方法,则必须传递第三个参数指明类作用域才能正常调用。
标签:XML,Closure,闭包,xmlrpc,示例,bind,server,bindTo,xml From: https://blog.csdn.net/weixin_47792780/article/details/139401572