本章节将详细讲述如何用PHP创建WebService服务端。
开发工具:Zend Studio 7.2;
部署环境:WampServer2.0c(包括了Apache、MySql、PHP)。
?
1.??? 用Zend Studio 7.2构造项目工程。
由于我们采用的部署环境是wamp,所以dbgp-bbs项目是部署在www目录下,如下图所示:
?
?
大家都知道,用UCenter安装完Discus后,论坛dbgp-bbs是没有任何工程文件的,所以在这种情况下是不能直接使用Zend Studio工具来对其进行开发的,所以下面我们的第一步就是如何把已经安装好的dbgp-bbs项目导入到Zend Studio开发环境中。
第一种方法,你可以随意用Zend Studio新建一个PHP Project,然后把工程文件拷贝到bbs目录下,然后用记事本工具打开这些文件进行编辑,改成本项目的内容,如.project文件内容:
?
<?xml version="1.0" encoding="UTF-8"?> <projectDescription> <name>dbgp_bbs</name> <comment></comment> <projects> </projects> <buildSpec> <buildCommand> <name>org.eclipse.wst.validation.validationbuilder</name> <arguments> </arguments> </buildCommand> <buildCommand> <name>org.eclipse.dltk.core.scriptbuilder</name> <arguments> </arguments> </buildCommand> </buildSpec> <natures> <nature>org.eclipse.php.core.PHPNature</nature> </natures> </projectDescription>
?
第二种方法,你可以把Zend Studio的默认WorkSpace设置为www\dbgp目录,然后新建一个PHP Project项目dbgp-bbs,把指向www\dbgp\bbs目录,创建完毕后在Zend Studio 中刷新一下整个项目,就可以看到所有的目录文件了。
2.??? 创建服务端PHP文件。
在工程中新建一个目录,命名为usersyncservice,然后在目录中新建一个PHP文件,在文件内编写服务端代码。本文不再讲解与PHP语法相关的事情,阁下可以参阅相关PHP技术文档。现在把代码贴出来,关键之处已经做了详细的注解。
<?php require_once '../include/common.inc.php'; require_once DISCUZ_ROOT.'./forumdata/cache/cache_profilefields.php'; require_once DISCUZ_ROOT.'./uc_client/client.php'; /** * 用户资料同步类。 * @author shangbingbing */ class UserSync { /** * 同步保存用户。 * 当系统管理员在门户站点中注册新用户时,同时调用此接口方法,同步新增论坛系统的此用户。 * @param unknown_type $userName 用户名称 * @param unknown_type $password 登录密码(明码) * @param unknown_type $email 信箱 */ public function SyncSaveUser($userName,$password,$email) { //把用户信息保存到UC_MEMBER表中 $uid = uc_user_register($userName, $password, $email, '', '', '127.0.0.1'); //把用户信息保存到CDB_MEMBER表中,以激活用户 GLOBAL $db; if($db->result_first("SELECT uid FROM cdb_members WHERE uid='$uid'")) { uc_user_delete($uid); } $idstring = random(6); $password = md5(random(10)); $sql = "insert into cdb_members (uid,username,email,groupid,timeoffset) values ($uid,'$userName','$email','10','9999')"; $sql = $db->query($sql); return "success"; } /** * 同步所有用户资料 */ public function SyncAllUsers() { return "success"; } /** * 同步修改用户密码 * 当某用户在门户站点内修改密码时,同时调用此接口方法,同步修改论坛系统的此用户的密码。 * @param $userName 用户名称 * @param $newPassword 新密码 */ public function SyncChangePassword($userName,$newPassword) { return "success"; } /** * 同步删除用户。 * 当系统管理员在门户站点中删除某用户时,同时调用此接口方法,同步删除论坛系统的此用户。 * @param unknown_type $userName */ public function SyncDeleteUser($userName) { return "success"; } /** * 同步失效(或禁用)用户。 * 当系统管理员在门户站点中禁用某用户时,同时调用此接口方法,同步禁用论坛系统的此用户。 * @param unknown_type $userName */ public function SyncInvalidationUser($userName) { return "success"; } /** * 测试接口方法,在程序调试期对本人有很大帮助,因此不忍心删除! * @param unknown_type $userName */ public function Hello($userName) { return "Hello ".$userName.",Welcome to PHP WebService World!"; } } $server = new SoapServer('UserSyncSoap.wsdl'); $server->setClass("UserSync"); $server->handle(); ?>
?
3.??? 生成WSDL文件。
不知道怎么回事,Zend Studio 7.2不支持自动将PHP文件转换为WSDL,所以必须手动生成WSDL文件。
在usersyncservice目录中新建WSDL文件,如下图所示:
?
?
?
?
?
?
完整的WSDL源代码如下:
?
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.example.org/UserSyncSoap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="UserSyncSoap" targetNamespace="http://www.example.org/UserSyncSoap/"> <wsdl:types> <xsd:schema targetNamespace="http://www.example.org/UserSyncSoap/"> <xsd:element name="SyncSaveUser"> <xsd:complexType> <xsd:sequence> <xsd:element name="in" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="SyncSaveUserResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="out" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="SyncAllUsers"> <xsd:complexType> <xsd:sequence> <xsd:element name="in" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="SyncAllUsersResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="out" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="SyncChangePassword"> <xsd:complexType> <xsd:sequence> <xsd:element name="in" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="SyncChangePasswordResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="out" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="SyncDeleteUser"> <xsd:complexType> <xsd:sequence> <xsd:element name="in" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="SyncDeleteUserResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="out" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="SyncInvalidationUser"> <xsd:complexType> <xsd:sequence> <xsd:element name="in" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="SyncInvalidationUserResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="out" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="Hello"> <xsd:complexType> <xsd:sequence> <xsd:element name="in" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="HelloResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="out" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </wsdl:types> <wsdl:message name="SyncSaveUserRequest"> <wsdl:part name="userName" type="xsd:string"></wsdl:part> <wsdl:part name="password" type="xsd:string"></wsdl:part> <wsdl:part name="email" type="xsd:string"></wsdl:part> </wsdl:message> <wsdl:message name="SyncSaveUserResponse"> <wsdl:part name="SyncSaveUserReturn" type="xsd:string"/> </wsdl:message> <wsdl:message name="SyncAllUsersRequest"> </wsdl:message> <wsdl:message name="SyncAllUsersResponse"> <wsdl:part name="SyncAllUsersReturn" type="xsd:string"/> </wsdl:message> <wsdl:message name="SyncChangePasswordRequest"> <wsdl:part name="userName" type="xsd:string"></wsdl:part> <wsdl:part name="newPassword" type="xsd:string"></wsdl:part> </wsdl:message> <wsdl:message name="SyncChangePasswordResponse"> <wsdl:part name="SyncChangePasswordReturn" type="xsd:string"/> </wsdl:message> <wsdl:message name="SyncDeleteUserRequest"> <wsdl:part name="userName" type="xsd:string"></wsdl:part> </wsdl:message> <wsdl:message name="SyncDeleteUserResponse"> <wsdl:part name="SyncDeleteUserReturn" type="xsd:string"></wsdl:part> </wsdl:message> <wsdl:message name="SyncInvalidationUserRequest"> <wsdl:part name="userName" type="xsd:string"></wsdl:part> </wsdl:message> <wsdl:message name="SyncInvalidationUserResponse"> <wsdl:part name="SyncInvalidationUserReturn" type="xsd:string"></wsdl:part> </wsdl:message> <wsdl:message name="HelloRequest"> <wsdl:part name="userName" type="xsd:string"></wsdl:part> </wsdl:message> <wsdl:message name="HelloResponse"> <wsdl:part name="HelloReturn" type="xsd:string"></wsdl:part> </wsdl:message> <wsdl:portType name="UserSyncSoap"> <wsdl:operation name="SyncSaveUser"> <wsdl:input message="tns:SyncSaveUserRequest"/> <wsdl:output message="tns:SyncSaveUserResponse"/> </wsdl:operation> <wsdl:operation name="SyncAllUsers"> <wsdl:input message="tns:SyncAllUsersRequest"/> <wsdl:output message="tns:SyncAllUsersResponse"/> </wsdl:operation> <wsdl:operation name="SyncChangePassword"> <wsdl:input message="tns:SyncChangePasswordRequest"/> <wsdl:output message="tns:SyncChangePasswordResponse"/> </wsdl:operation> <wsdl:operation name="SyncDeleteUser"> <wsdl:input message="tns:SyncDeleteUserRequest"></wsdl:input> <wsdl:output message="tns:SyncDeleteUserResponse"></wsdl:output> </wsdl:operation> <wsdl:operation name="SyncInvalidationUser"> <wsdl:input message="tns:SyncInvalidationUserRequest"></wsdl:input> <wsdl:output message="tns:SyncInvalidationUserResponse"></wsdl:output> </wsdl:operation> <wsdl:operation name="Hello"> <wsdl:input message="tns:HelloRequest"></wsdl:input> <wsdl:output message="tns:HelloResponse"></wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="UserSyncSoapSOAP" type="tns:UserSyncSoap"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="SyncSaveUser"> <soap:operation soapAction="http://www.example.org/UserSyncSoap/SyncSaveUser"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="SyncAllUsers"> <soap:operation soapAction="http://www.example.org/UserSyncSoap/SyncAllUsers"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="SyncChangePassword"> <soap:operation soapAction="http://www.example.org/UserSyncSoap/SyncChangePassword"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="SyncDeleteUser"> <soap:operation soapAction="http://www.example.org/UserSyncSoap/SyncDeleteUser"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="SyncInvalidationUser"> <soap:operation soapAction="http://www.example.org/UserSyncSoap/SyncInvalidationUser"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="Hello"> <soap:operation soapAction="http://www.example.org/UserSyncSoap/Hello"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="UserSyncSoap"> <wsdl:port binding="tns:UserSyncSoapSOAP" name="UserSyncSoapSOAP"> <soap:address location="http://localhost/dbgp/bbs/usersyncservice/UserSyncWebService.php"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
4.??? 简单测试WebService。
在浏览器地址中输入
http://localhost/dbgp/bbs/usersyncservice/UserSyncSoap.wsdl,查看是否能够XML文档。
这只是进行最最初步和简单的测试,真正的测试,你必须编写代码调用此WebService测试才行。
5.??? 注意事项。
Soap通讯是基于XML的,并且要求WebService客户端和服务端的文件编码必须一致是UTF-8,所以在Zend Studio工程中必须把上面涉及到的两个文件的编码格式设置为UTF-8。
?
其他说明:
本章节主要是讲述利用Zend Studio编写WebService服务端的流程,中间涉及到的WebService开发技术、WSDL编写技术、PHP语法等只是,需要阁下自行学习和查找。本人也是在编写此文章的之前四天才开始接触PHP和Zend Studio的,几乎所有的东西都是从网络上查找的,然后本人一步一步的进行测试,解决了一个又一个讨厌的小问题,最后才总算把整个解决方案搞定。
如果阁下在学习过程中遇到与此相关的问题,可以告诉我,我会尽力帮助解决的。?