PHP curl and Web Proxy...maybe - php

I have a script which calls an external API using curl. This script worked perfectly when the website was on a dedicated server however I have had to move the server to a load balanced set up which sits behind a proxy and now for some reason I get
PHP Warning: SimpleXMLElement::__construct() [simplexmlelement.--construct]: Entity: line 1: parser error : Start tag expected, '<' not found in...file name.
In Firebug it comes back as a 500 error if there is a result (formatted XML) otherwise it processes as normal.
I am running Zend CE 5.1.0 with only the default modules installed. Do I need to set something on the proxy or do I need to install additional modules to get this working.
If you need further information let me know.
Cheers

Did you defined your proxy in php?
Something like:
define('HTTP_PROXY_HOST', '192.168.100.100');
define('HTTP_PROXY_PORT', '8080');
if (defined('HTTP_PROXY_HOST') && HTTP_PROXY_HOST != '') {
curl_setopt($ch, CURLOPT_PROXY, HTTP_PROXY_HOST);
}
if (defined('HTTP_PROXY_PORT') && HTTP_PROXY_PORT != '') {
curl_setopt($ch, CURLOPT_PROXYPORT, HTTP_PROXY_PORT);
}

Related

file_get_contents() returning empty string

I am having the weirdest, head splitting issue ever. The real issue is I'm getting a SOAP error SOAP-ERROR: Parsing WSDL: Couldn't load from 'some website' : failed to load external entity
In the past it was caused by the host not responding, bad URL, etc. But today I have no problem connecting to the host.
I'm using Symfony to run the API. I stripped ALL of the soap code from the API, created a simple test.php file and ran it from the command line on the exact server the API is running on, and it worked perfectly!
So I went back to the Symfony, flushed the cache. Still not working.
Next I decided to test the simplest methods I could and slapped 'file_get_contents('the url to the WSDL')` at the very top of the service that's making this SOAP call. It returns an empty string. No errors in the error log.
Next I tried moving that to the Controller. Still an empty string.
I tried file_get_contents('https://google.com'). Still, empty string no matter where in the Controller or Service I stick it. But, if on that same server I run a PHP script from the command line, it works no problem.
I don't even know where to begin showing you my code. Because it doesn't matter if file_get_contents() is in the controller, an entity, or the services it's using. Every time it returns an empty string.
As a side note, this is a development server. Which is an exact mirror of production (they just made an image of the production server). The whole API works fine in production and also on my local dev environment and in other environments it's been deployed to. So I'm entirely lost on why it's just this server, and just this particular application.
Any help is appreciated.
==
Update 1
As suggested by a friend I checked allow_url_fopen in both the cli php -i and apache phpinfo() and in both cases it's set to On
==
Update 2
As Pedro suggested I ran a cURL test in the controller of the API. And that worked, it retrieved the contents of the WDSL, and of course Google.
However, it doesn't solve my root problem with SOAP not retrieving the contents of a URL. Nor the obvious file_get_contents() not working. Does the PHP SOAP client use file_get_contents() to retrieve WSDLs?
==
Update 3
For those curious this is where the code is failing. I have to omit a lot of the class because it contains information specific to my company.
<?php
class Carrier implements CarrierInterface
{
//...omitted code
private function getSoapClient($wsdl)
{
// This line is what fails.
return new \SoapClient( $wsdl , array('trace' => true));
}
//...omitted code
public function quote(QuoteInterface $quote)
{
//Get the Soap Client
$client = $this->getSoapClient($this->quoteWSDL);
// The rest of the SOAP CALL
return $quote;
}
}
But in short, $this->quoteWSDL is just a URL, and yes it has a the correct value I've checked. But it fails when trying to construct the SOAP client stating SOAP-ERROR: Parsing WSDL: Couldn't load from '<url>' : failed to load external entity
==
Update 4 (with Kinda Solution)
Restarting apache fixed everything. I'm not sure why I didn't just ask the SysAdmin to do that sooner. That's like IT 101 right there. Thanks for your help. But now I'm curious why this was an issue to begin with. Weird.
My guess is that allow_url_fopen is disabled.
To enable it, you'll have to set allow_url_fopen=1 on php.ini.
Restart the Apache server to reload the configuration.
Have you considered using curl? Here's an example:
$url = "http://google.com";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$contents = curl_exec($ch);
curl_close($ch);
PS: For future users: Make sure you read the comments below.

Error using curl_init() in php environment on BlueMix

I use the PHP runtime on Bluemix. In my solution, I need to invoke the external API available on the Internet on port 3000.
I used curl to manage the API invocation using the following code:
$endPoint="http://".$this->server.":".$this->port.$endPoint;
$session = curl_init($endPoint);
curl_setopt($session, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($session);
In the Bluemix log I found the following error:
Got error 'PHP message: PHP Fatal error: Call to undefined function
curl_init() in /home/vcap/app/htdocs/include/service.php on line 50\n',
referer: http://m2msite.mybluemix.net/login.php
It does not seem to be a defined curl library inside my runtime.
I do not found any documentation on how to define the curl library in a Bluemix runtime.
Can anyone help me to configure my runtime in a correct way?
Many thanks in advance
I found the solution.
under the project root I create a directory .bp-config
Inside the directory I create a file option.json with the following content:
{
"PHP_EXTENSIONS": ["mysqli","curl"]
}
mysqli for mysql library and curl for the curl library.
So now I am able to use curl library inside my project
Has anyone the link for a complete documentation around this configuration steps ?
Ciao
the complete documentation for your this kind of configuration related to a PHP buildpack could be found here
https://docs.cloudfoundry.org/buildpacks/php/gsg-php-config.html

PHP Fatal error: Failure in wincache (windows azure)

I have codeigniter framework in my project. My website is running on windows azure platform. Sometimes it's giving me this error:
PHP Fatal error: Failure in Wincache[6484] free_memory: Block 0x41d56d8 not in use
in D:\home\site\wwwroot\system\libraries\Log.php on line 44
I tried to change php.ini file by changing value of memory:
ini_set('memory_limit','2048M');
But, then after I checked memory_get_peak_usage(); then I found that application is not even using more than 1MB. I don't know what's going on here. I am getting blank page and website gets down when this happens.
Please, ask me if you need more information or code.
Log.php:
public function __construct()
{
$config =& get_config();
$this->_log_path = ($config['log_path'] != '') ? $config['log_path'] : APPPATH.'logs/';
if ( ! is_dir($this->_log_path) OR ! is_really_writable($this->_log_path)) // This is line 44.
{
$this->_enabled = FALSE;
}
if (is_numeric($config['log_threshold']))
{
$this->_threshold = $config['log_threshold'];
}
if ($config['log_date_format'] != '')
{
$this->_date_fmt = $config['log_date_format'];
}
}
log.php file is default codeigniter file.
FINAL SOLUTION:
I have updated my php.ini file with this:
wincache.fcenabled=0
wincache.ocenabled=0
wincache.ucenabled=0
wincache.reroute_enabled = 0
wincache.srwlocks = 0
It's an issue with IIS or WinCache on Windows Server. You can follow official thread on a iis forum.
Just to be sure, check following options in your php.ini:
wincache.reroute_enabled = 0
wincache.srwlocks = 0
Also update wincache to a latest version.
The specific WinCache error message has been removed as of WinCache 1.3.7.5, which was pushed out in a recent Azure Web Services update.
As for the meaning of the error message: While attempting to free a block of memory in a cross-process shared memory segment, WinCache detected that the block had already been freed. The message indicates that WinCache detected the problem, and avoided corrupting memory. The message should really be a Warning level message. Further, the executing request should run to completion, and a response should be returned to the customer.
Prior to WinCache 1.3.7.4, WinCache did not detect this scenario, and would wind up corrupting memory, which would eventually lead to an AV. So, the error message actually indicates that WinCache just saved you from crashing, and you're welcome!

PHP SoapClient using WCF service hosted in Windows application on Windows 2008 Server

This question relates to the requirement to utilize a WCF service hosted in a Windows application on Windows 2008 Server, from PHP scripts which are hosted in IIS 7 on the same server, and from other applications hosted elsewhere.
The application has been developed and tested thoroughly on a Windows 7 machine using Visual Studio 2010, .NET Framework 4, IIS 7, and various versions of PHP.
On the Windows 7 machine, netsh was used as follows.
netsh http add urlacl url=http://localhost:8000/WCFService/ user=machinename\user
Various other ports were also successfully added and used during testing.
When the application was copied to the Windows 2008 Server, the essential parts of the application were successfully tested.
The same netsh command was used on Windows 2008 Server, yet localhost was replaced with the server IP and machinename with domain as follows:
netsh http add urlacl url=http://serveripaddress:8000/WCFService/ user=domain\user
During attempts to get the PHP SoapClient working, various user="..." options were attempted, including "everyone".
The initial PHP SoapClient script is as follows:
try {
$client = new SoapClient("http://serveripaddress:8000/WCFService/?wsdl");
} catch (Exception $e) {
echo $e->getMessage(), "\n";
exit();
}
During initial testing, the following errors were encountered:
Warning:
SoapClient::SoapClient(http://serveripaddress:8000/WCFService/?wsdl)
[soapclient.soapclient]: failed to open stream: HTTP request failed!
in C:\inetpub\wwwroot\Sites\www.myurl.com\WCF-Test.php on line 7
Warning: SoapClient::SoapClient() [soapclient.soapclient]: I/O
warning : failed to load external entity
"http://serveripaddress:8000/WCFService/?wsdl" in
C:\inetpub\wwwroot\Sites\www.myurl.com\WCF-Test.php on line 7
SOAP-ERROR: Parsing WSDL: Couldn't load from
'http://serveripaddress:8000/WCFService/?wsdl' : failed to load
external entity "http://serveripaddress:8000/WCFService/?wsdl"
After some fiddling around the error reduced to the following:
SOAP-ERROR: Parsing WSDL: Couldn't load from
'http://serveripaddress:8000/WCFService/?wsdl' : failed to load
external entity "http://serveripaddress:8000/WCFService/?wsdl"
I then extracted the wsdl into a file and used the following PHP script:
try {
$client = new SoapClient("wsdl\wcf-wsdl.wsdl");
} catch (Exception $e) {
echo $e->getMessage(), "\n";
exit();
}
The error then changed slightly to the following:
SOAP-ERROR: Parsing Schema: can't import schema from
'http://serveripaddress:8000/WCFService/?xsd=xsd0'
I am of the opinion that the issue at hand relates to the "visibility" of the service, to the client, and possibly permissions.
After reading dozens of posts, I still have not been able to find a solution to this issue.
Any assistance will be greatly appreciated.
Many thanks in advance.
If the WCF Service is something you are hosting for it to be accessed by php clients you need to have a flat wsdl. On how to generate Flat Wsdl follow the below link:
How to flatten your wsdl
The same feature would be avaiable in the framework as part of .NET 4.5. Hope that helps you out.
If you know you are working with a .NET WCF service you can just change the location you download the wsdl from .svc?wsdl to .svc?singleWsdl and the WCF server will take care of the recursion / linking work for you.
This may the answer,.net has the default config make this error.
https://bugs.php.net/bug.php?id=47761

Internal Server Error 500 simplexml_load_file

if I use Firefox and access http://svcs.ebay.com/services/search/FindingService/v1 I get some sort of XML in respose, when I do that through PHP I get Internal Server Error 500
$ php -r 'print_r(simplexml_load_file("http://svcs.ebay.com/services/search/FindingService/v1"));'
PHP Warning: simplexml_load_file(http://svcs.ebay.com/services/search/FindingService/v1): failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error
in Command line code on line 1
PHP Stack trace:
PHP 1. {main}() Command line code:0
PHP 2. simplexml_load_file() Command line code:1
PHP Warning: simplexml_load_file(): I/O warning : failed to load external entity "http://svcs.ebay.com/services/search/FindingService/v1" in Command line code on line 1
PHP Stack trace:
PHP 1. {main}() Command line code:0
PHP 2. simplexml_load_file() Command line code:1
$
When I visit http://svcs.ebay.com/services/search/FindingService/v1 in firefox, firebug reports that the HTTP reponse code is indeed 500. (even though it sends some XML in the request body)
You're calling the web service in the wrong way.
Yes, you got XML back, but the response code is 500, meaning your URL is wrong.
Calling ximlexml_load_file via url wrappers expects a success code.
That said, you could probably get at the data anyway. Maybe.
But you should figure out how the service wants you to to query.
If you want to be able to read 500 request data use curl
<?php
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, "http://svcs.ebay.com/services/search/FindingService/v1");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// grab URL and pass it to the browser
$xml = curl_exec($ch);
$simpleXml = simplexml_load_string($xml);
// close cURL resource, and free up system resources
curl_close($ch);
?>
When I go to that site, I get:
<ms:errorMessage>
−
<error>
<errorId>2038</errorId>
<domain>SOA</domain>
<severity>Error</severity>
<category>System</category>
<message>Missing SOA operation name header</message>
</error>
</ms:errorMessage>
So it would seem that the URL is to a web service and probably requires some kind of authentication or at least input data in the request header. The HTTP response 500, according to Wikipedia, is a generic error meaning that the server can't specify the problem but knows there was one. Here's the best part of that article:
Response status codes beginning with
the digit "5" indicate cases in which
the server is aware that it has
encountered an error or is otherwise
incapable of performing the request.
Except when responding to a HEAD
request, the server should include an
entity containing an explanation of
the error situation, and indicate
whether it is a temporary or permanent
condition.
All that combined, I'd have to say your issue is that your are trying to grab a file from a remote server using a method that assumes you have some directory-level access to that file, and the server is responding with "Um, what?"
If you want to get the actual XML error as though you were in Firefox, use cURL:
$ebay_url = "http://svcs.ebay.com/services/search/FindingService/v1";
$ebay_page = curl_init();
curl_setopt($ebay_page, CURLOPT_RETURNTRANSFER, true); //output to string.
curl_setopt($ebay_page, CURLOPT_URL, $ebay_url); //set the url for the request.
$ebay_response = curl_exec($ebay_page);
print_r(simplexml_load_string($ebay_response));
If you want to actually get something back more meaningful, I would look at PHP's SoapClient methods and the actual ebay web service documentation.
The http headers need to be set specifying the operation to be executed. If you read how to make a call using the finding API, the article mentions the following http headers that need to be set:
X-EBAY-SOA-SERVICE-NAME: FindingService
X-EBAY-SOA-OPERATION-NAME: findItemsAdvanced <-- whatever call you are making
X-EBAY-SOA-SERVICE-VERSION: 1.0.0
X-EBAY-SOA-GLOBAL-ID: EBAY-US
X-EBAY-SOA-SECURITY-APPNAME: MyAppID
X-EBAY-SOA-REQUEST-DATA-FORMAT: XML
X-EBAY-SOA-MESSAGE-PROTOCOL: XML
Once those are set your call shoud work fine.
Maybe you want to try the following URL. When I do, I get back the XML and a 200 response.
http://svcs.ebay.com/services/search/FindingService/v1?wsdl
You need to reinstall your php (assuming you already have apache2 installed). Using these commands:
1) sudo apt update && apt upgrade
2) sudo apt install php-pear php-fpm php-dev php-zip php-curl php-xmlrpc php-gd php-mysql php-mbstring php-xml libapache2-mod-php
3) sudo service apache2 restart

Categories