如何在symfony 控制器里面创建soap web service
通过一些工具将一个控制器设置成一个soap服务将会非常简单。首先,你必须安装了php soap扩展。由于php soap扩展现在不能生成wsdl,你要么自己从头开始创建要模使用第三方生成器。
php中有一些可以使用的soap服务接口。Zend SOAP 和 NuSOAP就是其中两个。尽管php soap扩展在这些例子中被使用,通用的思想还是可以被用在其他应用接口。
SOAP 的工作是通过暴露PHP对象给外部实体的(使用soap服务的人)。首先,创建一个Helloservice类-表示你将在你的soap服务中暴露的功能。在下面这个例子中,soap服务允许客户端调用一个hello方法来发送邮件:
// src/Acme/SoapBundle/Services/HelloService.php namespace Acme\SoapBundle\Services; class HelloService { private $mailer; public function __construct(\Swift_Mailer $mailer) { $this->mailer = $mailer; } public function hello($name) { $message = \Swift_Message::newInstance() ->setTo('me@example.com') ->setSubject('Hello Service') ->setBody($name . ' says hi!'); $this->mailer->send($message); return 'Hello, '.$name; } }
接下来,你可以配置symfony来创建该类的实例。由于该类是用来发送邮件,他需要接收一个swift_mailer实例参数。使用服务容器,你可以很好的配置一个symfony helloservice对象:
# app/config/services.yml services: hello_service: class: Acme\SoapBundle\Services\HelloService arguments: ['@mailer']
下面是一个调用soap请求的例子。假如indexAction()能通过路由成功访问到,那么wsdl文档就能被返回。
namespace Acme\SoapBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Response; class HelloServiceController extends Controller { public function indexAction() { $server = new \SoapServer('/path/to/hello.wsdl'); $server->setObject($this->get('hello_service')); $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; } }
记下ob_start()
和 ob_get_clean()这两个方法。这些方法可以控制
$server->handle()
输出。这是很有必要的,因为symfony希望你的控制器返回的对象是它期望的内容。Content-Type也必须设置为"text/xml",因为这是请求端希望的返回类型。因此,你使用ob_start()缓存输出内容,使用ob_get_clean()打印出要返回的内容并清空缓存,最后返回response。
下面的例子是调用nusoap客户端的服务,假设indexAction是可以通过路由成功访问到的。
$client = new \Soapclient('http://example.com/app.php/soap?wsdl'); $result = $client->call('hello', array('name' => 'Scott'));
wsdl例子如下
<?xml version="1.0" encoding="ISO-8859-1"?> <definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:arnleadservicewsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="urn:helloservicewsdl"> <types> <xsd:schema targetNamespace="urn:hellowsdl"> <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" /> <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" /> </xsd:schema> </types> <message name="helloRequest"> <part name="name" type="xsd:string" /> </message> <message name="helloResponse"> <part name="return" type="xsd:string" /> </message> <portType name="hellowsdlPortType"> <operation name="hello"> <documentation>Hello World</documentation> <input message="tns:helloRequest"/> <output message="tns:helloResponse"/> </operation> </portType> <binding name="hellowsdlBinding" type="tns:hellowsdlPortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="hello"> <soap:operation soapAction="urn:arnleadservicewsdl#hello" style="rpc"/> <input> <soap:body use="encoded" namespace="urn:hellowsdl" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </input> <output> <soap:body use="encoded" namespace="urn:hellowsdl" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </output> </operation> </binding> <service name="hellowsdl"> <port name="hellowsdlPort" binding="tns:hellowsdlBinding"> <soap:address location="http://example.com/app.php/soap" /> </port> </service> </definitions>