我正在Symfony应用程序中构建一个Soap服务器。作为第一步,我用“hello world”肥皂动作创建了一个控制器,并为它定义了路径:
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;
}
现在,当我在浏览器中调用http://my-app.loc/soapapi/foo/bar
或使用cURL(通过HTTP GET)时,我收到错误:
<?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>
但是当我调用http://my-app.loc/soapapi/foo/bar?wsdl
时,我实际上得到了(生成的)WSDL文档。为什么?我没有定义任何地方,它应该像这样工作。为什么以及如何(魔术)起作用?这是Symfony特有的魔法吗?
答案 0 :(得分:3)
这是一个很好的问题。
这不是Symfony特有的,它是PHP中内置SOAP服务器的行为。当附加?wsdl
访问端点URL时,SOAP服务器将使用构造函数中实例化的wsdl文档进行响应:
$server = new SoapServer(__DIR__ . '/soapapi-foo-bar.wsdl');
我无法找到PHP网站上记录此行为的位置,但它显然存在且可重现。
该功能的代码可以在PHP's source code starting on line 1550中找到并在第1592行结束。代码检查请求方法是否为GET并检查是否存在'wsdl'查询参数。