PHP > LIBRARY > PHP SOAP Extension
 
PHP
Library
Tip&Tech
Q&A
 
PHP Function
phpschool
그누보드
LIBRARY
  HOME > PHP > LIBRARY
 
PHP SOAP Extension
작성일 : 10-03-09
조회 : 6,367  

PHP SOAP Extension

  • Apache Php Mysql|2005/11/21 17:06
  • http://blog.paran.com/sputnik/7029392 글주소복사 By Dmitry Stogov

    March 16, 2004

Intended Audience
Introduction
A First SOAP Client
?  Example 1 (client1.php)
?  Example 2 (client2.php)
?  A First SOAP Server
?  Example 3 (stockquote.wsdl)
?  Example 4 (server1. php)
?  Example 5 (client3.php)
?  Example 6 (server2.php)
?  Example 7 (client4.php)
What's inside?
?  Example 8 (client5.php)
Other Implementations of SOAP for PHP
Summary
References
About the Author
Revision Date

Intended Audience

This article describes the new SOAP extension for PHP. It is intended for PHP developers who want to write their own Web Services servers, or use SOAP to access existing ones. It assumes some familiarity with Web Services, SOAP, and WSDL (Web Services Description Language).

Introduction

SOAP (Simple Object Access Protocol) is a lightweight XML-based protocol for exchanging structured information between distributed applications over native web protocols, such as HTTP. SOAP specifies the formats that XML messages should use, the way in which they should be processed, a set of encoding rules for standard and application-defined data types, and a convention for representing remote procedure calls and responses.

Web Services is a modern and very popular technology. The list of protocols and technologies related to Web Services grows every day, but SOAP is probably the most important. It is rapidly becoming the standard protocol for accessing Web Services. It uses XML messages to exchange information across endpoints, and provides several advantages over other binary protocols. RPC (Remote Procedure Calls) support was originally a minor element in the design of SOAP, but this feature is one of the most useful it has today.

PHP 5's SOAP extension is the first attempt to implement the SOAP protocol for PHP in C. It has some advantages over the existing implementations written in PHP itself, the main one being speed. The extension is currently marked as experimental, but should gradually become more stable and reliable as time progresses.

The SOAP extension implements a large subset of SOAP 1.1, SOAP 1.2 and WSDL 1.1 specifications. The key goal is to use the RPC feature of the SOAP protocol. WSDL is used where possible in order to make the implementation of Web Services more straightforward.

A First SOAP Client

To demonstrate how to make a simple SOAP Client, we'll take the XMethods demo service, “Delayed Stock Quote”, as our target. Before we start to write any PHP code, we'll need to gather some information about this particular service:

  • The method name
  • The endpoint URL where the service is running
  • The SOAPAction header value for the method
  • The namespace URI for the method
  • Input and output parameter names and types
Happily, all this information is available on the XMethods web site at http://www.xmethods.com/ in the form of the service's RPC profile:

Method Name getQuote
Endpoint URL http://64.124.140.30:9090/soap
SOAPAction urn:xmethods-delayed-quotes#getQuote
Method Namespace URI urn:xmethods-delayed-quotes
Input Parameters Symbol
String
Output Parameters Result
float

Example 1 (client1.php)

<?php

$client
= new SoapClient(NULL
,
        array(
        
"location" => "http://64.124.140.30:9090/soap"
,
        
"uri"      => "urn:xmethods-delayed-quotes"
,
        
"style"    => SOAP_RPC
,
        
"use"      =>
SOAP_ENCODED
           
));

print(
$client->__call
(
        
/* SOAP Method Name */
        
"getQuote"
,
        
/* Parameters */
        
array(
            new
SoapParam
(
                
/* Parameter Value */
                
"ibm"
,
                
/* Parameter Name */
                
"symbol"
        
)),
        
/* Options */
        
array(
            
/* SOAP Method Namespace */
            
"uri" => "urn:xmethods-delayed-quotes"
,
            
/* SOAPAction HTTP Header for SOAP Method */
            
"soapaction" =>
"urn:xmethods-delayed-quotes#getQuote"
        
)). "\n"
);
?>

As you can see, this simple task required a lot of work

Fortunately, Web Services can describe themselves to the client using WSDL, and generally they achieve this successfully. The location of the WSDL document for the XMethods “Delayed Stock Quote” service is given on the information page for that service at xmethods.com:

http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl

Here is the same PHP SOAP client, rewritten using that WSDL document. Now we don't need to specify the endpoint URI, namespace, SOAPAction header, encoding style and parameter types. All the information comes from the WSDL file.

Example 2 (client2.php)

<?php
$client
= new
    
SoapClient
(
        
"http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl"
    
);

print(
$client->getQuote("ibm"
));
?>

That's a little easier, isn't it?

What are the problems with WSDL? The only argument against using it is that the client has to load the relevant WSDL document from the server before the RPC can be made, and this can take a significant amount of time in a Web environment. In order to speed things up, PHP's ext/soap uses a WSDL caching feature that can be controlled through setting the soap.wsdl_cache_enabled, soap.wsdl_cache_dir and soap.wsdl_cache_ttl configuration directives, either in your php.ini or by using ini_set()(see Example 4 ). By default, WSDL caching is turned on and caches WSDL files for one day.

Here is the SOAP section for php.ini with default values. You can paste it into your php.ini.


[soap]

soap.wsdl_cache_enabled = "1"
; enables or disables WSDL caching feature

soap.wsdl_cache_dir = "/tmp"
; sets the directory name where SOAP extension will put cache files

soap.wsdl_cache_ttl = "86400"
; (time to live) sets the number of second while cached file will be used
; instead of original one

A First SOAP Server

Let's try to write our own SOAP Web service that will do the same as the XMethods “Delayed Stock Quote” service.

The first task is to create a WSDL document describing our service in a format that client requests will understand. This requires minor modifications to the original document taken from the Xmethods site, so we'll start by taking a close look at that file.

The message section defines two messages. The first is getQuoteRequest, which is a request to relay the getQuote message and takes one string parameter called symbol. The other is getQuoteResponse, which is a response to the getQuote message, containing one float value, named Result.

The portType section defines one operation, getQuote, which describes which of the messages listed in the message section will be used to transmit the request and response.

The binding section defines how the messages must be transmitted and encoded. Here it tells us that we will be sending an RPC request using SOAP encoding across HTTP. It also specifies namespace and value of the SOAPAction header for the getQuote method.

Lastly, the service section defines the endpoint URL where the service is running.

Example 3 (stockquote.wsdl)

<?xml version ='1.0' encoding ='UTF-8' ?>
<definitions name='StockQuote'
  targetNamespace='http://example.org/StockQuote'
  xmlns:tns=' http://example.org/StockQuote '
  xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
  xmlns:xsd='http://www.w3.org/2001/XMLSchema'
  xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
  xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
  xmlns='http://schemas.xmlsoap.org/wsdl/'>

<message name='getQuoteRequest'>
  <part name='symbol' type='xsd:string'/>
</message>
<message name='getQuoteResponse'>
  <part name='Result' type='xsd:float'/>
</message>

<portType name='StockQuotePortType'>
  <operation name='getQuote'>
    <input message='tns:getQuoteRequest'/>
    <output message='tns:getQuoteResponse'/>
  </operation>
</portType>

<binding name='StockQuoteBinding' type='tns:StockQuotePortType'>
  <soap:binding style='rpc'
    transport='http://schemas.xmlsoap.org/soap/http'/>
  <operation name='getQuote'>
    <soap:operation soapAction='urn:xmethods-delayed-quotes#getQuote'/>
    <input>
      <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
        encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
    </input>
    <output>
      <soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
        encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
    </output>
  </operation>
</binding>

<service name='StockQuoteService'>
  <port name='StockQuotePort' binding='StockQuoteBinding'>
    <soap:address location='http://[insert real path here]/server1.php'/>
  </port>
</service>
</definitions>

Note: The WSDL caching feature is on by default. During the development of your WSDL file it should be turned off.

Now it's time to create our server.

First, we'll implement the getQuote() function, which will be accessed as a service function by incoming request messages from the web. Next, we'll create a SoapServer object and connect it with the service function using SoapServer::addFunction() method. As you will see, the SoapServer() constructor has only one parameter: the path of the WSDL document that describes the service.

Example 4 (server1. php)

<?php
$quotes
= array(
  
"ibm" =>
98.42
);  

function
getQuote($symbol
) {
  global
$quotes
;
  return
$quotes[$symbol
];
}

ini_set("soap.wsdl_cache_enabled", "0");
// disabling WSDL cache
$server = new SoapServer("stockquote.wsdl"
);
$server->addFunction("getQuote"
);
$server->handle
();
?>

The SoapServer can work without a WSDL document in much the same way that the SoapClient can, but there are no obvious benefits to be had from setting it up in this way. Were you to do so, you should ensure that the return values are special objects of the SoapParam and SoapVar classes (as in the first example).

Here is a client for accessing our own SOAP server. Nothing has changed from the previous example except the WSDL location. It assumes that “stockquote.wsdl” is in the same directory as our SOAP server.

Example 5 (client3.php)

<?php
  $client
= new SoapClient("stockquote.wsdl"
);
  print(
$client->getQuote("ibm"
));
?>

What are the problem areas with our server and client?

To start with, they don't handle errors. What happens when the server doesn't recognize the requested symbol? The SOAP protocol specifies a special format of messages for reporting errors ? SoapFault. To generate such messages the server should throw an exception using the SoapFault object. The first parameter to the SoapFault() constructor is a fault code string, and the second is a fault description string. The client should be written in such a way as to catch SoapFault exceptions.

Secondly, it would be better to encapsulate Web Service functionality in a PHP class. In this case we wouldn't need to use global variables and add each SOAP method to the server individually; we could add an entire class, and all its methods would be accessible through SOAP.

Save stockquote.wsdl as stockquote2.wsdl, and alter the soap:address on line 43 to point to server2.php. A modified version of our SOAP server and client follows:

Example 6 (server2.php)

<?php
class QuoteService
{
  
private $quotes = array("ibm" => 98.42
);  

  function
getQuote($symbol
) {
    if (isset(
$this->quotes[$symbol
])) {
      return
$this->quotes[$symbol
];
    } else {
      
throw new SoapFault("Server","Unknown Symbol '$symbol'."
);
    }
  }
}

$server = new SoapServer("stockquote2.wsdl"
);
$server->setClass("QuoteService"
);
$server->handle
();
?>

As you can see, I have used the SoapServer::setClass() method to connect the SoapServer object with the QuoteService class.

Example 7 (client4.php)

<?php
  $client
= new SoapClient("stockquote2.wsdl"
);
  
try
{
    echo
"<pre>\n"
;
    print(
$client->getQuote("ibm"
));
    echo
"\n"
;
    print(
$client->getQuote("microsoft"
));  
    echo
"\n</pre>\n"
;
  }
catch (SoapFault $exception
) {
    echo
$exception
;      
  }
?>

What's inside?

Are you curious about the SOAP message format, or hoping to debug a SOAP client of your own? If so, this section is for you.

The SoapClient() constructor accepts an associative array as its second parameter, as you already saw in the first example. Various options can be passed through this associative array. Here are just two:

  • trace ? allows the client to store SOAP requests and responses (turned off by default)
  • exceptions ? allows the client to control the exception mechanism (turned on by default)
Take a look at the following SOAP client example. It is derived from example 5, and shows precisely what is transmitted between the client and the server. In order to retrieve this information we use the SoapClient methods __getLastRequest() and __getLastResponse().

Example 8 (client5.php)

<?php
  $client
= new SoapClient("stockquote.wsdl"
,array(
    
"trace"      => 1
,
    
"exceptions" => 0
));
  
$client->getQuote("ibm"
);
  print
"<pre>\n"
;
  print
"Request :\n".htmlspecialchars($client->__getLastRequest()) ."\n"
;
  print
"Response:\n".htmlspecialchars($client->__getLastResponse())."\n"
;
  print
"</pre>"
;
?>

Here is the output of the script. It is modified a little, to make it more easily understood.

Request :
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:ns1="urn:xmethods-delayed-quotes"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
  <ns1:getQuote>
    <symbol xsi:type="xsd:string">ibm</symbol>
  </ns1:getQuote>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Response:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:ns1="urn:xmethods-delayed-quotes"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
  <ns1:getQuoteResponse>
    <Result xsi:type="xsd:float">98.42</Result>
  </ns1:getQuoteResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>


 
 

Total 25
번호 제   목 조회
공지 php 라이브러리 117
25 php 라이브러리 117
24 isset, empty, is_null의 상관 관계와 정보 요약 / define(), de… 1382
23 cookie(쿠키) & session(세션) 4777
22 PHP4 + NuSOAP 4218
21 Java + PHP SOAP 모듈 설치 4735
20 PHP SOAP Extension 6368
19 PHP를 이용한 웹 서비스 개발(3) 3286
18 PHP를 이용한 웹 서비스 개발(2) 3126
17 PHP를 이용한 웹 서비스 개발(1) 3872
16 파일-텍스트 카운터 만들기/파일-이미지 카운터 만들기/DB-이미… 2718
15 간단한 문자열분리,찾기,변환 => explode,substr,strstr,ereg… 7678
14 php 이전 경로를 알아내는 함수 6400
13 php 함수정리 1 5443
12    php 함수정리 all 4190
11 CLASS 3647
10 GD and Image 함수 목록 6226
9 file()관련함수 4047
8 array 배열 함수 목록 4116
7 String 함수 목록 3745
6 each() 2996
 1  2  
 
개인홈페이지 덤벙닷컴은 프로그래머와 디자이너위한 IT커뮤니티 공간입니다.
Copyright ⓒ www.dumbung.com. All rights reserved.