Tiago Magalhães Tiago Magalhães - 4 months ago 173
PHP Question

PHP SoapClient fails with - Failed to load external entity

I've been trying to use the European Union's website to validate TIN numbers (Europa TIN validation website - there is a WSDL available at the bottom of the page)

The problem I'm having is that when I try to make a new SoapClient the function fails immediately when building the client. At first I was having a "Failed to load external entity" and I assumed it was because the WSDL has a secure connection. After searching around I found some answers that said that the problem could have to do with the certificate being outdated and the most recent versions of PHP throw errors in that case, so I disabled certificate validation with:

// Stream context due to certificate problems
$streamContext = stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
));


But now I'm getting another error: "failed to open stream: HTTP Request failed! HTTP/1.1 502 Bad Gateway". Any thoughts about how to solve this issue? If I remove "https://" from the link I get the same result as before with the "failed to load external entity" message.

Now here's the real brain picker. If I try to use chrome's extension "Boomerang" to test SOAP calls on the WSDL it works absolutely perfectly, so I have no idea what's wrong here... Anyone can easily try this by attempting to make a soap call in a PHP file.

Here's the full code:

public static function validateTIN($tin) {
// Stream context due to certificate problems
$streamContext = stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
));

// Create our soap client
$client = new SoapClient('https://ec.europa.eu/taxation_customs/tin/checkTinService.wsdl', array(
'exceptions' => 0,
'trace' => 1,
'connection_timeout' => 1800,
'stream_context' => $streamContext
));

dd($client->__getFunctions());

return true;
}

Answer

After spending hours researching and trying to figure out the problem I found a ye old 2 years old post that somehow served my purpose.

Unfortunately I can't mark this as duplicate so I'll just link it here: SOAP error parsing wsl couldn't load from but works on wamp

I couldn't find this question because Google didn't tag it as using the Europa services.

Either way, my problem was that I needed to specify my user agent explicitly because Europa web services are too outdated and can't resolve IPv6 requests, only IPv4. Like so:

$opts = array(
    'http'=>array(
        'user_agent' => 'PHPSoapClient'
        )
    );

$context = stream_context_create($opts);
$client = new SoapClient('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl',
                         array('stream_context' => $context,
                               'cache_wsdl' => WSDL_CACHE_NONE));

$result = $client->checkVat(array(
                                'countryCode' => 'DK',
                                'vatNumber' => '47458714'
                                ));

The example uses the CheckVAT SOAP function but it works just as well for the CheckTIN function.