Pedido incorreto de PHP no Curl na interface SOAP de http://www.cyberlogic.gr/webservices/PlaceSearch

Estou tentando chamar a url usando curl em php. Recebo um erro MAIS PEDIDO. Se alguém puder me ajudar, não percebi qual é o problema

Sua “receita” é a seguinte: http://wl.filos.com.gr/services/WebService.asmx?op=PlaceSearch (veja o soap 1.1)

O código que eu tenho é:

<? // xml data $soap_request = "\n"; $soap_request .= "\n"; $soap_request .= " \n"; $soap_request .= " \n"; $soap_request .= " SERUNCDTA78UNCCitiesen\n"; $soap_request .= " \n"; $soap_request .= " \n"; $soap_request .= ""; // 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 
'; } echo "The server responded:
"; echo " " . $info['http_code']; ?>

Como você não tem um WSDL para a interface SOAP do serviço web http://www.cyberlogic.gr, você não se beneficiará de usá-lo em comparação com os outros methods, por exemplo, o método GET:

 < ?php /** * Example for cyberlogic.gr GET webservice */ // create the request XML $request = new SimpleXMLElement(""); $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"]); } } 

Este exemplo também mostra como acessar o atributo city-id que não era facilmente possível com a análise e o mapeamento de resultados padrão do SoapClient do PHP. Como o tipo de resultado permanece indefinido de qualquer maneira, fazer isso em SoapClient não vale a pena os passos que ele precisaria tomar.

Exemplo de saída:

 #000: Achladies (545) #001: Afitos (338) #002: Agia Paraskevi (548) ... #142: Volos town (473) #143: Vourvourou (420) #144: Vrachos- Loutsa (922) 

Você pode tentar “Content-type: application / xml; charset = utf-8” na sua linha de header?

Como eu entendo, você precisa usar o SOAP PHP para solicitação SOAP ou o PHP CURL para solicitação HTTP POST ou GET .

Aqui está o seu código:

 $soap_request = 'xml='.urlencode(trim('  SERUNCD TA78UNC Cities en  ')); $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"; 

Execute-o no terminal com o php your_code.php por exemplo.

Aqui está saída para dados de string XML atuais: < ?xml version="1.0" encoding="utf-8"?>soap:ReceiverServer was unable to process request. ---> Data at the root level is invalid. Line 1, position 1. < ?xml version="1.0" encoding="utf-8"?>soap:ReceiverServer was unable to process request. ---> Data at the root level is invalid. Line 1, position 1.

A interface SOAP do http://www.cyberlogic.gr webservice para o PlaceSearch exige que você passe o parâmetro xml corretamente codificado – caso contrário você receberá uma resposta de 400 Solicitações ruins.

Isso normalmente é feito melhor usando a biblioteca XML de sua escolha, aqui eu faço isso com SimpleXML, o que é bastante útil para seu caso de uso:

 // create the request XML $request = new SimpleXMLElement(''); $request->Username = 'SERUNCD'; $request->Password = 'TA78UNC'; $request->PlaceType = 'Cities'; $request->Language = 'en'; 

Ao lado da criação do XML correto para o parâmetro a ser passado, o próprio parâmetro precisa também ser codificado corretamente. Como isso envolve alguns valores configurados, antes de mais definir os dados necessários para toda a operação:

 $soapUrl = "http://wl.filos.com.gr/services/WebService.asmx"; $namespace = "http://www.cyberlogic.gr/webservices/"; $action = "PlaceSearch"; 

e então use o object $request criado apenas para transformá-lo no parâmetro SOAP necessário. É importante aqui que a codificação XML também seja aplicada corretamente. Novamente, isso deve ser feito com a biblioteca XML de sua escolha, aqui eu faço isso com 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); 

Observe que o XML é devidamente designado como XML para o nodeValue . Isso é importante para criar um pedido válido.

Agora, como $soapVar foi criado, tudo o que precisa, então configure o SoapClient :

 // create soap client in non-WSDL mode $client = new SoapClient(null, array( 'location' => $soapUrl, 'uri' => $namespace )); 

E então faça o pedido:

 // place soap call $result = $client->__soapCall( $action, array($soapVar), array('soapaction' => "$namespace$action") ); 

E é isso mesmo. Note-se que a API que você possui tem alguns problemas XML, ou seja, faz uso de um elemento XML com o nome-tag “xml” que é reservado e não permitido. Isso também é um sinal de que você deve ter cuidado extra quando precisar solucionar problemas de seus pedidos de serviço na web. Como curl só pode dar-lhe um pedido de 400 Bar, o SoapClient realmente retorna mensagens de erro muito melhores que ajudam muito a começar as coisas.

O que resta é o processamento do valor de retorno, aqui exemplar:

 // process result foreach ($result->PlaceSearch->Response->Cities->City as $i => $City) { printf("#%03d: %s\n", $i, $City->CityName); } 

Que saídas:

 #000: Achladies #001: Afitos #002: Agia Paraskevi ... #142: Volos town #143: Vourvourou #144: Vrachos- Loutsa 

O código-exemplo na íntegra incl. Manipulação de erros para a solicitação de soap:

 /** * 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(''); $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 } 

Feito!

 $soap_request = 'xml='.urlencode(trim(' < ?xml version="1.0" encoding="utf-8"?>  SERUNCD TA78UNC Cities en  ')); $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";