在 Eclipse 中使用 PHP 构建 Web 服务


开始之前

  关于本教程

  本教程展示如何通过 PHP Development Tools (PDT) 插件使用 PHP 构建 Web 服务。PDT 项目于 2007 年 9 月启动,于 2008 年 1 月发行版本 V1.0.2。PDT 项目提供了一流的功能,可以在 Eclipse IDE 中编辑、调试和部署 PHP 应用程序。

  目标

  本教程有三个主要目标。第一个目标是使读者熟悉 PDT 项目,并了解如何创建和部署有用的 PHP 项目。第二个目标是了解契约优先开发背后的原理。最后,概述构成一个 WSDL 文件的基本部分。

  先决条件

  您应该具备 PHP 开发经验。

  系统需求

  要从本教程中获得最大收益,需要安装 Eclipse Europa 和 PDT 插件。此外,还须安装 Eclipse Web Standard Tools(WST)子项目。注意:如果安装了 Eclipse 的 Java 2 Platform, Enterprise Edition(J2EE)包,则已经安装了 WST。

  要跟随教程中的示例,需要 Eclipse Europa 以及 Eclipse 支持的操作系统之一 — Mac OS X、Microsoft? Windows? 或 Linux?。还需要一个 Java? Runtime Environment(JRE)— 建议至少使用 JRE for Java V5。

  PDT 概述

  PDT 项目提供了使用 Eclipse IDE 进行 PHP 开发的能力。它包括很多 Java 编辑环境的特性,包括语法突出显示、代码模板、透视图、文件和项目向导。

  安装 PDT

  要安装 PDT,确保具有最新版本的 Eclipse。使用内置的软件更新程序从更新站点更新 PDT。PDT 需要 WST 子项目。如果还没有安装的话,应首先安装 WST。如果已下载并安装了 Eclipse 的 J2EE 包,就已经有了 WST。如果下载的是 Eclipse 的只包含 Java 的包,则必须从 Eclipse Europa 发现站点安装 WST。


图 1. 从 Eclipse Europa 发现站点安装 WST

  设置 PDT

  安装 PDT 后,需要进行一些设置,特别是使用 PDT 和 Eclipse 的计算机以前进行过 PHP 开发的话。首先设置 PHP 可执行文件的路径。要设置这个路径,打开 Preferences 窗口。在左侧面板中,展开 PHP,然后单击 PHP Executables。在右侧面板中,将看到可以输入或浏览 PHP 可执行文件路径的位置。


图 2. 设置 PHP 解释程序


  在左侧面板的 PHP 下,单击 PHP Interpreter,然后指定所使用的 PHP 的版本。默认值为 PHP V5。

  要访问 PHP 编辑器,在左侧面板的 PHP 下,展开 Editor。随 PDT 附带的 PHP 编辑器包含有许多 Java 编辑器的特性,包括语法突出显示、格式化、代码完成功能和代码模板。

  PHP Functions 选项卡

  PHP Functions 选项卡展示库路径中常用的 PHP 函数和类。通过在搜索框中输入内容,可以在列表中搜索函数,如图 3 所示。双击 PHP Functions 选项卡上的名称,以将名称插入到编辑器的当前位置。还可以在向编辑器输入内容时使用代码完成功能(Ctrl+Space),可以从匹配的函数或模板列表中进行选择并插入它们。


图 3. 搜索 PHP 函数


  PHP Project 选项卡

  通过列出分为不同对象类型的项目的内容,PHP Project 选项卡提供了 PHP 项目的以 PHP 为中心的视图。您可以在 Classes 下查看在项目中定义的所有类,在 Functions 下查看定义的所有函数。双击 PHP Project 选项卡中的项,这将自动导航到编辑器中的项。图 4 展示了 PHP Project 选项卡示例,其中包含了后文将讨论的类和函数。


图 4. PHP Project 选项卡


  PHP Explorer

  PHP Explorer 在工作空间中显示一个项目和文件列表。它与其他项目浏览器(如 Java Explorer)相一致。

  构建一个服务契约

  WSDL 概述

  WSDL 文件是一个描述一个或多个 Web 服务的 XML 文件。描述的内容包括在服务中可用的方法或操作,以及构成操作的输入和输出的消息的模式。

  如果您已经很熟悉 WSDL 文件,或者已经具备要使用的文件并且不关心其工作方式,那么可以跳过本节内容,继续学习 “替代方法:导入一个 WSDL 文件” 小节。但是如果您刚刚接触 WSDL 文件,或者以前使用过但是现在想复习一下,那么本节内容将非常有帮助。

  在 Eclipse 中可视性地构建 WSDL 文件和 XML Schema Definition (XSD) 文件,这种能力对于在 Eclipse 中构建 WSDL 文件非常有帮助。如果愿意的话,可以始终将 WSDL 编辑器切换到源代码模式来亲自编辑源代码。WSDL 文件包括 4 个主要部分,本节后面的内容将从较高的层次进行详细介绍。

  type 涵盖了 Web 服务请求和响应消息中使用的类型。message 包含发往 Web 服务和从中返回的消息。在可视化的 Eclipse 编辑器中,它们被显示为 Web 服务操作的输入和输出。 portType 列出 Web 服务公开的操作。binding 包含 Web 服务使用的通信协议。service 描述公开的一个或多个服务。

  types 元素

  types 元素包含有关 SOAP 消息中使用的类型的信息。XML 模式可以方便地描述类型,并且您可以导入其他类型。Eclipse 编辑器可以很好地处理多种类型。使用外部模式的一个优点就是可以重用已经定义的复杂类型。相反,使用内联(即位于 WSDL 内部)模式的优点是您的 WSDL 文件包含关于 Web 服务的所有必要信息。注意:为简单起见,本教程主要关注使用内联模式定义类型。

  message 元素

  message 元素定义操作发送和接收的消息。如果将 Web 服务的操作看作是 PHP 代码中的方法,那么 message 将描述发送给方法的参数和方法返回的 return 类型。

  portType 元素

  portType 元素描述 Web 服务公开的操作,如果将 Web 服务看作一个 PHP 类,portType 元素将解释 PHP 类公开的 public 方法。

  binding 元素

  binding 元素解释如何根据使用的访问协议公开操作。对于大多数例子,都使用 SOAP 协议访问 Web 服务操作。然而,也可以使用 HTTP 等其他协议。

  service 元素

  service 元素描述 Web 服务,允许在适合构成服务的操作集合中对类似的操作进行分组。

  契约优先开发

  首先构建或提供一个 WSDL 文件,然后根据这个 WSDL 文件(契约)编写代码来实现服务,这种开发方式被称为契约优先(contract-first)开发。在思考如何实现之前首先构建契约,这样做有几个好处。

  开放实现 它允许您根据个人意愿自由地实现服务。只要遵守契约,无论使用 PHP、Java 语言、Groovy 或是其他任何语言,都可以构建 Web 服务。 并发开发 如果首先构建契约,可以将其提供给客户,以便他们可以开始开发客户机来调用服务。只要遵循为客户提供的契约,您和客户可以同时进行并发开发。如果进行与此相反的 Web 服务开发,即首先构建代码,然后再公开服务的契约,那么其他人需要等待您完成您的代码库后才能采取行动。 适当分析 先创建契约能够保持您和您的团队的信誉,因为提前执行分析产生了契约内容。如果执行自下而上的 Web 服务开发,那么您的服务很可能是自然地发展,并且结果会得到一个比预期更加特定于您的实现的契约。

  可视化地构建 WSDL 文件

  当在 Eclipse WSDL 可视编辑器中可视化地构建 WSDL 文件时,会感觉非常自然,这是因为在构建 WSDL 文件时,可视化的编辑器布局首先构建 service 元素并向后倒退处理,最后定义类型。编辑器首先展示一个 UI 元素,它实际对应 WSDL 文件中的 service 元素。

  图 5 展示了 Web 服务的一个部分。因为例子是一个返回制造商推荐轮胎大小的 Web 服务,提供了汽车的品牌、型号、年份,所以调用 myTireService 服务。您可以在可视编辑器中直接输入新的名字。


图 5. WSDL 文件中的 Web 服务


  清单 1 展示了 Eclipse 在 WSDL 源代码中所做的修改。


清单 1. WSDL 中对服务的修改
<wsdl:service name="myTireService"> 
 <wsdl:port binding="tns:myTireServiceSOAP" 
 name="myTireService"> 
 <soap:address 
  location="http://localhost/~nagood/phpws/service.php" /> 
 </wsdl:port> 
</wsdl:service> 

  如图 6 所示,Outline 选项卡显示 WSDL 文件的主要部分。当单击 Outline 选项卡中的各部分时,它们将在 WSDL 可视编辑器中突出显示。


图 6. Outline 选项卡


  更新默认操作的名称

  修改了服务的名称之后,可以更新默认操作的名称,这个默认名称是在 Eclipse 最初构建骨架 WSDL 文件时创建的。单击 NewOperation 并开始输入方法的名称。本例中的方法名称为 getRecommendedTireSpecs,如图 7 所示。更新后的 WSDL 源代码如清单 2 所示。


图 7. WSDL 编辑器中的操作



清单 2. 为 getRecommendedTireSpecs 更新源代码
<wsdl:portType name="myTireService"> 
 <wsdl:operation name="getRecommendedTireSpecs"> 
 <wsdl:input message="tns:getRecommendedTireSpecsRequest" /> 
 <wsdl:output message="tns:getRecommendedTireSpecsResponse" /> 
 </wsdl:operation> 
</wsdl:portType> 

  Outline 选项卡和可视编辑器都进行了更新。


图 8. 编辑了操作之后的 Outline 选项卡


  暂时不讨论 binding — 保留默认值,不需要对它进行修改。然而,在这个例子中,请求和响应的类型将在其默认的字符串类型上进行了补充。

  编辑请求和响应类型

  在可视编辑器的输入行,单击生成的请求元素名 getRecommendedTireSpecs 旁边的蓝色箭头。Eclipse 可视 XML 模式编辑器将自动打开,允许您编辑复杂的请求和响应类型。请求如图 9 所示,添加了汽车的品牌、型号和年份的元素。


图 9. getRecommendedTireSpecs 请求对象


  如果希望在 WSDL 文件的其他地方重用复杂类型,请右键单击类型,然后单击 Refactor > Make Anonymous Type Global。global 类型对于本例来说并不是必要的,但是它有助于了解差别。

  清单 3 展示了修改为 global 类型的类型。


Listing 3. 将类型修改为 global 类型
<!-- ... parts of the WSDL before ... --> 
<xsd:element name="recommendedTireSpecsRequest" type="tns:automobileType"></xsd:element> 
<xsd:complexType name="automobileType"> 
 <xsd:sequence> 
  <xsd:element name="year" type="xsd:int"></xsd:element> 
  <xsd:element name="make" type="xsd:string"></xsd:element> 
  <xsd:element name="model" type="xsd:string"></xsd:element> 
 </xsd:sequence> 
</xsd:complexType> 

  返回 WSDL 编辑器并单击输出行旁边的蓝色箭头。模式编辑器将再一次打开,这一次显示元素和匿名类型。由于示例服务返回一个或多个轮胎规格集,每一个都包含速率、牵引率、额定温度以及轮胎的尺寸,return 类型中的简单字符串并不充分。

  将数据部分作为属性添加

  这一次不是向复杂类型添加元素,而是以属性的形式添加不同的数据部分。删除现有的元素,然后为 speedRating、tempRating、tractionRating、width、ratio 和 radius 添加属性。


图 10. 添加属性之后


  添加另一个复杂类型,称为 tireSpecificationsType。这不过是一个 tireSpecificationType 复杂类型的集合。当添加完新类型后,将如图 11 所示。


图 11. tireSpecifcationsType


  现在修改 recommendedTireSpecsResponse,使其类型为 tireSpecifcationsType。完成之后,如图 12 所示。现在您拥有了使用 Web 服务所需的所有类型。最终的 WSDL 文件如清单 4 所示。


图 12. 最终响应



清单 4. 完成后的 WSDL 文件
<?xml version="1.0" encoding="UTF-8"?> 
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
  xmlns:tns="urn:myTireService" 
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="myTireService" 
  targetNamespace="urn:myTireService"> 
  <wsdl:types> 
    <xsd:schema targetNamespace="urn:myTireService"> 
      <xsd:element name="recommendedTireSpecsRequest" 
        type="tns:automobileType"> 
      </xsd:element> 
      <xsd:element name="recommendedTireSpecsResponse" 
        type="tns:tireSpecificationsType"> 
      </xsd:element> 
      <xsd:complexType name="automobileType"> 
        <xsd:sequence> 
          <xsd:element name="year" type="xsd:int"></xsd:element> 
          <xsd:element name="make" type="xsd:string"></xsd:element> 
          <xsd:element name="model" type="xsd:string"></xsd:element> 
        </xsd:sequence> 
      </xsd:complexType> 
 
      <xsd:complexType name="tireSpecificationType"> 
        <xsd:attribute name="speedRating" type="xsd:string"></xsd:attribute> 
        <xsd:attribute name="tempRating" type="xsd:string"></xsd:attribute> 
        <xsd:attribute name="tractionRating" 
          type="xsd:string"> 
        </xsd:attribute> 
        <xsd:attribute name="width" type="xsd:int"></xsd:attribute> 
        <xsd:attribute name="ratio" type="xsd:int"></xsd:attribute> 
        <xsd:attribute name="radius" type="xsd:int"></xsd:attribute> 
      </xsd:complexType> 
 
      <xsd:complexType name="tireSpecificationsType"> 
        <xsd:sequence> 
          <xsd:element name="tireSpecification" 
            type="tns:tireSpecificationType" minOccurs="0" 
            maxOccurs="unbounded"> 
          </xsd:element> 
        </xsd:sequence> 
      </xsd:complexType> 
    </xsd:schema> 
  </wsdl:types> 
  <wsdl:message name="getRecommendedTireSpecsRequest"> 
    <wsdl:part name="parameters" type="tns:automobileType" /> 
  </wsdl:message> 
  <wsdl:message name="getRecommendedTireSpecsResponse"> 
    <wsdl:part name="parameters" type='tns:tireSpecificationsType' /> 
  </wsdl:message> 
  <wsdl:portType name="myTireService"> 
    <wsdl:operation name="getRecommendedTireSpecs"> 
      <wsdl:input message="tns:getRecommendedTireSpecsRequest" /> 
      <wsdl:output message="tns:getRecommendedTireSpecsResponse" /> 
    </wsdl:operation> 
  </wsdl:portType> 
  <wsdl:binding name="myTireServiceSOAP" type="tns:myTireService"> 
    <soap:binding style="rpc" 
      transport="http://schemas.xmlsoap.org/soap/http" /> 
    <wsdl:operation name="getRecommendedTireSpecs"> 
      <soap:operation 
        soapAction="urn:myTireService#getRecommendedTireSpecs" /> 
      <wsdl:input> 
        <soap:body use="literal" namespace="urn:myTireService" 
          encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> 
      </wsdl:input> 
      <wsdl:output> 
        <soap:body use="literal" namespace="urn:myTireService" 
          encodingStyle="http://schemas.xmlsoap.org/soap/encoding" /> 
      </wsdl:output> 
    </wsdl:operation> 
  </wsdl:binding> 
  <wsdl:service name="myTireService"> 
    <wsdl:port binding="tns:myTireServiceSOAP" 
      name="myTireService"> 
      <soap:address 
        location="http://localhost/~nagood/phpws/service.php" /> 
    </wsdl:port> 
  </wsdl:service> 
</wsdl:definitions> 

  验证 Web 服务

  完成 WSDL 文件后,可以在 Eclipse 中验证它,从而确保它是有效的。

  在 Eclipse 中验证 Web 服务

  完成 WSDL 文件后,可以在 Eclipse 中验证它,确保它是有效的 WSDL 文件。在 PHP Explorer 中从项目的上下文菜单中选择 Validate,使用 Eclipse 验证文件。只要文件是有效的,您就可以开始构建 PHP Web 服务。

  替代方法:导入一个 WSDL 文件

  如果您已经有了一个 WSDL 文件,因此不需要为 Web 服务构建它,那么可以将这个 WSDL 文件导入到 Eclipse。导入后,您仍然可以对它进行验证或使用 WSDL 可视编辑器进行查看。

  构建 PHP 服务代码

  使用 SOAP 扩展

  PHP 中的 SOAP 扩展允许您使用 PHP 构建 SOAP 客户机和服务器。要在本教程中构建 SOAP 构建客户机,主要使用 PHP 的 SoapClient 类。除了 SoapClient 类外,还提供了用于构建 SOAP 服务器的类(SoapServer)和用于处理 SOAP 消息的类(SoapHeader、SoapFault、SoapParam 和 SoapVar)。

  在 PHP V4 中,SOAP 扩展是一项可选的配置。如果希望使用 SOAP 扩展,则必须使用 --enable-soap 选项启用这个扩展,或者寻找预编译的 PHP 发行版,它已经启用了 SOAP 扩展。在 PHP V6 中,SOAP 扩展已默认为启用。

  启用了 SOAP 扩展后,您可以动态地创建一个 SoapServer,而不需要考虑将您的 PHP 对象序列化到 XML 或将它们从 XML 反序列化到 PHP 类。

  PHP 的 SOAP 扩展

  如果不能确定您的 PHP 版本中是否启用了 SOAP 扩展,可以使用两种方法判断。第一种方法是编写一个仅包含 <?php phpinfo(); ?> 的简要的 PHP 文件并在浏览器中查看,或者从命令行中执行这个文件。另一种方法是使用命令行选项 -m,它将展示 PHP 的编译模块。

  本教程中的 Web 服务演示了如何使用比标准的 echo 或 Hello World 服务(获取一个字符串并返回一个字符串)稍微复杂的 WSDL 文件和类结构构建一个 PHP Web 服务。要构建这个服务,PHP 代码中必须包含某些对象,这些对象被 SOAP 扩展代码映射回 WSDL 文件中的复杂类型。

  支持的类

  在 PHP 服务代码中,尽管不需要担心对象与 XML 之间的序列化和反序列化问题,您也应该构建与 WSDL 文件中的类型对应的类。这里有一些使用 PHP 编写的项目可以提供一些帮助,但是这个服务中只包含三种类型,因此帮助不大。

  构建 Automobile 类

  PHP 代码中要构建的第一个类是 Automobile 类。它实际上映射到 automobileType,但是由于在创建 PHP SoapServer 时能够指定映射,您无需将该类的名称映射到 WSDL 文件中的复杂类型的名称。这使得 PHP 代码更加具有 PHP 的特性,因为 PHP 中的类通常遵循 Pascal 或 upper-camel 命名约定。相比之下,如果在 Web 上浏览网页,则会发现人们很多时候就将 PHP 类的名称与 WSDL 文件中的复杂类型保持一致,大概是这样做可以更容易理解彼此之间的关联。

  Automobile清单 5 展示了 PHP 类。WSDL 文件中公开为元素的字段是该类中的公共字段。注意类中没有出现 accessor。


清单 5. Automobile PHP 类
class Automobile { 
  public $year; // int 
  public $make; // string 
  public $model; // string 
} 

  构建 TireSpecification 类

  第二个类是 TireSpecification 类(参加清单 6)。在 WSDL 文件的类型定义中(如清单 7 所示),针对 speedRating、tempRating 等的字段都是属性。在 PHP 类中,它们仍然被定义为公共字段,正如在清单 5 的 Automobile 类中一样。


清单 6. TireSpecification 类
class TireSpecification { 
  public $speedRating; // string 
  public $tempRating; // string 
  public $tractionRating; // string 
  public $width; // int 
  public $ratio; // int 
  public $radius; // int 
} 


清单 7. automobileType 的 WSDL 定义
<xsd:complexType name="automobileType"> 
<xsd:sequence> 
 <xsd:element name="year" type="xsd:int"></xsd:element> 
 <xsd:element name="make" type="xsd:string"></xsd:element> 
 <xsd:element name="model" type="xsd:string"></xsd:element> 
</xsd:sequence> 
</xsd:complexType> 

  构建 TireSpecificationList 类

  最后,TireSpecificationList 类包含一个字段,这个字段持有一个 TireSpecification 对象数组(参见清单 8)。这将映射回 WSDL 文件中的 tireSpecificationsType 并将成为处理 Web 服务的函数的返回值。


清单 8. TireSpecificationList 类
class TireSpecificationList { 
  public $tireSpecification; // tireSpecificationsType 
} 

  复杂类型都有对应的 PHP 类,因此代码基本上很完整。如果查看 PHP Project 选项卡,将看到一个新类的列表。因此代码需做的是添加一个类作为服务并且告诉 SoapServer 如何处理 WSDL。

  构建服务类

  服务类是一个轻量级类,它包含映射到 WSDL 文件中的操作名的方法。操作如清单 9 所示。注意,名称是相同的,并且函数只包含单个参数,这个参数将是 Automobile 对象。


清单 9. WSDL 操作
<wsdl:binding name="myTireServiceSOAP" type="tns:myTireService"> 
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> 
<wsdl:operation name="getRecommendedTireSpecs"> 
  <soap:operation 
    soapAction="urn:myTireService#getRecommendedTireSpecs" /> 
  <wsdl:input> 
    <soap:body use="literal" namespace="urn:myTireService" 
      encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> 
  </wsdl:input> 
  <wsdl:output> 
    <soap:body use="literal" namespace="urn:myTireService" 
      encodingStyle="http://schemas.xmlsoap.org/soap/encoding" /> 
  </wsdl:output> 
</wsdl:operation> 
</wsdl:binding> 

  为简单起见,我为我的汽车,1993 年的 Nateauto Speedster,(虚构的名字,编辑希望避免商标侵权)硬编码了一些轮胎规格。我制定了一个规则,如果汽车出厂日期早于 1994,则尺寸小一点的轮胎也是推荐的轮胎。

  添加服务器代码

  最后,service.php 文件的末尾列出了服务器代码。SoapServer 使用类映射和几个选项进行了实例化(参见清单 10)。


清单 10. SoapServer 代码
$server = new SoapServer('myTireService.wsdl', 
array('classmap' => $classmap, 
  'soap_version' => SOAP_1_2, 
  'uri' => 'urn:myTireService', 
  'style' => SOAP_RPC, 
  'use' => SOAP_LITERAL)); 
 
$server->setClass('myTireService'); 
$server->handle(); 

  表 1 展示了创建代码的选项。


表 1. 创建 SoapServer 的选项

键名 作用
classmap 将 WSDL 文件中的复杂类型链接到 PHP 类型名称的关联数组。
soap_version SoapServer 支持的 SOAP 规范版本。
uri 用作服务名称空间的统一资源标识符(Universal Resource Identifier,URI)(可以在 WSDL 文件中查看 urn:myTireService)。
style WSDL 方法绑定使用的样式(在本例中使用的是 RPC literal)。
use 将要使用的绑定类型,可以是 SOAP_LITERAL(“literal”)或 SOAP_ENCODED(“encoded”)的其中之一。

  设置 myTireService 类,以便在 handle() 方法处理 post 时调用 getRecommendedTireSpecs() 函数。

  部署代码

  为项目添加构建程序

  尽管 PDT 工具允许您针对一个服务器运行时运行 PHP 脚本并执行 PHP Web 页面,但是这无助于测试 Web 服务,因为您需要向 Web 服务发送一个 SOAP 请求并能够查看响应。因此需要能够向一个 Web 位置发布 service.php 文件和 myTireService.wsdl 文件,您可以在这个 Web 位置从一个测试 SOAP 客户机调用这些文件。

  出于权限和安全性的考虑,您不应该将工作空间放在文档根目录或由 Web 服务发布的文件夹下。较好的方法是将构建程序放到 Eclipse 中,它将把您的文件发布到所选的 Web 文档位置。 要为项目添加新的构建程序,从项目的上下文菜单中单击 Properties。

  在左侧面板中,单击 Builders,如图 13 所示,然后单击 New 为项目添加一个新的构建程序。


图 13. 添加一个新的构建程序


  在 Choose configuration type 窗口中,从列表中选择 Program,然后单击 OK。


图 14. 可用的构建程序


  输入构建程序的名称 — 比如 ServicePublisher。在 Location 字段中,输入对应于操作系统的复制命令的名称,如 /bin/cp。


图 15. 配置新的构建程序以部署服务
 

另一方法:REST 服务

  具象状态传输(Representational State Transfer,REST)是一种使用 Web 服务的架构或风格,而不是 SOAP 这样的标准。REST Web 服务非常简单并且可以使用任何其他标准,例如 HTTP 或 XML。Internet 实质上就是一个巨大的 REST 服务集合,在其中可以通过向服务器提供一个 URL 来生成请求并接收响应文档。诸如 Atom 或 RSS 之类的常见技术都属于 REST 服务。

  作为使用 SOAP 服务的替代方法,您可以使用 PHP 构建 Web 服务。您可以使用现有的 PHP 和 PEAR 对象,例如 PHP V5 中包含的 SimpleXML、XMLReader 和 XMLWriter。

  在 Arguments 字段下,单击 Variables,然后选择变量 ${project_loc} 作为项目基础。记住,您将需要在这个 Arguments 字段中输入实际文件的名称。您不能使用星号(*)或问号(?)这样的通配符,因为它们在发送给命令行之前将由 shell 进行解释。就 /bin/cp 而言,没有名为 * 或 ? 的文件。

  故障排除

  要进行故障排除,一个良好的 SOAP 客户机为您提供了所有 SOAP 故障帮助。如果您的现有 SOAP 客户机没有对错误进行响应,那么考虑使用另一种客户机。其他有用工具包括 Fiddler或其他代理应用程序,可以捕获发往或来自 Web服务的消息。

  在第一次构建 WSDL 文件时,我并没有特别留意并使用文档文字(document literal)创建 WSDL。虽然这对于创建 WSDL 文件是非常好的实践,但是它却不能正常工作,即使将 PHP SoapServer 类设置为使用SOAP_DOCUMENT 和 SOAP_LITERAL。当将 WSDL 设置为文档文字时接收得到的错误为:

Procedure 'getRecommendedTireSpecs' not present. 

  修改 WSDL 以使用 RPC 编码后,收到的错误如下:

Error cannot find parameter. 

  我能够处理除年份元素以外的所有的 automobileType。我最后将 WSDL 修改为使用 RPC 文字,它完全遵从 Web Services Interoperability Organization (WS-I),并允许我使用已经设置的丰富的复杂类型。

  结束语

  首先创建一个 WSDL 文件,然后再创建服务,这就是契约优先开发。通过使用 Eclipse Europa、PDT 和 WST,您可以轻松且可视地创建 WSDL,然后使用 Eclipse Europa 的特性自动将 PHP 服务发布到某个位置。

  PDT 项目使您能够使用一流的 IDE 特性编写 PHP 代码。通过使用 PHP 透视图,您可以更加轻松地导航 PHP 项目。拥有了这些工具和针对 SOAP 和 XML 的内置 PHP 支持,您可以轻松创建 PHP Web 服务。


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3