Я пытаюсь вызвать URL с помощью curl в php. Я получаю ошибку BAD REQUEST.
если кто-то может мне помочь, я не понимаю, в чем проблема
Их «рецепт» заключается в следующем: http://wl.filos.com.gr/services/WebService.asmx?op=PlaceSearch (посмотрите на мыло 1.1)
Код у меня есть:
<?
// 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'];
?>
Поскольку у вас нет WSDL для интерфейса SOAP веб-службы www.cyberlogic.gr, вы не сможете воспользоваться им по сравнению с другими методами, например, метод GET:
<?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"]);
}
}
В этом примере также показано, как получить доступ к атрибуту city-id, что было непросто при стандартном разборе результатов и отображении PHP. SoapClient. Так как тип результата остается неопределенным, делая это в SoapClient не стоит шагов, которые нужно было бы предпринять.
Пример вывода:
#000: Achladies (545)
#001: Afitos (338)
#002: Agia Paraskevi (548)
...
#142: Volos town (473)
#143: Vourvourou (420)
#144: Vrachos- Loutsa (922)
Вы можете попробовать «Content-type: application / xml; charset = utf-8» в строке заголовка?
Как я понимаю, вам нужно использовать PHP SOAP за SOAP запрос ИЛИ ЖЕ PHP CURL за HTTP POST или GET запрос.
Вот ваш код:
$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";
Запустите его в терминале с php your_code.php
например.
Вот вывод для текущих данных строки XML:
<?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>
Интерфейс SOAP веб-службы www.cyberlogic.gr для PlaceSearch требует, чтобы вы правильно передавали параметр xml — в противном случае вы получите ответ 400 Bad Request.
Обычно это лучше всего сделать с помощью библиотеки XML по вашему выбору, здесь я делаю это с SimpleXML что очень удобно для вашего варианта использования:
// create the request XML
$request = new SimpleXMLElement('<PlaceSearchRequest/>');
$request->Username = 'SERUNCD';
$request->Password = 'TA78UNC';
$request->PlaceType = 'Cities';
$request->Language = 'en';
Помимо создания правильного XML для передаваемого параметра, сам параметр также должен быть правильно закодирован. Поскольку это включает в себя некоторые настроенные значения, в первую очередь определяют данные, необходимые для всей операции:
$soapUrl = "http://wl.filos.com.gr/services/WebService.asmx";
$namespace = "http://www.cyberlogic.gr/webservices/";
$action = "PlaceSearch";
а затем использовать $request
объект только что создан, чтобы превратить его в необходимый параметр SOAP. Здесь важно, чтобы XML-кодировка также применялась правильно. Опять же, это должно быть сделано с библиотекой XML по вашему выбору, здесь я делаю это с 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);
Обратите внимание, что XML правильно назначен как XML для nodeValue
, Это важно для создания правильного запроса.
Сейчас как $soapVar
все, что нужно, так что настройте SoapClient:
// create soap client in non-WSDL mode
$client = new SoapClient(null, array(
'location' => $soapUrl,
'uri' => $namespace
));
А затем сделайте запрос:
// place soap call
$result = $client->__soapCall(
$action, array($soapVar), array('soapaction' => "$namespace$action")
);
И это все уже. Обратите внимание, что у вашего API есть некоторые проблемы с XML, а именно он использует элемент XML с именем тега «xml», который зарезервирован и недопустим. Это также признак того, что вам следует проявлять особую осторожность, когда вам необходимо устранить неполадки в запросах веб-службы. Поскольку curl может дать вам только запрос 400 Бар, SoapClient на самом деле возвращает гораздо лучшие сообщения об ошибках, которые помогают начать работу.
Осталось обработать возвращаемое значение, вот примерное:
// process result
foreach ($result->PlaceSearch->Response->Cities->City as $i => $City) {
printf("#%03d: %s\n", $i, $City->CityName);
}
Какие выводы:
#000: Achladies
#001: Afitos
#002: Agia Paraskevi
...
#142: Volos town
#143: Vourvourou
#144: Vrachos- Loutsa
Пример кода в полном объеме вкл. обработка ошибок для запроса мыла:
/**
* 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
}
Готово!
$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";