大多数的Web Service是使用Java语言的,因此在PHP中很少用到Web Service,用PHP写Web Service程序也就成为了比较冷门的知识点,其实仔细研究一下,似乎没有想象中复杂
下面我们就来用PHP写Web Service程序:
1、Server端
首先,定义一个类,在其中实现方法,然后用SoapServer将此类发布出去。
data_service.php:
class DataAction{
public function add($x, $y){
return $x + $y;
//定义SoapServer,不指定wsdl,必须指定uri,相当于asmx中的namespace
$server = new SoapServer(null, ["uri" => "php.test"]);
//指定此SoapServer发布DataAction类中的所有方法
$server->setClass("DataAction");
$server->handle>
也可以不用class,直接发布function。
function add($x, $y){
return $x + $y;
$server = new SoapServer(null, ["uri" => "php.test"]);
$server->addFunction("add");
$server->handle();
2、Client端
client.php:
//SoapClient即WebService客户端,其uri与Server端保持一致,location是WebService服务地址
$client = new SoapClient(null, ["uri" => "php.test", "location" => "http://192.168.90.81/test/data_service.php"]);
//调用add方法,传入参数
echo $client->add(100, 200);
unset($client);
我们尝试抓包看看:
请求包:
POST /test/data_service.php HTTP/1.1
Host: 192.168.90.81
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.4.3
Content-Type: text/xml; charset=utf-8
SOAPAction: "php.test#add"
Content-Length: 512
100800
响应包:
HTTP/1.1 200 OK
Server: nginx/1.2.0
Date: Thu, 07 Jun 2012 06:51:33 GMT
Content-Type: text/xml; charset=utf-8
Content-Length: 488
Connection: keep-alive
X-Powered-By: PHP/5.4.3
900
我们需要注意,如果PHP是以FastCGI方式运行,且只启动了一个进程 ,由于php-cgi.exe的单线程模型,访问client.php时其又会向data_service.php发送请求,但当前请求未处理完毕,data_service.php无法响应,会造成卡死得不到结果。
比如nginx如果没有使用负载均衡,所有php请求都转发到同一个php-cgi进程,就肯定会卡死。请负载均衡到不同进程上,或者换用isapi模式。
使用这种方式没有定义wsdl,没想明白双方是如何约定通讯的。另外显然,用这种方式肯定无法跨语言访问服务,因为我们访问data_service.php?wsdl拿不到wsdl,返回如下:
SOAP-ENV:Server
WSDL generation is not supported yet
看完了本文。我们可能觉得用PHP写Web Service程序似乎很简单,但实际操作起来并没有我们看起来那么轻松,会遇到许多的现实问题,需要我们花大量时间和精力去考证和解决。或许,这也是我们学习的乐趣之所在吧!
热门跟贴