67

This works fine on my WAMP server, but doesn't work on the linux master server!?

try{
    $client = new SoapClient('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', ['trace' => true]);
    $result = $client->checkVat([
        'countryCode' => 'DK',
        'vatNumber' => '47458714'
    ]);
    print_r($result);
}
catch(Exception $e){
    echo $e->getMessage();
}

What am I missing here?! :(

SOAP is enabled

Error

SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl' : failed to load external entity "http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl"/taxation_customs/vies/checkVatService.wsdl"

Call the URL from PHP

Calling the URL from PHP returns error

$wsdl = file_get_contents('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl');
echo $wsdl;

Error

Warning:  file_get_contents(http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl): failed to open stream: HTTP request failed! HTTP/1.0 503 Service Unavailable

Call the URL from command line

Calling the URL from the linux command line HTTP 200 is returned with a XML response

curl http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl
clarkk
  • 27,151
  • 72
  • 200
  • 340
  • 2
    What does `curl http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl` say if you run it on the shell on the Linux server? – ntaso Feb 20 '14 at 18:20
  • 1
    HTTP 200 and the XML is the response – clarkk Feb 20 '14 at 19:10
  • 1
    Sounds like it might be a character encoding issue. Is the WDSL encoded in the charset the SOAP client is expecting? – GordonM Jul 11 '17 at 09:07

17 Answers17

94

For some versions of php, the SoapClient does not send http user agent information. What php versions do you have on the server vs your local WAMP?

Try to set the user agent explicitly, using a context stream as follows:

try {
    $opts = array(
        'http' => array(
            'user_agent' => 'PHPSoapClient'
        )
    );
    $context = stream_context_create($opts);

    $wsdlUrl = 'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl';
    $soapClientOptions = array(
        'stream_context' => $context,
        'cache_wsdl' => WSDL_CACHE_NONE
    );

    $client = new SoapClient($wsdlUrl, $soapClientOptions);

    $checkVatParameters = array(
        'countryCode' => 'DK',
        'vatNumber' => '47458714'
    );

    $result = $client->checkVat($checkVatParameters);
    print_r($result);
}
catch(Exception $e) {
    echo $e->getMessage();
}

Edit

It actually seems to be some issues with the web service you are using. The combination of HTTP over IPv6, and missing HTTP User Agent string, seems to give the web service problems.

To verify this, try the following on your linux host:

curl  -A ''  -6 http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl

this IPv6 request fails.

curl  -A 'cURL User Agent'  -6 http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl

this IPv6 request succeeds.

curl  -A ''  -4 http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl
curl  -A 'cURL User Agent'  -4 http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl

both these IPv4 request succeeds.

Interesting case :) I guess your linux host resolves ec.europa.eu to its IPv6 address, and that your version of SoapClient did not add a user agent string by default.

MarthyM
  • 1,839
  • 2
  • 21
  • 23
Ivar
  • 1,208
  • 9
  • 15
  • you say the IPv6 request fails, but don't specify how. If it fails with a 503 status code, I'll delete my answer. Where I am, it says `Failed to connect to 2001:bc8:3408:200::2: Network is unreachable` – Walter Tross Feb 23 '14 at 21:48
  • That is correct, the request fails with a `HTTP/1.0 503 Service Unavailable`. The text body of the 503 response is `Erreur 503 Erreur proxy ipv6`. – Ivar Feb 24 '14 at 07:41
  • 2
    The link to the reported SoapClient User Agent bug https://bugs.php.net/bug.php?id=60887 – Ivar Feb 24 '14 at 07:47
  • 1
    OK, so what I didn't think of in my answer was to try IPv6. You won. I'm going to delete my answer. – Walter Tross Feb 24 '14 at 07:59
  • stream_context for https url : http://stackoverflow.com/a/28701786/2042775 – sj59 Oct 10 '16 at 12:04
  • @Ivar I am using wamp in windows, if i try to get category tree my error: https://snag.gy/psFcBi.jpg and my code : https://justpaste.it/6bfrw how can i solve the error? – Gem May 07 '18 at 11:22
  • @Ivar http://192.168.1.89/abc/api/v2_soap/?wsdl return : https://snag.gy/eZI0iB.jpg – Gem May 08 '18 at 04:24
  • @Ivar giving the same error after adding the stream_context over HTTPS. curl -A '' -6 and curl -A 'cURL User Agent' -6 these commands are giving an error curl: (6) Could not resolve host – Tomas Jul 05 '22 at 07:15
34

Security issue: This answer disables security features and should not be used in production!

Try this. I hope it helps

$options = [
    'cache_wsdl'     => WSDL_CACHE_NONE,
    'trace'          => 1,
    'stream_context' => stream_context_create(
        [
            'ssl' => [
                'verify_peer'       => false,
                'verify_peer_name'  => false,
                'allow_self_signed' => true
            ]
        ]
    )
];

$client = new SoapClient($url, $options);
PiTheNumber
  • 22,828
  • 17
  • 107
  • 180
gogagubi
  • 965
  • 1
  • 15
  • 36
11

This issue can be caused by the libxml entity loader having been disabled.

Try running libxml_disable_entity_loader(false); before instantiating SoapClient.

Attila Szeremi
  • 5,235
  • 5
  • 40
  • 64
5

It may be helpful for someone, although there is no precise answer to this question.

My soap url has a non-standard port(9087 for example), and firewall blocked that request and I took each time this error:

ERROR - 2017-12-19 20:44:11 --> Fatal Error - SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://soalurl.test:9087/orawsv?wsdl' : failed to load external entity "http://soalurl.test:9087/orawsv?wsdl"

I allowed port in firewall and solved the error!

EmRa228
  • 1,226
  • 13
  • 22
4

Try changing

$client = new SoapClient('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', ['trace' => true]);

to

$client = new SoapClient('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', ['trace' => true, 'cache_wsdl' => WSDL_CACHE_MEMORY]);

Also (whether that works or not), check to make sure that /tmp is writeable by your web server and that it isn't full.

klugerama
  • 3,312
  • 19
  • 25
  • @clarkk Minor change (added single quotes), sorry. Also, is `/tmp` good? Also, what does `phpinfo()` tell you? – klugerama Feb 21 '14 at 17:33
  • Another thought: could the server be redirecting to https? Have you run wireshark or Fiddler on the request? – klugerama Feb 21 '14 at 17:55
  • I saw the typo with single quotes :) and there is no redirect.. have tried the request at `www.web-sniffer.net` – clarkk Feb 21 '14 at 23:14
  • As I wrote in my question I can call the URL with curl in the command line.. this must be a misconfiguration in PHP... On the old server with debian 6 and php5.3-something it worked.. haven't monkeyed around with php.ini and it's pretty much out of the box – clarkk Feb 21 '14 at 23:17
3

Try enabling openssl extension in your php.ini if it is disabled. This way I could access the web service without need of any extra arguments, i.e.,

$client = new SoapClient(url);
3

None of the above works for me, so after a lot of research, I ended up pre-downloading the wsdl file, saving it locally, and passing that file as the first parameter to SoapClient.

Worth mentioning is that file_get_contents($serviceUrl) returned empty response for me, while the url opened fine in my browser. That is probably why SoapClient also could not load the wsdl document. So I ended up downloading it with the php curl library. Here is an example

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $serviceUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$wsdl = curl_exec($ch);
curl_close($ch);

$wsdlFile = '/tmp/service.wsdl';
file_put_contents($wsdlFile, $wsdl);

$client = new SoapClient($wsdlFile);

You can of course implement your own caching policy for the wsdl file, so it won't be downloaded on each request.

Shumoapp
  • 1,489
  • 16
  • 15
2

503 means the functions are working and you're getting a response from the remote server denying you. If you ever tried to cURL google results the same thing happens, because they can detect the user-agent used by file_get_contents and cURL and as a result block those user agents. It's also possible that the server you're accessing from also has it's IP address blackballed for such practices.

Mainly three common reasons why the commands wouldn't work just like the browser in a remote situation.

1) The default USER-AGENT has been blocked. 2) Your server's IP block has been blocked. 3) Remote host has a proxy detection.

Madan
  • 691
  • 5
  • 20
1

After hours of analysis reading tons of logs and internet, finally found problem.

If you use docker and php 7.4 (my case) you probably get error because default security level in OpenSSL it too high for wsdl cert. Even if you disable verify and allow self-signed in SoapClient options.

You need lower seclevel in /etc/ssl/openssl.cnf from DEFAULT@SECLEVEL=2 to

DEFAULT@SECLEVEL=1

Or just add into Dockerfile

RUN sed -i "s|DEFAULT@SECLEVEL=2|DEFAULT@SECLEVEL=1|g" /etc/ssl/openssl.cnf

Source: https://github.com/dotnet/runtime/issues/30667#issuecomment-566482876


You can verify it by run on container

curl -A 'cURL User Agent' -4 https://ewus.nfz.gov.pl/ws-broker-server-ewus/services/Auth?wsdl

Before that change I got error:

SSL routines:tls_process_ske_dhe:dh key too small
GetoX
  • 4,225
  • 2
  • 33
  • 30
1

It was solved for me this way:

Every company from which you provide "Host" has a firewall.

This error occurs when your source IP is not defined in that firewall. Contact the server administrator to add the IP.

Or the target IP must be defined in the server firewall whitelist.

mmd
  • 47
  • 8
1

Below solution worked for me.

1- Go to php.ini in ubuntu with apache is /etc/php/7.4/apache2 ( note: you should use your php version replace by 7.4 )

2- Remove ; from this line ;extension=openssl to make in uncommented.

3- Restart your web server sudo service apache2 restart

mohammad asghari
  • 1,817
  • 1
  • 16
  • 23
0

I use the AdWords API, and sometimes I have the same problem. My solution is to add ini_set('default_socket_timeout', 900); on the file vendor\googleads\googleads-php-lib\src\Google\AdsApi\AdsSoapClient.php line 65

and in the vendor\googleads-php-lib\src\Google\AdsApi\Adwords\Reporting\v201702\ReportDownloader.php line 126 ini_set('default_socket_timeout', 900); $requestOptions['stream_context']['http']['timeout'] = "900";

Google package overwrite the default php.ini parameter.

Sometimes, the page could connect to 'https://adwords.google.com/ap i/adwords/mcm/v201702/ManagedCustomerService?wsdl and sometimes no. If the page connects once, The WSDL cache will contain the same page, and the program will be ok until the code refreshes the cache...

0

Adding ?wsdl at the end and calling the method:

$client->__setLocation('url?wsdl'); 

helped to me.

double-beep
  • 5,031
  • 17
  • 33
  • 41
Sakezzz
  • 468
  • 6
  • 16
0

I might have read all questions about this for two days. None of the answers worked for me.

In my case I was lacking cURL module for PHP.

Be aware that, just because you can use cURL on terminal, it does not mean that you have PHP cURL module and it is active. There was no error showing about it. Not even on /var/log/apache2/error.log

How to install module: (replace version number for the apropiated one)

sudo apt install php7.2-curl
sudo service apache2 reload
Hache_raw
  • 471
  • 3
  • 10
0

I had the same problem

From local machines everything work (wamp + php5.5.38 or vagrant + php 7.4), but from prod linux server I had error

SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl' : failed to load external entity "http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl"

From redirect path plugin in chrome I discovered permanent redirect to https, but change url to https doesnt help.

Status Code    URL    IP    Page Type    Redirect Type    Redirect URL    

301 http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl 147.67.210.30 server_redirect permanent https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl 200 https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl 147.67.210.30 normal none none

After few attempts of different code solutions helped my our server provider. He discovered problem in IP forwarding with ipv6.

http://ec.europa.eu/

Pinging ec.europa.eu [147.67.34.30] with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.

Recommendation was user stream_context_create with socket and bind to 0:0. this forces ipv4

// https://www.php.net/manual/en/context.socket.php

$streamContextOptions = [
  'socket' => [
    'bindto' => '0:0'
  ],
];

$streamContext = stream_context_create($streamContextOptions);

$soapOptions = [
  'stream_context' => $streamContext
];

$service = new SoapClient('https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', $soapOptions);
smeta
  • 131
  • 1
  • 4
0

I had similar error because I accidently removed attribute [ServiceContract] from my contract, yet the service host was still opening successfully. Blunders happen

eXPerience
  • 346
  • 1
  • 3
  • 19
0

May try to see if the endpoint supports https as well

Pak Ho Cheung
  • 1,382
  • 6
  • 22
  • 52