PHP Doku:: SoapClient-Konstruktor - soapclient.soapclient.html

Verlauf / Chronik / History: (4) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzWeb ServicesSOAPThe SoapClient classSoapClient::SoapClient

Ein Service von Reinhard Neidl - Webprogrammierung.

The SoapClient class

<<SoapClient::__soapCall

The SoapServer class>>

SoapClient::SoapClient

(PHP 5 >= 5.0.1)

SoapClient::SoapClientSoapClient-Konstruktor

Beschreibung

SoapClient::SoapClient ( mixed $wsdl [, array $options ] )

Der Konstruktor erstellt SoapClient-Objekte im WSDL- oder non-WSDL-Modus.

Parameter-Liste

wsdl

URI der WSDL-Datei oder NULL, wenn der non-WSDL-Modus verwendet werden soll.

Hinweis:

Während der Entwicklung sollte das WSDL-Caching durch die Verwendung der soap.wsdl_cache_ttl-Option in der php.ini ausgeschaltet werden. Andernfalls wirken sich Änderungen an der WSDL-Datei erst aus, wenn soap.wsdl_cache_ttl abgelaufen ist.

options

Ein Array aus Optionen. Wenn im WSDL-Modus gearbeitet wird, ist dieser Parameter optional. Im non-WSDL-Modus müssen die Optionen location und uri gesetzt sein. Dabei enthält location den anzufragenden URL und uri den Zielnamensraum des SOAP-Dienstes.

Die Optionen style und use funktionieren nur im non-WSDL-Modus. Im WSDL-Modus werden sie durch das WSDL-File bestimmt.

Die Option soap_version gibt an, ob der SOAP 1.1- (Standardvorgabe) oder der SOAP 1.2-Client verwendet werden soll.

Die Optionen login und password können verwendet werden, um Daten für die HTTP-Authentifizierung zu übergeben. Um eine Verbindung über einen Proxy-Server herzustellen, stehen die Optionen proxy_host, proxy_port, proxy_login und proxy_password zur Verfügung. Für Authentifizierung über HTTPS-Client-Zertifikate nutzen Sie die Optionen local_cert und passphrase. Eine Authentifizierung kann in der authentication-Option mit Werten befüllt werden. Die Authentifizierungsmethode kann dabei entweder SOAP_AUTHENTICATION_BASIC (Standardvorgabe) oder SOAP_AUTHENTICATION_DIGEST sein.

HTTP-SOAP-Anfragen und -Antworten können mit Hilfe von compression komprimiert werden.

Die Option encoding definiert die intern verwendete Zeichenkodierung. Sie ändert nicht die Kodierung der SOAP-Anfrage selbst (die bleibt immer utf-8), es werden lediglich die Zeichenketten konvertiert.

Die trace-Option schaltet das Tracing von Anfragen ein. Damit können fehler zurückverfolgt werden. Der Standardwert ist FALSE.

Die classmap-Option kann verwendet werden, um WSDL-Typen auf PHP-Klassen abzubilden. Die Option muss ein Array mit den WSDL-Typen als Schlüssel und den PHP-Klassennamen als Wert sein.

Das Setzen der trace-Option aktiviert den Gebrauch der Methoden SoapClient->__getLastRequest, SoapClient->__getLastRequestHeaders, SoapClient->__getLastResponse und SoapClient->__getLastResponseHeaders.

Die Option exceptions ist ein boolscher Wert. Sie definiert, ob bei SOAP-Fehlern Exceptions vom Typ SoapFault geworfen werden sollen.

Zeitüberschreitung in Sekunden für Verbindungen zu einem SOAP-Service können mit der Option connection_timeout angegeben werden. Diese Option definiert keine Zeitüberschreitung für Dienste mit langsamen Antwortzeiten. Um zu definieren, wie lange auf die Beendung einer Anfrage gewartet werden soll, steht die Einstellung default_socket_timeout zur Verfügung.

Die Option typemap ist ein Array mit Typabbildungen. Jede Abbildung ist ein Array mit den Schlüsseln type_name, type_ns (Namespace-URI), from_xml (Callback akzeptiert einen String-Parameter) und to_xml (callback akzeptiert einen Objekt-Parameter).

Die Option cache_wsdl ist eine der folgenden Konstanten: WSDL_CACHE_NONE, WSDL_CACHE_DISK, WSDL_CACHE_MEMORY oder WSDL_CACHE_BOTH.

Die Option user_agent gibt die Zeichenkette an, die im User-Agent-Header verwendet werden soll.

Die Option stream_context ist eine Ressource auf context.

The features option is a bitmask of SOAP_SINGLE_ELEMENT_ARRAYS, SOAP_USE_XSI_ARRAY_TYPE, SOAP_WAIT_ONE_WAY_CALLS.

Beispiele

Beispiel #1 SoapClient::SoapClient()-Beispiel

<?php

$client 
= new SoapClient("ein.wsdl");

$client = new SoapClient("ein.wsdl", array('soap_version'   => SOAP_1_2));

$client = new SoapClient("ein.wsdl", array('login'          => "ein_name",
                                           
'password'       => "ein_passwort"));

$client = new SoapClient("ein.wsdl", array('proxy_host'     => "localhost",
                                           
'proxy_port'     => 8080));

$client = new SoapClient("ein.wsdl", array('proxy_host'     => "localhost",
                                           
'proxy_port'     => 8080,
                                           
'proxy_login'    => "ein_name",
                                           
'proxy_password' => "ein_passwort"));

$client = new SoapClient("ein.wsdl", array('local_cert'     => "cert_key.pem"));

$client = new SoapClient(null, array('location' => "http://localhost/soap.php",
                                     
'uri'      => "http://test-uri/"));

$client = new SoapClient(null, array('location' => "http://localhost/soap.php",
                                     
'uri'      => "http://test-uri/",
                                     
'style'    => SOAP_DOCUMENT,
                                     
'use'      => SOAP_LITERAL));

$client = new SoapClient("ein.wsdl",
  array(
'compression' => SOAP_COMPRESSION_ACCEPT SOAP_COMPRESSION_GZIP));

$server = new SoapClient("ein.wsdl", array('encoding'=>'ISO-8859-1'));

class 
MyBook {
    public 
$title;
    public 
$author;
}

$server = new SoapClient("books.wsdl", array('classmap' => array('book' => "MyBook")));

?>


38 BenutzerBeiträge:
- Beiträge aktualisieren...
faebu at faebu dot ch
21.12.2010 15:58
I'm experiencing the same problems when trying to load a WDSL fiel which is protected by basic http authentication, since the parameters login and password are just used for the request but not when reading the wdsl file. I just use the following workaround by downloading the xml file to a non-protected location on my server. Please notice that this doesn't support any kind of caching.

Hope it helps

<?php
class SoapAuthClient extends SoapClient {
   
/**
     * Since the PHP SOAP package does not support basic authentication
     * this class downloads the WDSL file using the cURL package and
     * creates a local copy of the wdsl on your server.
     * Make sure you provide the following additional parameter in the
     * $options Array:
     * wdsl_local_copy => true
     */
    
   
private $cache_dir = '/home/example/htdocs/cache/';
    private
$cache_url = 'http://www.example.com/cache/';
    
    function
SoapAuthClient($wdsl, $options) {
        if (isset(
$options['wdsl_local_copy']) &&
           
$options['wdsl_local_copy'] == true &&
            isset(
$options['login']) &&
            isset(
$options['password'])) {
           
       
           
$file = md5(uniqid()).'.xml';
           
            if ((
$fp = fopen($this->cache_dir.$file, "w")) == false) {
                throw new
Exception('Could not create local WDSL file ('.$this->cache_dir.$file.')');
            }
                       
           
$ch = curl_init();
           
$credit = ($options['login'].':'.$options['password']);
           
curl_setopt($ch, CURLOPT_URL, $wdsl);
           
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
           
curl_setopt($ch, CURLOPT_USERPWD, $credit);
           
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
           
curl_setopt($ch, CURLOPT_FILE, $fp);
            if ((
$xml = curl_exec($ch)) === false) {
               
//curl_close($ch);
               
fclose($fp);
               
unlink($this->cache_dir.$file);
                               
                throw new
Exception(curl_error($ch));
            }
           
           
curl_close($ch);
           
fclose($fp);
           
$wdsl = $this->cache_url.$file;
        }
       
       
        unset(
$options['wdsl_local_copy']);
        unset(
$options['wdsl_force_local_copy']);
       
        echo
$wdsl;
       
parent::__construct($wdsl, $options);
       
       
unlink($this->cache_dir.$file);
    }
}
?>
tatupheba at gmail dot com
20.12.2010 23:30
Hello folks!

A hint for developers:

When programming some soap server set the "soap.wsdl_cache_enabled" directive in php.ini file to 0:

soap.wsdl_cache_enabled=0

Otherwise it will give a bunch of strange errors saying that your wsdl is incorrect or is missing.

Doing that will save you from a lot of useless pain.
titan at phpdevshell dot org
6.10.2010 15:11
It should be noted that if you receive a return error : 'Object reference not set to an instance of an object.'. This could be due to something as simple as passing the incorrect parameters. When you look at this XML:

    <Get xmlns="http://example.com">
      <request>
        <CustomerId>string</CustomerId>
        <From>dateTime</From>
        <To>dateTime</To>
      </request>
    </Get>

Your code should look something like this:

<?php
       
try {
           
$options = array(
               
'soap_version'=>SOAP_1_2,
               
'exceptions'=>true,
               
'trace'=>1,
               
'cache_wsdl'=>WSDL_CACHE_NONE
           
);
           
$client = new SoapClient('http://example.com/doc.asmx?WSDL', $options);
// Note where 'Get' and 'request' tags are in the XML
           
$results = $client->Get(array('request'=>array('CustomerId'=>'1234')));
        } catch (
Exception $e) {
            echo
"<h2>Exception Error!</h2>";
            echo
$e->getMessage();
        }

$results = $client->Get(array('request'=>array('CustomerId'=>'842115')));
?>
marcovtwout at hotmail dot com
29.06.2010 17:30
If your WSDL file containts a parameter with a base64Binary type, you should not use base64_encode() when passing along your soap vars. When doing the request, the SOAP library automatically base64 encodes your data, so otherwise you'll be encoding it twice.

WSDL snipplet:
<element name="content" type="base64Binary" xmime:expectedContentTypes="*/*"/>

<?php
$string
= 'data_you_want_to_send___like_xml_in_soap';
$soap_data = array(
       
'foo' => 'bar',
     
//'content' => base64_encode($string ) // don't do this
       
'content' => $string //do this
);
$response = $client->Send($soap_data);
?>
marcovtwout at hotmail dot com
26.06.2010 15:20
Being new to SOAP, I was searching for a while to find out why my message was getting a response in soapUI, but not with my php code. The specific service I was addressing gives a HTTP 202 Accepted on success (no response), but returns a SOAP message on errors.

Situation:
Using an (authenticated) client connection, and a WDSL file, SOAP calls with type "One-Way" don't give a response header, even though a response is expected.

Solution:
When calling the client constructor, set SOAP_WAIT_ONE_WAY_CALLS in the $options['features'].
tim at tdinternet dot com
10.06.2010 17:05
PHP 5.2.11 seems to not be very picky about the correctness of a WSDL.

Other SOAP clients were complaining about schema and namespace issues, while PHP's SoapClient worked completely fine.  Fixing those issues for the other clients however broke PHP's SoapClient to the point where objects being passed to the SOAP method were becoming empty arrays on the server side.

Lesson learned:  some elements were being prefixed with xsd: and others were not -- make absolutely sure your WSDL is correct and consistent (I'm using a tweaked WSDL_Gen.php).
james dot ellis at gmail dot com
10.06.2010 4:06
I was having troubles getting responses from a Coldfusion SOAP server, with no obvious issues in the SoapClient used.

Eventually I found that the server was only accepting SOAP 1.1 requests and not 1.2. Not sure if this is  a system wide Coldfusion setting but if you hit the same wall, try setting the SoapClient option "soap_version" to the constant SOAP_1_1 (which is the default but mine was defaulting to 1.2 as the client was being reused for another service)
ajcartmell at fonant dot com
9.06.2010 12:57
There seems to be a problem with specifying empty strings for proxy_host and proxy_port options in recent versions of PHP (from a version later than 5.2.9, and equal to or earlier than 5.2.11).

Supplying empty string values for proxy_host and proxy_port causes "host not found" type errors: supplying NULL or FALSE works fine.
reinaldo at mandic dot com dot br
25.05.2010 16:43
You need both certificates, privateKey and publicKey on the same file, on local_cert path to work.

# cat publicKey.pem privateKey.pem > key.pem
bhargav dot khatana at gmail dot com
11.04.2010 20:10
It took me longer than a week to figure out how to implement WSSE (Web Service Security) headers in native PHP SOAP. There are no much resource available on this, so thought to add this here for community benefit.

Step1: Create two classes to create a structure for WSSE headers

<?php
class clsWSSEAuth {
          private
$Username;
          private
$Password
        function
__construct($username, $password) {
                
$this->Username=$username;
                
$this->Password=$password;
              }
}

class
clsWSSEToken {
        private
$UsernameToken;
        function
__construct ($innerVal){
           
$this->UsernameToken = $innerVal;
        }
}
?>

Step2: Create Soap Variables for UserName and Password

<?php
$username
= 1111;
$password = 1111;

//Check with your provider which security name-space they are using.
$strWSSENS = "http://schemas.xmlsoap.org/ws/2002/07/secext";

$objSoapVarUser = new SoapVar($username, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);
$objSoapVarPass = new SoapVar($password, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);
?>

Step3: Create Object for Auth Class and pass in soap var

<?php
$objWSSEAuth
= new clsWSSEAuth($objSoapVarUser, $objSoapVarPass);
?>

Step4: Create SoapVar out of object of Auth class

<?php
$objSoapVarWSSEAuth
= new SoapVar($objWSSEAuth, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'UsernameToken', $strWSSENS);
?>

Step5: Create object for Token Class

<?php
$objWSSEToken
= new clsWSSEToken($objSoapVarWSSEAuth);
?>

Step6: Create SoapVar out of object of Token class

<?php
$objSoapVarWSSEToken
= new SoapVar($objWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'UsernameToken', $strWSSENS);
?>

Step7: Create SoapVar for 'Security' node

<?php
$objSoapVarHeaderVal
=new SoapVar($objSoapVarWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'Security', $strWSSENS);
?>

Step8: Create header object out of security soapvar

<?php
$objSoapVarWSSEHeader
= new SoapHeader($strWSSENS, 'Security', $objSoapVarHeaderVal,true, 'http://abce.com');

//Third parameter here makes 'mustUnderstand=1
//Forth parameter generates 'actor="http://abce.com"'
?>

Step9: Create object of Soap Client

<?php
$objClient
= new SoapClient($WSDL, $arrOptions);
?>

Step10: Set headers for soapclient object

<?php
$objClient
->__setSoapHeaders(array($objSoapVarWSSEHeader));
?>

Step 11: Final call to method

<?php
$objResponse
= $objClient->__soapCall($strMethod, $requestPayloadString);
?>
peter at webacoustics dot com
1.04.2010 7:58
I found that WSDL fetching fails when using basic authentication in the soapclient. So I implemented the following workaround using wget. I realize wget may not be an option for some environments, in that case cURL would be the next simplest thing.

<?php
$wsdl
= get_wsdl("https://example.com/soap/service?wsdl");
$this->client = new SoapClient($wsdl, array('user'=>'someuser', 'password'=>'somepassword'));

private function
get_wsdl($url) {
    global
$g;
   
$url = escapeshellarg($url);
   
$cache_file = "/tmp/soap.wsdl." . md5($url);
   
   
//only fetch a new wsdl every hour
   
if(!file_exists($cache_file) || filectime($cache_file) < time() - 3600) {
       
$agent = escapeshellarg("--user-agent={$g['useragent']}");
       
mwexec("wget --quiet --timeout=5 {$agent} --no-check-certificate --output-document={$cache_file} {$url}");
        if(!
file_exists($cache_file)) {
            throw new
Exception("Couldn't load WSDL at {$url}");
        }
    }
    return
$cache_file;
}
?>
meltir at meltir dot com
29.03.2010 15:59
To those fighting with NTLM authenticated proxy servers, here's a solution I'm using atm:

<?php
/**
 * A child of SoapClient with support for ntlm proxy authentication
 *
 * @author Meltir <meltir@meltir.com>
 *
 */
class NTLM_SoapClient extends SoapClient {
   
    public function
__construct($wsdl, $options = array()) {
        if (empty(
$options['proxy_login']) || empty($options['proxy_password'])) throw new Exception('Login and password required for NTLM authentication!');
       
$this->proxy_login = $options['proxy_login'];
       
$this->proxy_password = $options['proxy_password'];
       
$this->proxy_host = (empty($options['proxy_host']) ? 'localhost' : $options['proxy_host']);
       
$this->proxy_port = (empty($options['proxy_port']) ? 8080 : $options['proxy_port']);
       
parent::__construct($wsdl, $options);
    }
   
   
/**
     * Call a url using curl with ntlm auth
     *
     * @param string $url
     * @param string $data
     * @return string
     * @throws SoapFault on curl connection error
     */
   
protected function callCurl($url, $data) {
   
$handle   = curl_init();
   
curl_setopt($handle, CURLOPT_HEADER, false);
   
curl_setopt($handle, CURLOPT_URL, $url);
   
curl_setopt($handle, CURLOPT_FAILONERROR, true);
   
curl_setopt($handle, CURLOPT_HTTPHEADER, Array("PHP SOAP-NTLM Client") );
   
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
   
curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
   
curl_setopt($handle, CURLOPT_PROXYUSERPWD,$this->proxy_login.':'.$this->proxy_password);
   
curl_setopt($handle, CURLOPT_PROXY, $this->proxy_host.':'.$this->proxy_port);
   
curl_setopt($handle, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);
   
$response = curl_exec($handle);
    if (empty(
$response)) {
      throw new
SoapFault('CURL error: '.curl_error($handle),curl_errno($handle));
    }
   
curl_close($handle);
    return
$response;
    }
   
    public function
__doRequest($request,$location,$action,$version,$one_way = 0) {
        return
$this->callCurl($location,$request);
    }
   
}
?>

Requires curl and could be extended, but it works for my simple needs.
eric dot caron at gmail dot com
31.01.2010 22:26
Though pointed out by jan at bestbytes, and discussed in bug #27777, one common source of the "Parsing WSDL: Couldn't find <definitions>" error is from trying to access a WSDL that is protected by HTTP authentication. Passing the login/password in the 2nd parameter doesn't always work; so if you encounter this error message and are trying to access a protected WSDL file, try passing the username and password in with the first parameter.
Anonymous
10.01.2010 15:53
I had to struggle with a rather strange behavior when trying to consume standard Parlay X web services with no success. However, I found a remedy to my problem.

The problem which I faced was about an erroneous invalid HTTP basic authentication request sent to the web service. Although I was sending the right credentials, I was getting an authentication error. It turns out that PHP was sending HTTP requests to another endpoint which is not exposed directly through the web service and that end point does not require authentication.

My remedy for that issue was by using this simple lines in the example of using sendSms Paraly-X method.

First, creating a soap client without any HTTP authentication options:

<?php
$client
= new SoapClient($wsdl_url);            
?>

The above request will cache the wsdl in the /tmp directory. Immediately after this construction we create another soap client, this time with HTTP authentication options:

<?php
try {                                           
       
$client = new SoapClient($wsdl_url, array('login' => "griffin",
                                           
'password'       => "password"));
} catch (
Exception $e) {                          
       
printf("Error:sendSms: %s\n",$e->__toString());
        return
false;                             
}
?>

Now it should work without any problem. Without the second call, PHP will call sendSms without credentials resulting in a failed attempt due to missing authentication information. I found this procedure to be the simplest.

This process should be done every time the cached wsdl expires, or simply a one can increase the time-to-live for the cached wsdl from php.ini
jon dot gilbert at net-entwicklung dot de
12.12.2009 18:55
Note that creating a soap client for an invalid URL (you do test what happens, when a service is not available, right?) usually throws an exception which can be caught with try..catch. However, if xdebug is active you will get a fatal error, which obviously cannot be caught.
sloloem at gmail dot com
19.10.2009 22:14
I had an issue figuring out the use of classmap that took me quite a while to figure out.  I was assuming the WSDL type the docs were referring to was the name of the element being returned in the SOAP, so like,
<ns1:node id="8675309" />

and I was wondering why mapping
'classmap'=>array('node'=>'MyNode')

did nothing.
That's because in my WSDL I defined node as:

<xsd:element name="node" type="tns:nodeType" />

The classmap I needed was:
'classmap'=>array('nodeType'=>'MyNode')

I was able to find the type names using SoapClient->__getTypes()
Later, I realized where I could look inside the WSDL for the typename I needed.

I dunno if I missed something painfully obvious but maybe this can clear up some of the docs.
Jon
6.05.2009 12:13
We've had some problems using SoapClient connecting to an external server via Microsoft ISA (presently v.2006 but this may apply to other versions too). We supply the proxy_host, proxy_port, proxy_login and proxy_password but the ISA server reports the login in its logs as "anonymous".

Our sysadmin believes this is because PHP is not supplying NTLN information (Windows security protocol) in the correct format (and whether it should work with proprietary proxies is of course another debate). We'd tried "username", "DOMAIN\username" to no effect. The solution is to add an exception in the ISA server for the target hostname/IP; null can then be supplied for proxy_login and proxy_password and the connection should then work as expected.

On a slightly related note, if you are having problems make sure the port number is supplied as an integer. Some versions of PHP will not use the proxy with SoapClient if the port number is supplied as a string.
jan at bestbytes dot de
12.02.2009 16:32
You CAN get a wsdl, if basic authentication is required:

<?php

$login
= 'bert';
$password = 'berts password';

$client = new SoapClient(
   
'http://' . urlencode($login) . ':' . urlencode($password) . '@www.server.com/path/to/wsdl',
    array(
       
'login' => $login,
       
'password' => $password
   
)
);

?>
info at nicksilvestro dot net
10.11.2008 7:40
For anyone having trouble with ArrayOf_xsd_string and getting an error similar to 'No deserializer defined for array type {http://www.w3.org/2001/XMLSchema}string'
Try using the 'features' param, set to SOAP_USE_XSI_ARRAY_TYPE - this makes sure the correct deserializer is used.

eg,
<?php
$client
= new SoapClient("some.wsdl", array('features' => SOAP_USE_XSI_ARRAY_TYPE));
?>
sniper
28.09.2008 8:46
i was looking for a good example and couldnt find one,
finally found it somewhere(forgot where) i think this is
the best example to make a soap request with multiple params
  
$params->AWSAccessKeyId = AMAZON_API_KEY;
$params->Request->SearchIndex = 'Books';
$params->Request->Keywords = 'php5 oop';

$amazon = new SoapClient('http://webservices.amazon.com
/AWSECommerceService/AWSECommerceService.wsdl');
$result = $amazon->itemSearch($params);
taras dot dot dot di at gmail dot com
16.09.2008 18:23
This took me a while to figure out.

As described at the bottom of here: http://bugs.php.net/bug.php?id=38703

having xdebug may interfere with the constructor throwing exceptions
alex on reutone comma com
10.09.2008 15:53
To connect PHP SOAP to MS SOAP (CRM/EXCHANGE/...) I have created some classes using the explanation below and in other places.
www.reutone.com/heb/articles.php?instance_id=62&actions=show&id=521
naugtur at gmail dot com
19.06.2008 15:48
SoapFault exception: [Client] looks like we got no XML document in <document> has been already mentioned to occur when your server outputs something before <?xml ... > tag.

For
all those having problems with that, and no access to the server code:
This is how to make a proxy that would clean responses for You

<?php
/**
 * Simple class taken from a note by James Ellis [in __doRequest() page of manual]
 */
class Proxy_Client extends SoapClient {
    protected
$cacheDocument = "";
    public function
__construct($wsdl, $options) {
       
parent::__construct($wsdl, $options);
    }

   
/**
     * SetCacheDocument() sets the previously cached document contents
     */
   
public function SetCacheDocument($document) {
       
$this->cacheDocument = $document;
    }

   
/**
     * __doRequest() overrides the standard SoapClient to handle a local request
     */
   
public function __doRequest() {
        return
$this->cacheDocument;
    }
}

//put this code in your function or wherever You have all required variables set

$client = new SoapClient($wsdl_url,$settings_array);
$void=$client->$method($params);  //call this to get response from server
       
$response_string=$client->__getLastResponse();
       
//this part removes stuff
$start=strpos($response_string,'<?xml');
$end=strrpos($response_string,'>');   
$response_string=substr($response_string,$start,$end-$start+1);

//get your proxy prepared
$proxy = new Proxy_Client($wsdl_url,$settings_array);
//and fill it with the server's response
$proxy->SetCacheDocument($response_string);

$and_finally_the_result_is=$proxy->$method($params);

print_r($and_finally_the_result_is); //this allows You to see what's there

?>

$method is the method's name eg. $method='getVersion';
$params - typical params for a soap method
david at globulebleu dot com
9.06.2008 9:44
When using classmap option to map the SOAP results to a class, the constructor
of the object you've mapped to is not called.

$client = new SoapClient("url_to_wsdl",
   array('classmap' => array('contact' => "Contact"));

$params = array("1");

$contact = $client->__soapCall("get_contact", $params);

Expected result:

A contact object that has properties initialized (i.e. db connections,
....).

Actual result:

A contact object without the properties.

Thanks for your help.

David Georges.
Anno v. Heimburg
27.05.2008 19:23
> When using HTTP basic authentication, PHP will only send
> the credentials when invoking the service, not when
> fetching the WSDL.

The same goes for using an SSL client certficate, the SoapClient will only present the certificate on the actual remote call, not when getting the WSDL. The workaround is the same as above. HttpRequest works as expected.
cw at netresearch dot de
30.04.2008 10:24
The "cache_wsdl" option takes constants like WSDL_CACHE_NONE or WSDL_CACHE_DISK that are listed on the "SOAP constants" page -> /manual/en/soap.constants.php
james dot ellis at gmail dot com
30.01.2008 2:10
A note regarding boolean values that may seem obvious on reflection but could be a gotcha for some:

Seeing a SOAP request example with <SomeBooleanParam>true</SomeBooleanParam> may lead you to pass in string "true" or "false" as the parameter, which is incorrect - the correct method is to use boolean data types.

<?php
$client
= new SoapClient($wsdl,$options);
$method = "DoSomething";
$params = new stdClass;

$params->SomeBooleanParam = TRUE;
$client->$method($params);
/**
 simplified request snippet would be
 <SomeBooleanParam>true</SomeBooleanParam>
**/

//this will also be correct, but not for the right reasons:
$params->SomeBooleanParam = "true";
$client->$method($params);
/**
 simplified request snippet would be
 <SomeBooleanParam>true</SomeBooleanParam>
**/

//this is where you may be wondering what is going on
$params->SomeBooleanParam = "false";
$client->$method($params);
/**
 simplified request snippet would be
 <SomeBooleanParam>true</SomeBooleanParam>
**/

//you need to do this instead
$params->SomeBooleanParam = FALSE;
$client->$method($params);
/**
 simplified request snippet would be
 <SomeBooleanParam>false</SomeBooleanParam>
**/
?>

Hope that helps!
dastephdev (at) gmail.com
20.12.2007 11:22
If you want to use compression there is a missing parameter in the example above:

<?php
$client
= new SoapClient("some.wsdl",
  array(
'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5));
?>

If you use SOAP_COMPRESSION_GZIP you have to add the compression level. Otherwise it will not compress the request. Took me some hours ;)

Stephan
giosh94mhz
8.07.2007 20:46
Oops!

I have written the wrong exception message in my last post.

The correct exception is:

SoapFault exception: [Client] looks like we got no XML document in <document>
giosh94mhz
8.07.2007 20:28
If you get the following exception:

'Cannot open the XML file: the file is not well-formatted!'

PHP files of your SOAP-server contains syntax-error (probably).

If everything looks ok, try to remove EVERY blank-space and new-line outside the <?php ... ?> tag... this should save you an headache!
lsmith at php dot net
8.02.2007 16:20
As noted in the bug report http://bugs.php.net/bug.php?id=36226, it is considered a feature that sequences with a single element do not come out as arrays. To override this "feature" you can do the following:

$x = new SoapClient($wsdl, array('features' =>
SOAP_SINGLE_ELEMENT_ARRAYS));
matt_schiros at academicsuperstore dot com
30.11.2006 21:26
When using classmap to map the SOAP results to a class, the constructor of the object you've mapped to is _not_ called.  This applies to the PHP5 __construct() and the PHP4 ClassName() constructors.
Marius Mathiesen
1.03.2006 13:57
I kept having a problem using an HTTP proxy with SOAP. The proxy_port parameter has to be an integer, ie. "proxy_port"=>"80" won't work, you'll have to use "proxy_port"=>80.

HTH,
Marius
php at sowen dot de
22.12.2005 15:40
If you're using CLI and there are multiple IP addresses available for outgoing SOAP-requests, try this "secret" to set outgoing IP:

e.g. for local IP 10.1.4.71:

$opts = array('socket' => array('bindto' => '10.1.4.71:0'));
$context = stream_context_create($opts);
$client  = new SoapClient(null, array('location'=>'http://...','uri' => '...','stream_context' => $context));

You can also set other options for the stream context, please refer to this page:

Appendix M: http://www.php.net/manual/en/wrappers.php

Bye,
   Nils Sowen
jared at ws-db dot com
28.08.2005 23:31
If you connect to a SoapServer, that has been created with session persistence, you can access the server's session id via SoapClient->_cookies[<session_id_name>][0]. This property becomes available after your first client method call.

I have only tested this with session.use_cookies=1.
Arjan van Bentem
12.08.2005 8:31
When using HTTP basic authentication, PHP will only send the credentials when invoking the service, not when fetching the WSDL.

To solve this, one needs to fetch the WSDL manually (or using PHP, of course!) and store it on the file system. Obviously, the first parameter for SoapClient(..) then needs to refer to that local copy.

Alternatively, the user annotations at http://nl3.php.net/manual/en/ref.soap.php state that one could encode the login and password into the URL as well.

See http://bugs.php.net/bug.php?id=27777
Jim Plush
11.07.2005 21:56
As of version 5.0.4 you can now dynamically change your location even if you're using a wsdl

<?php

$client
= new SoapClient("http://some.host.net/wsdl/somefile.wsdl",array(
   
"location" => 'myurl.com'));

?>

notice you can now use the "location" key.
This means you can have the same wsdl file not define a location until runtime which is great if you have a development test site or if you distribute your files to other companies.
Prior to this change you would have to ship a custom wsdl file to every client you had with their location hardcoded.
Brian Grayless
4.03.2005 23:30
Using a WSDL file is the way to go, however, for my particular application, the LOCATION:PORT needed to be dynamic so that my SOAP clients would be able to call a different service based on the client domain.

If you are using a WSDL, SoapClient() requires a URL direct to an actual URL and does not let you use a PHP file that outputs the dynamic WSDL XML in its stead. So, I ended up making a separate WSDL for each possible service needed and had to maintain them all if the service description changed.

Finally, after some fiddling, I was able to create a PHP page with the proper Mime type headers so that I could then trick SoapClient() to think that it was being passed a file with a ".wsdl" extension.

Example:

<?php

// filename: wsdl.php

header('Content-Type: application/xml; charset=UTF-8');
header('Content-Disposition: attachment; filename="filename.wsdl"');

$wsdl = 'path/wsdl_name.wsdl';

// read in file
$handle = fopen($wsdl, "r");
$wsdl_xml = fread($handle, filesize($wsdl));
fclose($handle);

// put code here to replace url and port in xml

echo $wsdl_xml;

?>

Now, in order to make this work, you can't just call a relative path to the file. I believe it has to go through Apache to properly set the mime type headers, etc... So you would use a full "http://....." address as the path to the wsdl.php file.

<?php

//... somewhere in your soap client code

$wsdl_loc = "http://yourdomain.com/wsdl.php";

$soap_client = new SoapClient($wsdl_loc, $client_param_array);

?>

Another, perhaps not so clean, way of achieving this would be to modify your .htaccess file in the directory where your WSDL file exists to force ".wsdl" files to run through the PHP engine. Add the following to your .htaccess:

AddType application/x-httpd-php .php .wsdl

You can then put dynamic PHP code snippets in your *.wsdl files to change whatever values you need to.

There are pros and cons to each solutions. The Mime solution probably taxes the system more as it has to read the file in every time a soap request is made. The htaccess solution makes it so you have to depend on either a modified .htaccess or Apache conf file.

Perhaps if you set the "soap.wsdl_cache_enabled", using ini_set(), to 1 (default), the caching will make it so it doesn't read the file every time for the Mime solution.



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)