SOAP
在线手册:中文 英文
PHP手册

SOAP 函数

Table of Contents


SOAP
在线手册:中文 英文
PHP手册
PHP手册 - N: SOAP 函数

用户评论:

admin at localfm dot info (13-Oct-2008 08:01)

As you may find, SOAP functions return result of type stdClass, not array. It means that you'll need to use $row->id instead of $row['id'] which may be inconvenient.

You can cast stdClass to array using this construction:

<?php
$data
= $soap->getMyData($someParams);
$data = (array)$data;

print
$data['field']; // now it works
?>

vIceBerg (24-Sep-2008 03:18)

I have PHP 5.2.5 on my computer. I get this result:

Array
(
    [0] => stdClass Object
        (
            [Client] => stdClass Object
                (
                    [Nom] => LeNom:00000
                    [Prenom] => LePrenom:00000
                )

        )

My host have 5.1.6, the same call returns this result:
Array
(
    [0] => stdClass Object
        (
            [Client] => Array
                (
                    [0] => stdClass Object
                        (
                            [Nom] => LeNom:00000
                            [Prenom] => LePrenom:00000

                        )

5.2.5 is the good structure.

Take care of the version you're using. It can be a lot of work to change all the code

daniel dot harding at chaptereight dot com (28-Jul-2008 04:13)

Setting Attributes for Complex Type Elements PHP5/SOAP
=========================================


// Setting attributes for simple elements:
<parentEl id="ref1">12345</foo>
<?php
array("parentEl" => array("_" => 12345, "id" => "ref1"));
?>

// Setting attributes for complex elements:
<parentEl id="ref1">
    <childEl>blah</childEl>
</parentEl>

'parentEl' => array(
        array('childEl' => 'blah')
    ),
    'id' => 'ref1'
)

nodkz at mail dot ru (24-May-2008 10:28)

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()

aeolianmeson at dontfindme dot blitzeclipse dot com (07-May-2008 04:42)

A quick example to do a login using a WSDL, do a second request using the session ID from the login response, and then dump the XML from that request.

    // Setting "trace" will allow us to view the request that we are making, after we have made it.
    $objClient = new SoapClient("http://www.somewhere.com/wsdls/some.wsdl", array('trace' => true));

    // These parameters satisfy this specific remote call.
    $arrParameters_Login = array('username' => 'username', 'password' => 'password', 'company' => 'Company');

    // Invoke the remote call "login()".
    $objLogin =  $objClient->login($arrParameters_Login);

    // Grab session ID that this remote call will provide.
    $strSessionID = $objLogin->loginReturn->sessionId;

    // Set headers-- The remote call "query()" will require a header pointing to our session.

    $strHeaderComponent_Session = "<SessionHeader><sessionId>$strSessionID</sessionId></SessionHeader>";

    $objVar_Session_Inside = new SoapVar($strHeaderComponent_Session, XSD_ANYXML, null, null, null);
    $objHeader_Session_Outside = new SoapHeader('namespace.com', 'SessionHeader', $objVar_Session_Inside);

    // More than one header can be provided in this array.
    $objClient->__setSoapHeaders(array($objHeader_Session_Outside));

    // Set the query parameters.

    $strQuery = 'select empID from Time where empID = 92389278';
    $arrParameters_Query = array('queryString' => $strQuery);

    // Make call.

    $objResponse = $objClient->query($arrParameters_Query);

    header('Content-Type: text/xml; ');
    print($objClient->__getLastRequest());

The request that goes out:

<SOAP-ENV:Envelope>
    <SOAP-ENV:Header>
        <SessionHeader>
            <sessionId>8789364113604871127</sessionId>
        </SessionHeader>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <ns1:query>
            <ns1:queryString>select empID from Time where empID = 92389278</ns1:queryString>
        </ns1:query>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

rlee at melbournechapter dot net (02-May-2008 01:38)

Just a note on "DTD not recognised..." faults. Check to make sure your wsdl file contains:

<?xml version ='1.0' encoding ='UTF-8' ?> 

Also make sure you use full paths, to your service (in the wsdl, client and server)
...
<wsdlsoap:address location='http://www.mysite.com.au/web_services/myserver.php' />
...
<?php
// SOAP Server
$server = new SoapServer('http://www.mysite.com.au/web_services/hello.wsdl');
...
...
?>

<?php
// SOAP Client
 
$client = new SoapClient('http://www.mysite.com.au/web_services/hello.wsdl');
...
...
?>

FYI im no SOAP expert but I hope this helps someone out ;)

Aurlien Christman (31-Mar-2008 09:34)

From PHP 5, you can use the undocumented method SoapClient::__setLocation() to redefine the target EPR :

<?php

$client
= new SoapClient("some_wsdl");
$client->__setLocation("http://new/target/epr");

$client->someFunction("param1", "param2");

?>

Andr Hnsel (24-Mar-2008 07:42)

Note that HTTP auth is not done when fetching the WSDL file, only when carrying out the actual SOAP request.

Bug #27777 states that it is possible to supply credentials for the WSDL file using URL notation:

<?php
$client
= new SoapClient("http://yourLogin:yourPassword@foo.com/bar.wsdl");
?>

bananos at dev dot co dot ua (17-Mar-2008 12:12)

Be aware when working with long integers in SOAP requests (PHP supports only 32-bit signed int with upper limit of
2147483647 )

If you need to make requests with 64-bit integers consider following code:

<?php

 $ID
= (float) "6146109011";
 
$params["campaignID"] = new SoapVar($ID, XSD_STRING, "string", "http://www.w3.org/2001/XMLSchema");
 
$res    = $client->getCampaign(new SoapParam($params, "getCampaign"));

?>

If you'll try to pass such $ID in a direct way:

<?
  $ID = (float) "6146109011";
  $res    = $client->getCampaign(array('campaignID'  => $ID));
?>

the request will fail, because php_soap.dll will generate

<campaignID>2147483647</campaignID>

and not
<campaignID>6146109011</campaignID>

as expected

thomas dot rabaix at gmail dot com (13-Mar-2008 04:41)

I have set up a small article which explains how to use SOAP with NTLM authentication.

http://tinyurl.com/328rgv (Ghrrr ! the url is too long)

Hope it can help you !

Thomas

Drydenmaker (14-Jan-2008 03:59)

Working with a third party service I got: "SOAP-ERROR: Parsing Schema: unexpected <text> in restriction"

Thought it would be worth it to share.  What it is saying is that there is some text in an invalid place.  C# seems to ignore it, and if you are using nusoap it doesn't notice it either.  But what was causing my problem was something like:
<types>
    <schema ...

            <simpleType name="some type">
                <restriction base="xsd:string">
                    <enumeration value="foo"/>;
                </restriction>
            </simpleType>

Note the semicolon (;).  Filter that out and your good.

sam dot lowry at ministryofinformation dot com (10-Jan-2008 11:52)

From the "I'll just do it manually" school of frustration.

If you've been having trouble getting complex types to work with no, or an entirely non-descript wsdl (my particular complaint... every method just has one child, a complex type element sequence of any... unnngh). Anyway I found the following works to fully replace the contents of the soap body with a pre-built xml string.  I haven't tested what this does for calls expecting multiple parameters, since that usually means I can call it with an actual paremeters argument, but I imagine it would still work the same way.

----------------------------------

$Result=$Client->SomeCall(new SoapVar('<Element attr="AttrValue">ElValue</Element>', XSD_ANYXML));

----------------------------------

it's really quite hackish and I'd prefer to know the proper method to add custom arguments to a SoapVar or SoapParam Object, but this worked and I'm leaving it there for now so can I lose the urge to break things.

NOTE: documentation says XSD_ANYXML wasn't added until 5.1.0

Dominik (07-Dec-2007 09:31)

If you are working
- on localhost
- in WSDL mode
and encounter the following error when you try to connect the soap client with the soap server

Fatal error: Uncaught SoapFault exception: [HTTP] Could not connect to host...

then change "localhost" to "127.0.0.1" in your WSDL file:
<soap:address location='http://127.0.0.1/soap-server.php'/>

Emanuele Colonnelli (06-Dec-2007 01:24)

Hi,

I'd like to add this trick to get SoapClient correctly running with a WSDD-generated Axis 1 webservice.

By default, Apache Axis 1 generates a SOAP RPC/Encoded WSDL with "urn:" prefixes before all <SERVICE_NAME> occurrences.

Axis 1 WSDL also uses an "impl:" namespace prefix.

Suppose your service's name is "myWS", your WSDL will contains a "<wsdl:binding>" element with the name attribute valued "urn:myWSSoapBinding":

<wsdl:binding name="myWSSoapBinding">

PHP SoapClient has a problem (I hope it will be fixed soon ) parsing this WSDL and generates this error:

SOAP-ERROR: Parsing WSDL: No  element with name 'myWSSoapBinding'

This error arise because PHP SoapClient could not resolve the "urn:impl:myWSSoapBinding" QName in generated WSDL:

<wsdl:service name="myWSService">
<wsdl:port binding="impl:urn:myWSSoapBinding" name="urn:myWS">
<wsdlsoap:address location="http://URL/services/urn:myWS"/>
</wsdl:port>
</wsdl:service>

To solve this problem I parse WSDL applying a preg_replace to delete all "urn:" occurrences.

Then I save this generated WSDL somewhere in my site and point my SoapClient to this location.

I also need to specify additional parameters to SoapClient constructor:

<?php
$soap
= new SoapClient("wsdl/myWS.wsdl",
array(   
 
"style" => SOAP_RPC,
 
"use" => SOAP_ENCODED,
 
"soap_version" => SOAP_1_1,
 
"uri"=>"urn:myWS"
));
?>

I suggest you this resources to a full understanding of this kind of problems:

http://www.ibm.com/developerworks/
webservices/library/ws-whichwsdl/

http://wso2.org/wiki/display/wsfphp/
PHP+SOAP+Extension+API+-+Backward+Compatibility

I hope this save you hours of imprecations! :)

Emanuele Colonnelli

AL13N (28-Nov-2007 12:05)

this might be helpful, as it took quite some time for me to find this out:

if you're using some .wsdl and there's a sequence that can be there more than once (ie: maxOccurs > 1), you can specify an non-associative array for it if you have more than 1 items OR you could just specify the one item if there is only one:

<?php
'items' => array(
    array(
       
'itemId' => 5,
       
'name' => 'some name',
    ),
    array(
       
'itemId' => 6,
       
'name' => 'some other name',
    ),
),
?>

this also works:

<?php
'items' => array(
   
'itemId' => 5,
   
'name' => 'some name',
),
?>

Anonymous (27-Nov-2007 04:58)

I had to add the following to be able to call the PHP webservice from .Net Client
It seems that eighter PHPs implementation of SoapServer or Microsofts .Net way is wrong. The Namespace SOAP-ENV must be removed inside of the SOAP-ENV:Body

function callback($input) {
    $search = '/(<SOAP-ENV:Body>)\s*(<SOAP-ENV:)/';
    $replace = '$1<';
    $input = preg_replace($search, $replace, $input);

    $search = '/(<\/SOAP-ENV:)([A-Za-z0-9]*>)\s*(<\/SOAP-ENV:Body>)/';
    $replace = '</$2$3';
    $input = preg_replace($search, $replace, $input);

    return ($input);
}

ob_start('callback');
$server->handle();
ob_end_flush();

Anonymous (26-Nov-2007 07:54)

when dealing with wsdl and flash soap with php
(not exactly php, but proper wsdl - took me hours to figure it to work properly in flash webservice)

when naming definitions,
don't use "tns:" but use "typens:"

makesure your "definitions/targetNamespace"
is same as your "soap:body" namespace
example: "urn:mynamespace"

makesure your "binding/type" is declared with "typens"

makesure your service/port/binding is set to 'typens:...'

if you did not do it properly, you will end up with
WSDL.UnrecognizedNamespace - in flash
but seems okay in php soapclient...

happy coding :)
hope this help you to save your time on the wsdl :)

james at mercstudio dot com (24-Nov-2007 09:45)

If you use wsdl,

makesure you define the input correctly.
if your method does not contain any input parameter,
you got to makesure that you:

 - do not create the message tag for the input..
 - do not put input within porttype / operation
 - do not put input within binding / operation

if not, you will get the error:
[Client] looks like we got no XML

d***, took me several hours figuring that out...

Dennis Du Krger (23-Nov-2007 03:15)

A word of warning:

Do NOT use associative arrays or arrays not starting with element number 0...

Various versions of the soap extension will not send it through properly.

t dot kloppenburg at billiton dot de (22-Nov-2007 11:33)

I had the "DTD are not supported by SOAP" message, too. It helped me to var_dump the complete "SoapFault" exception to find helpful information in a field "["faultstring"]=>....".

It was an error my soap handler (adding a non existant function).

dirk at waferthin dot com (21-Jun-2007 12:31)

I hope this will save someone time. When developing and testing your SOAP server, remember to disable WSDL caching in BOTH client and server:

$ini = ini_set("soap.wsdl_cache_enabled", 0);

jochen dot munz at municons dot com (11-Jun-2007 04:56)

When encountering an error message like this

[faultstring] => Function ("yourMethod") is not a valid method for this service

although it is present in the WSDL etc., be aware that PHP caches the wsdl locally for better performance. You can disable the caching via php.ini/.htaccess completely or remove the cache file (/tmp/wsdl-.. if you are on Linux) to force regeneration of it.

Marcio Annunciato (17-May-2007 10:22)

In case your soap response containts an ampersand, in certain cases you might get an "unterminated entity reference" warning and data might appear truncated (related to bug #36795?). Maybe there is a more formal fix or setting, but since I couldn't find anything I came with the following:

class MySoapClient extends SoapClient {
    function __doRequest($request, $location, $action, $version) {
        $res = parent::__doRequest($request, $location, $action, $version);
        $resx = str_replace('&amp;', '&amp;amp;', $res);
        print_r($resx);
        return ($resx);
    }
}

albert at jool dot nl (27-Mar-2007 10:59)

A note for ppl who use certificates with SOAP under a Windows config: it seems to be required to give the full path to the certificate file - and don't prepend 'file://' :

<?php

$wsdl
= "test.wsdl";
$local_cert = "c:\htdocs\mycert.pem";
$passphrase = "xyz";

$client = new SoapClient($wsdl, array('local_cert' => $local_cert, 'passphrase' => $passphrase);

?>

kroesjnov at hotmail dot com (09-Feb-2007 03:38)

If you dont want to manually maintain the classmap, make sure you use the same names for your PHP object classes and your WSDL complexTypes, and use the following code:

$classmap = array();
$tmpClient = new SoapClient("soapserver.wsdl");
   
foreach($tmpClient->__getTypes() as $type)
{
    $array = split(" ", $type);
    if($array[0] == "struct" && class_exists($array[1]))
    {
        $classmap[$array[1]] = $array[1];
    }
}
unset($tmpClient);
   
$server = new SoapServer("soapserver.wsdl", array("classmap" => $classmap));
unset($classmap);
$server->setClass("someclass");
$server->handle();

Herman Hiddema (07-Feb-2007 02:32)

I recently found that when using SoapClient with client certificates (the 'local_cert' and 'passphrase' options), PHP needs to have CURL enabled. (At least with PHP 5 and Apache on Windows)

I kept getting errors like this:
Unable to set local cert chain file `filename.pem'; Check that your cafile/capath settings include details of your certificate and its issuer in somescript.php on line ##

I tried everything I could find on the net (correct .pem format, constructing and passing my own stream context, etc) but nothing would work. Enabling CURL (by uncommenting extension=php_curl.dll in php.ini) instantly caused my client to work.

brephophagist (18-Jan-2007 05:45)

For those working from a wsdl full of complex types that just want a class structure to hang your code on and not worry about typing in long parameter lists (or creating a script to do so): wsdl2php is a wonderful time-saver. Gets a structure going so you can go in and add what validation and special data munging you need: http://www.urdalen.no/wsdl2php/

Big up yourself, Knut.

Olaf Krische (21-Nov-2006 09:48)

If you use SSL with a cert and password authentication:

$wsdl = "https://ws.ecopatz.de/ProductInfo?wsdl";
$pass = 'a password';
$certFile = "./mycert.pem";

  $client = new SoapClient($wsdl,
    array(
     'local_cert' => $certFile,
     'passphrase' => $pass
    )
  );

If you have problems with the certfile like this:

  Warning: SoapClient::__construct(): Unable to set local cert chain file `./mycert.pem'; Check that your cafile/capath settings include details of your certificate and its issuer in productinfo.php on line 27

then the certFile is probably in the "wrong format" (the wrong format for php maybe). It worked for me, when i appended the content of the private key file and the certificate file to a single file "mycert.pem":

  cat mycert.key >mycert.pem # mycert.key was the private key
  cat mycert.crt >>mycert.pem # mycert.crt was the signed certificate

Thanks to an author somewhere, who pointed to "curl --cert", where this little "so unimportant" dependency has been mentioned.

Ger?me <kontakt at bmservices dot de> (16-Nov-2006 04:27)

When compiling SOAP support for PHP 5.2.0 it was not sufficient to use "--with-soap" in the "./configure" statement. I also had to include "--enable-soap" to get it work.

nico (25-Aug-2006 02:20)

If you want to build a Soap Server for Microsoft Office's client (like Microsoft Office Research Service) you need to rewrite SOAP's namespaces :

<?php
// (...)

$server = new SoapServer($wsdl, array('uri' => $uri, 'classmap' => $classmap));
$server->setClass($class);
function
callback($buffer)
{
   
$s = array('<ns1:RegistrationResponse>', 'ns1:', 'xmlns:ns1="urn:Microsoft.Search"');
   
$r = array('<RegistrationResponse xmlns="urn:Microsoft.Search">', '', '');
   return (
str_replace($s, $r, $buffer));
}
ob_start('callback');
$server->handle();
ob_end_flush();

// (...)
?>

There are a complete example at this URL : http://touv.ouvaton.org/article.php3?id_article=104

info at webability dot info (22-Aug-2006 08:30)

If you want to use soap over https, you *must* compile php with the configure option with-openssl or you will have the error "[HTTP] SSL support not available in this build" while trying to use the web services over SSL

mini at freebsd dot org (09-Jul-2006 12:54)

wokan at cox dot net is incorrect about the security of URI-passed values to HTTPS URIs.  HTTPS connections are HTTP inside SSL -- all of the HTTP traffic, including the request, are encrypted.

lists at 5etdemi dot com (14-Mar-2006 02:26)

To enable SoapClient on Windows, simply add a line:

extension=php_soap.dll

in php.ini in the extensions section.

adm (01-Mar-2006 07:27)

Wondering why the function you just added to your WSDL file is not available to your SOAP client? Turn off WSDL caching, which (as the documentation says) is on by default.

At the top of your script, use:

$ini = ini_set("soap.wsdl_cache_enabled","0");

Matthew Glubb (20-Jan-2006 04:05)

For anyone wondering why they are getting a "DTD are not supported by SOAP" fault string. It is because you are probably being returned an HTML page due to an internal server error, 404, etc.

Refer to the documentation for SoapClient->__getLastResponse in order to see what returned by the server.

ckl at ecw dot de (17-Jan-2006 07:54)

To debug a SOAP service using SoapServer(), a WSDL file and Zend Studio Client/Server, you have to append ?start_debug=1&amp;debug_port=10000 to the service location:
--- snip ---
... method / service definition ....

<service name="SOAPService">
  <port
    name="SOAPServicePort"
    binding="typens:SOAPServiceBinding">
   <soap:address
   location="$URL?start_debug=1&amp;debug_port=10000"/>
  </port>
</service>
--- snap ---

Rui Martins (18-Dec-2005 04:33)

Here's an example on how to pass ArrayOfAnyType arguments
containing complex types.

Suppose your WSDL file defines "http://any.url.com/" as the default namespace and a complex type "SomeComplexType".

If you want to call a WebServices which takes an ArrayOfAnyType argument of "SomeComplexType"s you need to perform the following:

<?php
// complexTypes being an array containing several instances of SomeComplexType

myWSParameter = array();
foreach (
complexTypes as ct)
{
  
// Don't misspell the type or the namespace. Also note that php won't assume the default namespace defined in the WSDL file.
  
myWSParameter []= new SoapVar(ct, 0, "SomeComplexType", "http://any.url.com/");
}
?>

On the other hand, when a WebService returns an ArrayOfAnyType you have to do the following to access each of its elements.

<?php
// Here, we will be echoing each return item
$res = $someWS->myFunction($myArgs)

// If only one element is returned, an array won't be built
if (is_array(myFunctionResult->anyType))
{
   foreach (
myFunctionResult->anyType as $soapVar)
   {
      echo
$soapVar->enc_value;
   }
}
else
{
   echo
myFunctionResult->anyType->enc_value;
}
?>

This has all been tested using a .NET WebService.

ChrisB (24-Oct-2005 07:03)

Heads up for anyone using PHP Soap + Sessions + PEAR DB classes.

Every time you make a call, via the soap client to your web service, your PEAR DB session is put to sleep and it doesnt by default wake upon the next request.

To fix this I simply called my particular database close call ifx_close() below my $soap->handle();

Bob (11-Oct-2005 09:17)

If you are scratching your head why NuSOAP not working on PHP 5.x , the reason is this built-in SOAP Extenstion uses same soapclient() class name as Nusoap.

replace 'soapclient' with 'soapclient_xxx'  in nusoap.php and you are good to go...

johnjawed at gmail dot com (22-Sep-2005 05:29)

For those wondering on how to set attributes on nodes with PHP5 SOAP, it would be done as such:

<... soap env/header>
<foo bar="blah">12345</foo>

array("foo" => array("_" => 12345, "bar" => "blah"));

Darryl (20-Jul-2005 07:46)

Having trouble passing complex types over SOAP using a PHP SoapServer in WSDL mode?  Not getting decoded properly?  This may be the solution you're looking for!

When using ComplexType in the schema portion of the WSDL file, You need use an additional step to tell PHP SOAP how to encode the objects.  The first method would be to explicitely encapsulate the object in a SoapVar object - telling PHP to use generalized SOAP encoding rules (which encodes all ComplexTypes as Structs).  This won't work, though, if the client is expecting the objects to be encoded according to the WSDL's schema.  So, The actual way to do this is:

* First, define a specific PHP class which is actually just a data structure holding the various properties, and the appropriate  ComplexType in the WSDL.

<?php
 
class MyComplexDataType {
     public
$myProperty1;
     public
$myProperty2;
 }
?>
<complexType name="MyWSDLStructure">
 <sequence>
    <element name="MyProperty1" type="xsd:integer"/>
    <element name="MyProperty2" type="xsd:string"/>
 </sequence>
 </complexType>

* Next, Tell the SoapServer when you initialize it to map these two structures together.

<?php
 $classmap
= array('MyWSDLStructure' => 'MyComplexDataType');
 
$server = new SoapServer("http://MyServer/MyService.wsdl", array('classmap' => $classmap))
?>

* Finally, have your method return an instance of your class directly, and let the SoapServer take care of encoding!

<?php
 
public function MySoapCall() {
    
$o = new MyComplexDataType();
 
    
$o->myProperty1 = 1;
    
$o->myProperty2 = "MyString";
 
     return
$o
 
}
?>

Jim Plush (13-Jul-2005 12:45)

If you're trying to use the SOAP Extension over SSL with a custom PEM file you need to do this:

$client->_local_cert = "C:\\path\myCert.pem";

pash_ka (18-May-2005 08:52)

One good tutorial on using this extension is on IBM web site:
"Using the PHP 5 SOAP extension to consume a WebSphere Web service"
http://www.ibm.com /developerworks/library/os-phpws/?ca=dgr-lnxw06PHP5soap

flobee at gmail dot com (11-May-2005 09:25)

wow, actually a cool program and soap is new for me.
I found out some interessting things i can not debug because the scripts exit without any error messages or notes. :-(

you may have problems with the memory and/or especially on "shared servers" when server load is high.
sometimes the script does the job, sometimes it just stopping at any unknown point.
these are the steps my script does:
* get data from remote server ( ~ 4.5 MB)
* parsing requested object and store the data in a database.

the return with debug messages was intressting:
-> check Mem limit: 30M
-> $client = new new SoapClient($url_wsdl, $options);
-> Memory usage: 185888
-> $client->[requested_method_to_get_data]();
-> check: __getLastResponseHeaders() - after:
-> HTTP/1.1 200 OK // remote server is fine with me :-)
-> Content-Length: 4586742  // I got the data
-> check: Memory usage now: 23098872 // ups !!! this can't be true!!

so, and if now someone on the server takes the rest of RAM  the walk thought the data breaks :-(

so, i need to store the xml tree ($client->client->__last_response) and parsing it by the classical way. (if you would request more RAM, you may get in trouble with the admin if you run a script like this more often! (on shared servers)

OrionI (18-Apr-2005 04:12)

If you're having problems calling a .NET web service, see the comments over on http://php.net/soap_soapclient_soapcall (the __soapCall method).

kucerar at hhmi dot org (25-Mar-2005 08:04)

Here are 73 test cases that detail the kinds of schemas that PHP5 currently supports and the structures you are expected to plug into them for the return value from your services.   Much better than trying to guess!

http://cvs.php.net/co.php/pecl/soap/tests/schema

You can cycle through the listings by changing the main index in the URL below,  rather than go in and out of the pages

http://cvs.php.net/co.php/pecl/soap/tests/schema/schema052.phpt?r=1.2

I downloaded the whole thing with this,  CVS might work too.
http://www.httrack.com/

With them all downloaded I just browse them with Textpad.

Norman Clarke <norman at dontblink dot com> (22-Feb-2005 12:29)

Note that if you should need to set the timeout for your soap request,  you can use ini_set to change the value for the default_socket_timeout. I previously used NuSOAP, whose soap client class has a timeout option, and it took me a while to figure out that PHP's soap uses the same socket options as everything else.

wokan at cox dot net (06-Feb-2005 01:06)

It's not good security practice to pass the username and password in the URI when the point of SSL is to prevent that information from being intercepted.  Putting that information in the URI makes it interceptable.  HTTPS-Posted values are safe because values passed in the headers are sent after the SSL handshake has been completed.

mikx at mikx dot de (29-Mar-2004 04:12)

It took me a while to properly establish a password protected client connection via https on windows/apache1.3. Here my little guide:

1. The SOAP extension isn't activated by default (PHP5 RC1). Just add "extension=php_soap.dll" to the php.ini and don't forget to set the extension_dir properly (in most cases "c:\php\ext").

2. Add "extension=php_openssl.dll" to the php.ini. This module depends on libeay32.dll and ssleay32.dll - copy them from your php folder to your system32 folder.

3. Restart apache

4. The sourcecode

$client = new SoapClient("https://yourLogin:yourPassword@foo.com/bar.wsdl", array(
    "login"      => "yourLogin",
    "password"   => "yourPassword",
    "trace"      => 1,
    "exceptions" => 0));

$client->yourFunction();

print "<pre>\n";
print "Request: \n".htmlspecialchars($client->__getLastRequest()) ."\n";
print "Response: \n".htmlspecialchars($client->__getLastResponse())."\n";
print "</pre>";

Currently it seems to be necessary to add your login and password both in the uri and in the options array. Not sure if this is the expected behavior.