Search code examples
phpwsdlphpunitsoap-client

Soap Client works on server; does not connect on CLI, while curl does connect on CLI


In a nutshell, I have a simple SoapClient script that:

  • works on my development machine (win - IIS)
  • won't connect on my local machine when using PHPUnit

Oddly enough, in my PHPUnit test, curl_init() and curl_exec() connects while SoapClient does not.

The working script on IIS:

<?php
$response = "No message received";
$wsdl = 'http://www.dneonline.com/calculator.asmx?WSDL';

$trace = true;
$exceptions = false;
$xml_array['intA'] = 5;
$xml_array['intB'] = 3;

try {
   $client = new SoapClient($wsdl, array('trace' => $trace, 'exceptions' => $exceptions));
   $response = $client->Add($xml_array);

   $foo = $client->Subtract($xml_array);
} catch (Exception $e) {
   echo "Error!";
   echo $e -> getMessage ();
   echo 'Last response: '. $client->__getLastResponse();
}

print "<pre>";

print_r($client->__getFunctions());

var_dump($response);
if($response->AddResult == 8) {
  print "Yep, it's eight";
}
print "\n-----------------------\n";
var_dump($foo);


if($foo->SubtractResult == 2) {
  print "Yep, it's two";
}

The PHPUnit tests:

public function testTruth() {
  $this->assertTrue(true);
}

public function testCurl() {
  $url = 'http://www.dneonline.com/calculator.asmx?WSDL';
  $curl = curl_init();
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($curl, CURLOPT_HEADER, false);
  $output = curl_exec($curl);
  $this->assertEquals('<?xml', substr($output,0,5));
}

public function testSoapClient() {
  $response = "No message received";
  $wsdl = 'http://www.dneonline.com/calculator.asmx?WSDL';

  $options = array(
    'trace' => true,
    'cache' => WSDL_CACHE_NONE,
    'exceptions' => true,
    'stream_context' => stream_context_create(array('http'=>array('user_agent'=>'PHPSoapClient')))
  );

  libxml_disable_entity_loader(false);

  $client = new SoapClient($wsdl,$options);  // test dies here...
 

PHPUnit output:

PHPUnit 6.0.10 by Sebastian Bergmann and contributors.

..PHP Fatal error:  SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.dneonline.com/calculator.asmx?WSDL' : failed to load external entity "http://www.dneonline.com/calculator.asmx?WSDL"
 in X:\websites\development\tests\soapTest.php on line 48
ER                                                               4 / 4 (100%)

Time: 1.65 seconds, Memory: 10.00MB

There was 1 error:

1) RDBTest::testSoapClient
SoapFault: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.dneonline.com/calculator.asmx?WSDL' : failed to load external entity "http://www.dneonline.com/calculator.asmx?WSDL"

What I've tried from other SO suggestions:

  • Compared php.ini for development server and local CLI. Added any directives from server not present in local CLI.
  • added libxml_disable_entity_loader(false)
  • added 'cache' => WSDL_CACHE_NONE
  • added 'stream_context => stream_context_create(array('http'=>array('user_agent'=>'PHPSoapClient')))

Any ideas why new SoapClient is failing to connect, while curl is connecting?


Solution

  • Proxy... The problem was my local computer is behind a proxy. The fix ended up being as simple as:

    $options = array(
      //'trace' => true,
      //'cache' => WSDL_CACHE_NONE,
      //'exceptions' => false,
      //'stream_context' => stream_context_create(array('http'=>array('user_agent'=>'PHPSoapClient'))),
      'proxy_host' => '{host name}',
      'proxy_port' => '{port}',
      'proxy_login' => '{username}',
      'proxy_password' => '{password}'
    );
    
    //libxml_disable_entity_loader(false);
    
    $client = new SoapClient($wsdl,$options);
    

    Five hours googling and searching SO...

    And the answer was lurking in the PHP documentation :/