(PHP 5 >= 5.0.1)
The SoapClient class provides a client for » SOAP 1.1, » SOAP 1.2 servers. It can be used in WSDL or non-WSDL mode.
$request
, string $location
, string $action
, int $version
[, int $one_way
= 0
] )$function_name
, array $arguments
[, array $options
[, mixed $input_headers
[, array &$output_headers
]]] )Guillermo Prandi (2012-02-20 14:10:37)
To make an HTTPS call with a client certificate, you can do it this way:
1) Create a file containing both the key and the signed certificate. I did this by concatenating my (.pem) key and the certificate I've got signed from my CA (also .pem format). The file looked like this:
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKagQC1N27Ilb9pWil2NaX2qM8FquXBXK5T1AydOv7sCotsc8MAwbi7
......(snip)......
wAiOCD4K9TyMS76pIS8UyfJl/oIrn7EF24BUpaUfsh8=
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIC/zCCAmigAwIBAgIEAIl1JzANBgkqhkiG9w0BAQQuADBQMQswCQYxVQQGEaJV
......(snip)......
eSPds1hLKYSg0bd3uI7LhaDLOC1PPgb77sYe/uYkUWuHBzllts5x/pfue0zaIBKG
Omjy
-----END CERTIFICATE-----
2) Reference your certificate in the creation of the SOAP client, like this:
$protected_url = "https://my-server/?wsdl";
$my_cert_file = "/my/path/to/mycert.pem";
$client = new SoapClient($protected_url, array('local_cert', $my_cert_file) );
egiardina at badatmath dot com (2011-08-03 18:05:31)
This one drove me nuts... if you are connecting to a web service run on Cassini, (Visual Studio's web server) from php, you may not be able to call web service functions or load a WSDL out-of-the-box.
My set up is that I am using xampp on my windows development machine, and also using Visual Studio's built in web-server. I built a web service in visual studio. I wrote a simple PHP script, running under xampp, to access this service, so the two projects can 'talk' to each other. What I found was the WSDL was never loaded.
So I moved the WSDL local to the PHP file and accessed it directly. Still no calls. Turns out, PHP's SoapClient seems to have a problem with 'localhost' as a web service endpoint. So I hand-edited the web service endpoint URL to read 127.0.0.1 instead of localhost, and Voila! Web Service calls work:
Here is my PHP, now working:
<?php
$client = new SoapClient("http://localhost/code/soap.wsdl");
$something = $client->HelloWorld(array());
echo $something->HelloWorldResult;
die();
?>
Here is my modified WSDL:
<wsdl:service name="MyService">
<wsdl:port name="MyServiceSoap" binding="tns:MyServiceSoap">
<soap:address location="http://127.0.0.1:55274/MyService/MyService.asmx" />
....
</wsdl:port>
stepan dot zarubin at gmail dot com (2011-06-30 11:51:23)
Well, this example works fine:
<?php
try {
$x = @new SoapClient("non-existent.wsdl");
} catch (Exception $e) {
echo $e->getMessage();
}
?>
Just make sure use NEW with @.
tlk (2011-05-19 06:35:39)
Make sure to prefix constructor calls with @ and catch SoapFault exceptions, otherwise you risk having the php interpreter exit/die on simple network issues.
Robust sample code by Rasmus from http://bugs.php.net/bug.php?id=47584
<?php
try {
$x = @new SoapClient("non-existent.wsdl",array("exceptions" => 1));
} catch (SoapFault $E) {
echo $E->faultstring;
}
echo "ok\n";
?>
jjlopez (2011-03-09 11:36:12)
If you are making soap calls in WSDL mode , and the address of your web service includes a port different from 80 (like http://my_ip_address:8080//service.asmx?wsdl), the WSDL file is fetched correctly, but all subsequent requests are made without any port in the host field. This causes a SoapFault exception when trying to call any of the service’s methods.
You need to redefine the soapClient class and force the port in each call.
See this example:
http://www.victorstanciu.ro/php-soapclient-port-bug-workaround/
hugues at zonereseau dot com (2011-02-17 21:17:31)
When you need to connect to services requiring to send extra header use this method.
Here how we can to it with PHP and SoapClient
<?php
class exampleChannelAdvisorAuth
{
public $DeveloperKey;
public $Password;
public function __construct($key, $pass)
{
$this->DeveloperKey = $key;
$this->Password = $pass;
}
}
$devKey = "";
$password = "";
$accountId = "";
// Create the SoapClient instance
$url = "";
$client = new SoapClient($url, array("trace" => 1, "exception" => 0));
// Create the header
$auth = new ChannelAdvisorAuth($devKey, $password);
$header = new SoapHeader("http://www.example.com/webservices/", "APICredentials", $auth, false);
// Call wsdl function
$result = $client->__soapCall("DeleteMarketplaceAd", array(
"DeleteMarketplaceAd" => array(
"accountID" => $accountId,
"marketplaceAdID" => "9938745" // The ads ID
)
), NULL, $header);
// Echo the result
echo "<pre>".print_r($result, true)."</pre>";
if($result->DeleteMarketplaceAdResult->Status == "Success")
{
echo "Item deleted!";
}
?>
jeffmixpute (2011-01-24 15:15:43)
Simple php client and server:
Client:
<?php
// bind SOAP/Client.php -> path of the php file
require_once "SOAP/Client.php";
// URI delivered to web service
$sc = new SOAP_Client("http://localhost/SOAP/Server.php");
// start call function to use the function of the Web Service
$parameter = array();
$result = $sc->call ("now", &$parameter, "urn:TimeSerivce");
// print result
print $result."\n";
?>
Server:
<?php
// bind PEAR::SOAP
require_once "SOAP/Server.php";
$skiptrace =& PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
$skiptrace = true;
// program service class
class TimeSerivce {
public function now () {
date_default_timezone_set("Europe/Berlin");
return (date ("H:i"));
}
}
// web service classs develop
$service = new TimeSerivce();
// server develop
$ss = new SOAP_SERVER();
// assing the name to the service
$ss->addObjectMap($service, "urn:TimeSerivce");
// Einstellung, dass POST-Daten an den Service weiter gegeben werden
// preferene to forword POST data to the service
$ss->service ($HTTP_RAW_POST_DATA);
?>
fourat dot zouari at tritux dot com (2009-06-20 08:08:55)
In addition to the KeepAlive trick which is a "server-side" modification, on the "client side" default_socket_timeout should be increased from its default value (60) when you deal with ~slow SOAP servers.
As for the KeepAlive, if creating a new separate vhost for the soap api is not possible, you can add this to your existing vhost: BrowserMatch "^PHP-SOAP" nokeepalive
where PHP-SOAP is the agent name of your soap client, if you dont know what agent name your client use, just checkout the access.log of your apache.
peter dot hansen at fastit dot net (2009-05-01 06:57:14)
When you get errors like:
"Fatal error: Uncaught SoapFault exception: [HTTP] Error Fetching http headers in"
after a few (time intensive) SOAP-Calls, check your webserver-config.
Sometimes the webservers "KeepAlive"-Setting tends to result in this error. For SOAP-Environments I recommend you to disable KeepAlive.
Hint: It might be tricky to create a dedicated vhost for your SOAP-Gateways and disable keepalive just for this vhost because for normal webpages Keepalive is a nice speed-boost.