2017-01-11 48 views
6

Buduję serwer Soap w aplikacji Symfony. Jako pierwszy krok I stworzył kontroler z moim "Hello World" działania mydło i zdefiniowane trasy dla niego:Jak to działa z magicznym parametrem zapytania WSDL URI?

routing.yml

api.soap.foo 
    path: /soapapi/foo 
    defaults: { _controller: SoapBundle\Controller\FooController:bar } 
    methods: [GET, HEAD, POST] 

FooController#bar(...)

protected function bar(Request $request) 
{ 
    $autodiscover = new AutoDiscover(); 
    $autodiscover 
     ->setClass(MyFooBarService::class) 
     ->setUri('http://my-app.loc/soapapi/foo/bar') 
     ->setServiceName('MyFooBarService') 
    ; 
    $wsdl = $autodiscover->generate(); 
    $wsdl->dump(__DIR__ . '/soapapi-foo-bar.wsdl'); 
    $server = new SoapServer(__DIR__ . '/soapapi-foo-bar.wsdl'); 
    $server->setObject($this->myFooBarService); 
    $response = new Response(); 
    $response->headers->set('Content-Type', 'text/xml; charset=ISO-8859-1'); 
    ob_start(); 
    $server->handle(); 
    $response->setContent(ob_get_clean()); 
    return $response; 
} 

Teraz, kiedy zadzwoń pod numer http://my-app.loc/soapapi/foo/bar w przeglądarce lub używając cURL (przez HTTP GET), pojawia się błąd:

<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <SOAP-ENV:Body> 
     <SOAP-ENV:Fault> 
      <faultcode>SOAP-ENV:Client</faultcode> 
      <faultstring>Bad Request</faultstring> 
     </SOAP-ENV:Fault> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

Ale kiedy zadzwonię pod numer http://my-app.loc/soapapi/foo/bar?wsdl, faktycznie otrzymuję (wygenerowany) dokument WSDL. Czemu? Nigdzie nie zdefiniowałem, że to powinno działać w ten sposób. Dlaczego i jak działa ta (magia)? Czy to specyficzna magia Symfony?

Odpowiedz

2

To jest świetne pytanie.

No to nie jest Symfony specyficzny, to zachowanie wbudowanego serwera SOAP w PHP. Gdy URL punktu końcowego jest dostępne z ?wsdl dołączony serwer SOAP odpowie dokumencie WSDL, który został tworzony z w konstruktorze:

$server = new SoapServer(__DIR__ . '/soapapi-foo-bar.wsdl'); 

Nie byłem w stanie znaleźć gdzie to zachowanie jest udokumentowane na Strona PHP, ale wyraźnie istnieje i jest powtarzalna.

Kod funkcji można znaleźć w PHP's source code starting on line 1550 i kończąc na linii 1592. Kod sprawdza, czy metoda żądania jest GET i sprawdza obecność parametru zapytania "wsdl".

+1

To zachowanie można znaleźć w [php źródło] (https://github.com/php/php-src) jest [przedłużenie mydło] (https://github.com/php/php-src/ blob/master/ext/soap/soap.C# L1550). Twoja odpowiedź jest poprawna. – Joe

+0

Dzięki @Joe zaktualizowałem odpowiedź. –