Php soap wsdl example

Работа с веб-серверами на php посредством SOAP

Не буду останавливаться на вопросе, что такое веб-сервисы и зачем они нужны. В сети очень много статей на эту тему. Просто постараюсь вкратце показать, каким простым способом возможно создание клиента к любому веб-сервису на php.

Для использования SOAP в php необходимо подключить модуль SOAP (входит в дистрибутив php5). Под windows это делается просто – необходимо дописать (именно дописать, так как эта строка там не просто закомментирована, она отсутствует вообще) в php.ini:
extension=php_soap.dll

Не забудьте перезапустить сервер, если php у вас установлен как модуль.

Создание SOAP-клиента по WSDL-документу

Создание SOAP-клиента обычно происходит по WSDL-документу, который представляет собой XML-документ в определенном формате, полностью описывающий тот или иной веб-сервис. За подробностями по поводу WSDL – отправляю Вас на сайт консорциума W3C — www.w3.org/TR/2005/WD-wsdl20-soap11-binding-20050510.

Главное же, что необходимо знать для того, чтобы построить клиента к веб-сервису – это знать URL его WSDL-документа.
Для примера возьмем веб-сервис «Currency Exchange Rate» от xmethods.com. Адрес этого веб-сервиса, который позволяет получать курсы валют в режиме онлайн — www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl.

Второй важный момент – из описания веб-сервиса необходимо получить информацию о том, какие методы этот сервис предоставляет, и какие параметры мы должны передавать ему в качестве входных значений (очень похоже на вызов обычной функции php или метода класса). Обычно эта информация содержится в описании сервиса на его сайте. Наш веб-сервис для получения курса валют предоставляет метод getRate(), которому в качестве аргументов передаются коды валют.

И последнее – важно знать, что ожидать в качестве ответа: сколько значений, какого типа и т.п. Это также можно получить из описания.
А в результате код получается очень простым и компактным, почти элементарным:

Читайте также:  This outer class java

// Использование Web-сервиса
// «Currency Exchange Rate» от xmethods.com

// Создание SOAP-клиента по WSDL-документу
$client = new SoapClient(«http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl»);

// Поcылка SOAP-запроса и получение результата
$result = $client->getRate(«us», «russia»);

echo ‘Текущий курс доллара: ’, $result, ‘ рублей’;
?>

Как видно из кода в конструктор класса SoapClient необходимо передать URL WSDL-документа и получить объект для работы с нужным веб-сервисом. Затем вызывается метод этого объекта, имя которого совпадает с именем самого метода веб-сервиса. Возвращает же этот метод желаемый нами результат.

Итак, этот простой пример иллюстрирует нам принцип построения SOAP-клиента для веб-сервисов на php. Однако в реальном приложении еще о многом придется позаботиться, в частности о том, что в момент обращения к веб-сервису он может быть временно недоступен или возвращать ошибку. Явно напрашивается использование блока try/catch/throw 🙂

Источник

SOAP

PROBLEM (with SOAP extension under PHP5) of transferring object, that contains objects or array of objects. Nested object would not transfer.

SOLUTION:
This class was developed by trial and error by me. So this 23 lines of code for most developers writing under PHP5 solves fate of using SOAP extension.

/*
According to specific of organization process of SOAP class in PHP5, we must wrap up complex objects in SoapVar class. Otherwise objects would not be encoded properly and could not be loaded on remote SOAP handler.

Function «getAsSoap» call for encoding object for transmission. After encoding it can be properly transmitted.
*/
abstract class SOAPable public function getAsSOAP () foreach( $this as $key =>& $value ) $this -> prepareSOAPrecursive ( $this -> $key );
>
return $this ;
>

private function prepareSOAPrecursive (& $element ) if( is_array ( $element )) foreach( $element as $key =>& $val ) $this -> prepareSOAPrecursive ( $val );
>
$element =new SoapVar ( $element , SOAP_ENC_ARRAY );
>elseif( is_object ( $element )) if( $element instanceof SOAPable ) $element -> getAsSOAP ();
>
$element =new SoapVar ( $element , SOAP_ENC_OBJECT );
>
>
>

class PersonList extends SOAPable protected $ArrayOfPerson ; // variable MUST be protected or public!
>

class Person extends SOAPable //any data
>

$client =new SoapClient ( «test.wsdl» , array( ‘soap_version’ => SOAP_1_2 , ‘trace’ => 1 , ‘classmap’ => array( ‘Person’ => «Person» , ‘PersonList’ => «PersonList» ) ));

$PersonList =new PersonList ;

$client -> someMethod ( $PersonList );

?>

So every class, which will transfer via SOAP, must be extends from class SOAPable.
As you can see, in code above, function prepareSOAPrecursive search another nested objects in parent object or in arrays, and if does it, tries call function getAsSOAP() for preparation of nested objects, after that simply wrap up via SoapVar class.

So in code before transmitting simply call $obj->getAsSOAP()

If you are having an issue where SOAP cannot find the functions that are actually there if you view the wsdl file, it’s because PHP is caching the wsdl file (for a day at a time). To turn this off, have this line on every script that uses SOAP: ini_set(«soap.wsdl_cache_enabled», «0»); to disable the caching feature.

Juste a note to avoid wasting time on php-soap protocol and format support.

Until php 5.2.9 (at least) the soap extension is only capable of understanding wsdl 1.0 and 1.1 format.

The wsdl 2.0, a W3C recommendation since june 2007, ISN’T supported in php soap extension.
(the soap/php_sdl.c source code don’t handle wsdl2.0 format)

The wsdl 2.0 is juste the 1.2 version renamed because it has substantial differences from WSDL 1.1.

The differences between the two format may not be invisible if you don’t care a lot.

The typical error message if you provide a wsdl 2.0 format file :
PHP Fatal error: SOAP-ERROR: Parsing WSDL: Couldn’t find in ‘wsdl/example.wsdl’ in /path/client.php on line 9

Was calling an asmx method like $success=$x->AuthenticateUser($userName,$password) and this was returning me an error.

However i changed it and added the userName and password in an array and its now KAWA.

If anyone is trying to use this for accessing Sabre’s web services, it won’t work. Sabre checks the request header «Content-Type» to see if it is «text/xml» . If it is not text/xml then it sends an error back.

You will need to create a socket connection and use that to send the request over.

Here is an example of a php client talking to a asmx server:

// Prepare SoapHeader parameters
$sh_param = array(
‘Username’ => ‘username’ ,
‘Password’ => ‘password’ );
$headers = new SoapHeader ( ‘http://soapserver.example.com/webservices’ , ‘UserCredentials’ , $sh_param );

// Prepare Soap Client
$soapClient -> __setSoapHeaders (array( $headers ));

// Setup the RemoteFunction parameters
$ap_param = array(
‘amount’ => $irow [ ‘total_price’ ]);

// Call RemoteFunction ()
$error = 0 ;
try <
$info = $soapClient -> __call ( «RemoteFunction» , array( $ap_param ));
> catch ( SoapFault $fault ) <
$error = 1 ;
print( »
alert(‘Sorry, blah returned the following ERROR: » . $fault -> faultcode . «-» . $fault -> faultstring . «. We will now take you back to our home page.’);
window.location = ‘main.php’;
» );
>

if ( $error == 0 ) <
$auth_num = $info -> RemoteFunctionResult ;

// Setup the OtherRemoteFunction() parameters
$at_param = array(
‘amount’ => $irow [ ‘total_price’ ],
‘description’ => $description );

// Call OtherRemoteFunction()
$trans = $soapClient -> __call ( «OtherRemoteFunction» , array( $at_param ));
$trans_result = $trans -> OtherRemoteFunctionResult ;
.
> else <
// Record the transaction error in the database

// Kill the link to Soap
unset( $soapClient );
>
>
>
>

Источник

Оцените статью