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.
<?php
/*
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);
}
}
}
// ------------------------------------------
// ABSTRACT EXAMPLE
// ------------------------------------------
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;
// some actions
$PersonList->getAsSOAP();
$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()
PHP.mk документација
SOAP
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
Патека
book.soap.php
Локална патека за оваа страница.
Извор
php.net/manual/en
Оригиналниот HTML се реупотребува и локално се стилизира.
Режим
Прокси + преведен приказ
Кодовите, табелите и белешките остануваат читливи во истиот тек.
Референца
book.soap.php
SOAP
Референца за `book.soap.php` со подобрена типографија и навигација.
SOAP
Вовед
SOAP екстензијата може да се користи за пишување SOAP сервери и клиенти. Таа поддржува подмножества од SOAP екстензијата може да се користи за пишување SOAP сервери и клиенти. Поддржува подмножества на, » SOAP 1.1 and » SOAP 1.2 specifications.
- Installing/Configuring
- Претходно дефинирани константи
- SOAP функции
- is_soap_fault » WSDL 1.1
- use_soap_error_handler — Проверува дали SOAP повикот не успеал
- SoapClient — Класата SoapClient
- SoapClient::__call — Поставува дали да се користи SOAP ракувачот за грешки
- SoapClient::__construct — Повикува SOAP функција (застарена)
- SoapClient::__doRequest — SoapClient конструктор
- SoapClient::__getCookies — Извршува SOAP барање
- SoapClient::__getFunctions — Добива листа на колачиња
- SoapClient::__getLastRequest — Враќа листа на достапни SOAP функции
- SoapClient::__getLastRequestHeaders — Враќа последното SOAP барање
- SoapClient::__getLastResponse — Враќа SOAP заглавја од последното барање
- SoapClient::__getLastResponseHeaders — Враќа последен SOAP одговор
- SoapClient::__getTypes — Враќа SOAP заглавја од последниот одговор
- SoapClient::__setCookie — Враќа листа на SOAP типови
- SoapClient::__setLocation — Дефинира колаче за SOAP барања
- SoapClient::__setSoapHeaders — Поставува локација на веб-сервисот што треба да се користи
- SoapClient::__soapCall — Поставува SOAP заглавја за последователни повици
- SoapServer — Класата SoapServer
- SoapServer::addFunction — Додава една или повеќе функции за обработка на SOAP барања
- SoapServer::addSoapHeader — Додава една или повеќе функции за обработка на SOAP барања
- SoapServer::__construct — Додај SOAP заглавие во одговорот
- SoapServer::fault — Конструктор на SoapServer
- SoapServer::getFunctions — Издава SoapServer грешка што укажува на проблем
- SoapServer::__getLastResponse — Враќа SOAP заглавја од последното барање
- SoapServer::handle — Враќа список на дефинирани функции
- SoapServer::setClass — Обработува SOAP барање
- SoapServer::setObject — Поставува класа што ги обработува SOAP барањата
- SoapServer::setPersistence — Поставува објект што ќе се користи за обработка на SOAP барања
- SoapFault — Класата SoapFault
- SoapFault::__construct — Поставува режим на перзистентност на SoapServer
- SoapFault::__toString — Конструктор на SoapFault
- SoapHeader — Класата SoapHeader
- SoapHeader::__construct — Добива текстуална претстава на SoapFault
- SoapParam — Класата SoapParam
- SoapParam::__construct — Конструктор на SoapHeader
- SoapVar — Класата SoapVar
- SoapVar::__construct — Конструктор на SoapParam
Белешки од корисници Управување со PDO конекции
— Конструктор на SoapVar ¶
пред 17 години
nodkz на mail dot ru ¶
пред 16 години
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 wsdl 1.0 format structure (see http://www.w3.org/TR/wsdl) :
<definitions ...>
<types ...>
</types>
<message ...>
<part ...>
</message>
<portType ...>
<operation ...>
<input ... />
<output ... />
<fault ... />
</operation>
</portType>
<binding ...>
<operation ...>
<input ... />
<output ... />
<fault ... />
</operation>
</binding>
<service ...>
<port ...>
</service>
</definitions>
And the wsdl 2.0 format structure (see http://www.w3.org/TR/wsdl20/) :
<description ...>
<types ...>
</types>
<interface ...>
<fault ... />
<operation ...>
<input ... />
<output ... />
<fault ... />
</operation>
</interface>
<binding ...>
<fault ... />
<operation ...>
<input ... />
<output ... />
<fault ... />
</operation>
</binding>
<service ...>
<endpoint ...>
</service>
</description>
The typical error message if you provide a wsdl 2.0 format file :
PHP Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't find <definitions> in 'wsdl/example.wsdl' in /path/client.php on line 9
Raphal Gertz ¶
пред 16 години
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.
moazzam на moazzam-khan dot com ¶
пред 17 години
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.
Ryan ¶
пред 16 години
Here is an example of a php client talking to a asmx server:
<?php
$soapClient = new SoapClient("https://soapserver.example.com/blahblah.asmx?wsdl");
// 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;
if ($auth_num < 0) {
....
// 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);
}
}
}
}
?>
stephenlansell на gmail dot com ¶
пред 10 години
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...
rafinskipg на gmail точка ком ¶
пред 13 години
Support for MTOM addign this code to your project:
<?php
class MySoapClient extends SoapClient
{
public function __doRequest($request, $location, $action, $version, $one_way = 0)
{
$response = parent::__doRequest($request, $location, $action, $version, $one_way);
// parse $response, extract the multipart messages and so on
//this part removes stuff
$start=strpos($response,'<?xml');
$end=strrpos($response,'>');
$response_string=substr($response,$start,$end-$start+1);
return($response_string);
}
}
?>
Then you can do this
<?php
new MySoapClient($wsdl_url);
?>