PHP & Web Service
http://www.phpchina.com/html/21/t-12821.html
废话不多说,WebService这个热啊,PHP这个火啊,想用PHP开发WebService是理所当然的事。什么?不懂WebService?没事,百度一下就知道了。啊?看不懂?不懂也没关系,直接看大少爷写的吧:)
大少爷是个激进分子,喜欢直接拿代码说事,不过在把可怜的读者弄得一头雾水之前,还是先大致说一下本文的目的。本文不打算讲述WebService的概念,也不打算讲那些复杂的协议内容。本文只是要让大家看看对于WebService,PHP可以做些什么,怎么做,有什么要注意的。
如果你刚才听了大少爷的查了百度,或者你以前查过,你应该已经大概知道了WebService的用处。通过WebService,我们可以调用部署在其他地方的程序,而不用care被调用的程序是在什么平台用什么语言编写的。也许你听说过GoogleAPI、YahooAPI什么的,大少爷虽然没有挨个调查过,但知道至少google是遵照标准的Web Service实现的,google用的是java,我们这里将使用PHP。
开始:Hello Word!
先来看代码:
[php]<?php
/**
* 实现业务逻辑的类,此类是一个普通类
*
*/
class Basic {
/**
* 返回一个字符串:Hello World!
*
* @return string
*/
public function returnString(){
return "Hello World!";
}
}
?> [/php]
so简单,一个类,返回一个字符串。假设这个程序在服务器A上面,如果大少爷想在服务器B上面想调用这个程序怎么办?首先我们先要将这个类变成Web服务,这就需要使用PHP的SOAP扩展,如何安装这个扩展请参考PHP手册。安装好后,请看如下代码。
[php]
<?php
/**
* Web Service的Server端,包含类文件。
*/
require_once("Basic.php");
/**
* 创建Server对象
*/
$arrOptions = array('uri'=>'http://example.com/'); //设置命名空间
$objSoapServer = new SoapServer(null,$arrOptions);
/**
* 注册Basic类的所有方法
*/
$objSoapServer->setClass("Basic");
/**
* 处理请求
*/
$objSoapServer->handle();
?> [/php]
OK,一个Web服务搭建好了,上面的例子中,我们创建了一个SoapServer对象,然后利用setClass函数将我们刚才编写的Basic类set进去,最后handle(),那个命名空间我们先不去管它。现在如果用浏览器访问这个文件,会出现警告,这是正常的,因为这个文件不是用浏览器访问的,而是用另一个程序访问的。当一个客户端程序访问我们的WebService时,运行到handle()时会对客户端的输入进行处理,并输出结果给各户端。这里需要注意一下,不要在handle()之前和之后输出任何东西,否则客户端会处理不了。
好了,我们要编写客户端访问这个WebService。
[php]
<?php
/**
* Client端,首先创建Client对象
*/
$arrOptions = array('uri'=>'http://example.com/', //设置命名空间
'location'=>'http://url/to/our/webservice', //设置Server地址
'trace'=>true);
$objSoapClient = new SoapClient(null,$arrOptions);
/**
* 远程调用
*/
try{
$strReturn = $objSoapClient->returnString();
}catch(Exception $e){
}
/**
* 打印结果
*/
echo $strReturn;
?>
[/php]
上面这个程序,我们首先创建了一个SoapClient对象,然后就像使用服务端的Basic对象一样调用returnString方法,并打印输出结果。不论你把这个PHP放在哪台服务器,只要它和服务端的网络能够相连,就能够得到我们期望的结果:Hello World!。
不论是SoapServer还是SoapClient,都接收两个参数,其中第二个参数是Option,它支持若干选项,这里我们用到的有:
uri:命名空间,客户端和服务端需要使用相同的命名空间
location:客户端用,用来指定服务端程序的访问地址,也就是本例第二段代码的程序地址。
trace:客户端用,为true时可以获取服务端和客户端通信的内容,以供调试。
你可以尝试将第一段代码扩展一下,填写更多的函数,看看返回整型、浮点型、数组、对象分别是什么样子,也可以尝试从客户端接收参数,处理一下再返回,或者利用SoapClient的函数跟踪一下客户端和服务端通信的内容(关于这些函数请查看PHP文档),你暂时可以不用太关心通信内容的含义。
如果你按照大少爷说的进行了尝试,你会发现,基本上服务端返回什么数据类型,客户端可以接收到什么数据类型,但是当服务端返回对象时,客户端接收到的是一个stdClass对象,并且其属性的可见性并非按照服务端定义的,而是全部的public。
有经验的读者可能会问,如果客户端和服务端的编码不同怎么办?在Option中,有一个选项encoding,可以在客户端和服务端使用,用以指定文字的编码。比如你的服务端是gbk编码的,客户端是utf8编码的,就分别在服务端和客户端填入gbk和utf8。注意,此选项不会更改客户端和服务端通信内容的编码(它永远是utf8的),而只是在两端接受到通信内容后进行编码转换。
好了,第一个例子讲完了,应该不难。不过,这只是最基础的东西而已,我们知道PHP是弱类型的语言,对于强类型的语言来说(C、C++、Java),他们怎么识别PHP返回的数据类型呢