XML-RPC实现WebService简单PHP程序示例 及 Closure闭包中的bind与bindTo方法的区别

作者 : admin 本文共4168个字,预计阅读时间需要11分钟 发布时间: 2024-06-10 共1人阅读

一、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
\r
";
echo '
';print_r($data);echo '

';

/**********************************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
User_Agent: XML-RPC Client
Host: ".$this->host."
Content-Type: text/xml
Content-Length:".strlen($request)."

".$request."
";
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='';
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-RPC实现WebService简单PHP程序示例 及 Closure闭包中的bind与bindTo方法的区别插图

    不过目前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 '
'; $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-RPC实现WebService简单PHP程序示例 及 Closure闭包中的bind与bindTo方法的区别
E-->