可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am trying to call the url using curl in php. I get a BAD REQUEST error .
if someone can help me,I do not get what the problem is
Their "recipe" is as follows: http://wl.filos.com.gr/services/WebService.asmx?op=PlaceSearch (look at soap 1.1)
The code I have is:
<?
// xml data
$soap_request = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$soap_request .= "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n";
$soap_request .= " <soap:Body>\n";
$soap_request .= " <PlaceSearch xmlns=\"http://www.cyberlogic.gr/webservices/\">\n";
$soap_request .= " <xml><PlaceSearchRequest><Username>SERUNCD</Username><Password>TA78UNC</Password><PlaceType>Cities</PlaceType><Language>en</Language></PlaceSearchRequest></xml>\n";
$soap_request .= " </PlaceSearch>\n";
$soap_request .= " </soap:Body>\n";
$soap_request .= "</soap:Envelope>";
// heder
$header = array(
"POST /services/WebService.asmx HTTP/1.1",
"Host: wl.filos.com.gr",
"Content-type: text/xml; charset=utf-8",
"Content-length: ".strlen($soap_request),
"SOAPAction: \"http://www.cyberlogic.gr/webservices/PlaceSearch\""
);
// call currl
$soap_do = curl_init();
curl_setopt($soap_do, CURLOPT_URL, "http://wl.filos.com.gr/services/WebService.asmx?op=PlaceSearch" );
curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($soap_do, CURLOPT_TIMEOUT, 10);
curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, true );
curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($soap_do, CURLOPT_POST, true );
curl_setopt($soap_do, CURLOPT_POSTFIELDS, $soap_request);
curl_setopt($soap_do, CURLOPT_HTTPHEADER, $header);
curl_getinfo($soap_do, CURLINFO_EFFECTIVE_URL);
curl_setopt($soap_do, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)');
$output = curl_exec($soap_do);
$info = curl_getinfo($soap_do);
print_r(curl_getinfo($soap_do)) ;
if(curl_exec($soap_do) === false) {
$err = 'Curl error: ' . curl_error($soap_do);
curl_close($soap_do);
print $err;
} else {
curl_close($soap_do);
print 'Operation completed without any errors <br />';
}
echo "The server responded: <br />";
echo " " . $info['http_code'];
?>
回答1:
As you don't have a WSDL for the SOAP interface of the www.cyberlogic.gr webservice, you won't benefit from using it compared with the other methods, e.g. the GET method:
<?php
/**
* Example for cyberlogic.gr GET webservice
*/
// create the request XML
$request = new SimpleXMLElement("<PlaceSearchRequest/>");
$request->Username = "SERUNCD";
$request->Password = "TA78UNC";
$request->PlaceType = "Cities";
$request->Language = "en";
$url = "http://wl.filos.com.gr/services/WebService.asmx/PlaceSearch";
$result = simplexml_load_file($url . "?xml=" . urlencode($request->asXML()));
if ($result) {
// process result
$count = 0;
foreach ($result->Response->Cities->City as $City) {
printf("#%03d: %s (%s)\n", $count++, $City->CityName, $City["city_id"]);
}
}
This example also shows how to access the city-id attribute which was something not easily possible with standard result parsing and mapping of PHP's SoapClient. As the result type remains undefined anyway, doing this in SoapClient isn't worth the steps it would need to take.
Example Output:
#000: Achladies (545)
#001: Afitos (338)
#002: Agia Paraskevi (548)
...
#142: Volos town (473)
#143: Vourvourou (420)
#144: Vrachos- Loutsa (922)
回答2:
You can try "Content-type: application/xml; charset=utf-8" in your header line?
回答3:
As I understand, you need to use PHP SOAP for SOAP request OR PHP cURL for HTTP POST or GET request.
Here is your code:
$soap_request = 'xml='.urlencode(trim('
<PlaceSearchRequest>
<Username>SERUNCD</Username>
<Password>TA78UNC</Password>
<PlaceType>Cities</PlaceType>
<Language>en</Language>
</PlaceSearchRequest>
'));
$header = array(
'POST /services/WebService.asmx HTTP/1.1',
'Host: wl.filos.com.gr',
'Content-Type: application/x-www-form-urlencoded',
'Content-Length: '.strlen($soap_request),
);
$soap_do = curl_init();
curl_setopt($soap_do, CURLOPT_URL, 'http://wl.filos.com.gr/services/WebService.asmx?op=PlaceSearch');
curl_setopt($soap_do, CURLOPT_HEADER, false);
curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 100);
curl_setopt($soap_do, CURLOPT_TIMEOUT, 100);
curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, true);
curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($soap_do, CURLOPT_HTTPHEADER, $header);
curl_setopt($soap_do, CURLOPT_POST, true);
curl_setopt($soap_do, CURLOPT_POSTFIELDS, $soap_request);
curl_setopt($soap_do, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)');
$output = curl_exec($soap_do);
$info = curl_getinfo($soap_do);
if (curl_exec($soap_do) === FALSE)
{
$err = 'Curl error: ' . curl_error($soap_do);
curl_close($soap_do);
print $err;
}
else
{
curl_close($soap_do);
}
echo 'The server responded: '.$info['http_code']."\n";
echo 'Output: '.$output;
echo "\n";
Run it in terminal with php your_code.php
for example.
Here is output for current XML string data:
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><soap:Code><soap:Value>soap:Receiver</soap:Value></soap:Code><soap:Reason><soap:Text xml:lang="en">Server was unable to process request. ---> Data at the root level is invalid. Line 1, position 1.</soap:Text></soap:Reason><soap:Detail /></soap:Fault></soap:Body></soap:Envelope>
回答4:
The SOAP interface of the www.cyberlogic.gr webservice for the PlaceSearch requires you to pass the xml parameter properly encoded - otherwise you'll get a 400 Bad Request response.
This is normally done best by using the XML library of your choice, here I do that with SimpleXML which is pretty handy for your use-case:
// create the request XML
$request = new SimpleXMLElement('<PlaceSearchRequest/>');
$request->Username = 'SERUNCD';
$request->Password = 'TA78UNC';
$request->PlaceType = 'Cities';
$request->Language = 'en';
Next to creating correct XML for the parameter to be passed, the parameter itself needs to be properly encoded as well. As this involves some values configured, first of all define the data needed for the whole operation:
$soapUrl = "http://wl.filos.com.gr/services/WebService.asmx";
$namespace = "http://www.cyberlogic.gr/webservices/";
$action = "PlaceSearch";
and then use the $request
object just created to turn it into the needed SOAP parameter. It is important here, that the XML encoding is applied correctly as well. Again, this should be done with the XML library of your choice, here I do that with DOMDocument:
// create the soap variable
$var = new DOMDocument();
$var->appendChild($var->createElementNS($namespace, 'xml'));
$var->documentElement->nodeValue = $request->asXML();
$soapVar = new SoapVar($var->saveXML($var->documentElement), XSD_ANYXML);
Note that the XML is properly assigned as XML to the nodeValue
. This is important to create a valid request.
Now as $soapVar
has been created, all it needs it so setup the SoapClient:
// create soap client in non-WSDL mode
$client = new SoapClient(null, array(
'location' => $soapUrl,
'uri' => $namespace
));
And then do the request:
// place soap call
$result = $client->__soapCall(
$action, array($soapVar), array('soapaction' => "$namespace$action")
);
And that's it already. Note that the API you have has some XML problems, namely it makes use of an XML element with the tag-name "xml" which is reserved and not allowed. That's also a sign that you should take extra care when you need to trouble-shoot your webservice requests. As curl can only give you a 400 Bar request, SoapClient does actually return much better error messages which help a lot to get things started.
What's left is the processing of the return value, here exemplary:
// process result
foreach ($result->PlaceSearch->Response->Cities->City as $i => $City) {
printf("#%03d: %s\n", $i, $City->CityName);
}
Which outputs:
#000: Achladies
#001: Afitos
#002: Agia Paraskevi
...
#142: Volos town
#143: Vourvourou
#144: Vrachos- Loutsa
The code-example in full incl. error handling for the soap request:
/**
* Example for cyberlogic.gr SOAP webservice
*/
$soapUrl = "http://wl.filos.com.gr/services/WebService.asmx";
$namespace = "http://www.cyberlogic.gr/webservices/";
$action = "PlaceSearch";
// create the request XML
$request = new SimpleXMLElement('<PlaceSearchRequest/>');
$request->Username = 'SERUNCD';
$request->Password = 'TA78UNC';
$request->PlaceType = 'Cities';
$request->Language = 'en';
// create the soap variable
$var = new DOMDocument();
$var->appendChild($var->createElementNS($namespace, 'xml'));
$var->documentElement->nodeValue = $request->asXML();
$soapVar = new SoapVar($var->saveXML($var->documentElement), XSD_ANYXML);
// create soap client in non-WSDL mode
$client = new SoapClient(null, array(
'location' => $soapUrl,
'uri' => $namespace
));
try {
// place soap call
$result = $client->__soapCall(
$action, array($soapVar), array('soapaction' => "$namespace$action")
);
// process result
foreach ($result->PlaceSearch->Response->Cities->City as $i => $City) {
printf("#%03d: %s\n", $i, $City->CityName);
}
} catch (Exception $e) {
echo $e->getMessage(), "\n";
echo $client->__getLastRequest(); // set 'trace' => true SoapClient option
}
回答5:
Done!
$soap_request = 'xml='.urlencode(trim('
<?xml version="1.0" encoding="utf-8"?>
<PlaceSearchRequest>
<Username>SERUNCD</Username>
<Password>TA78UNC</Password>
<PlaceType>Cities</PlaceType>
<Language>en</Language>
</PlaceSearchRequest>
'));
$header = array(
'POST /services/WebService.asmx HTTP/1.1',
'Host: wl.filos.com.gr',
'Content-Type: application/x-www-form-urlencoded',
'Content-Length: '.strlen($soap_request),
);
$soap_do = curl_init();
curl_setopt($soap_do, CURLOPT_URL, 'http://wl.filos.com.gr/services/WebService.asmx/PlaceSearch');
curl_setopt($soap_do, CURLOPT_HEADER, false);
curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 100);
curl_setopt($soap_do, CURLOPT_TIMEOUT, 100);
curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, true);
curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($soap_do, CURLOPT_HTTPHEADER, $header);
curl_setopt($soap_do, CURLOPT_POST, true);
curl_setopt($soap_do, CURLOPT_POSTFIELDS, $soap_request);
curl_setopt($soap_do, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)');
$output = curl_exec($soap_do);
$info = curl_getinfo($soap_do);
if (curl_exec($soap_do) === FALSE)
{
$err = 'Curl error: ' . curl_error($soap_do);
curl_close($soap_do);
print $err;
}
else
{
curl_close($soap_do);
}
echo 'The server responded: '.$info['http_code']."\n";
echo 'Output: '.$output;
echo "\n";