.. index:: single: Web Services; SOAP Symfony2 コントローラで SOAP ウェブサービスを作成する方法 ========================================================= SOAP サーバとして動作するコントローラをセットアップするには、数個のツールを使うだけで簡単にできます。まず `PHP_SOAP`_ エクステンションをインストールしておく必要があります。この記事の執筆時点の PHP SOAP エクステンションは、 WSDL を生成することができないので、自分で書くか、サードパーティのジェネレータを使用する必要があります。 .. note:: PHP で SOAP のサーバを実装するには、複数の選択肢があります。 `ZEND SOAP`_ や `NuSOAP` はその例です。この例では、 PHP SOAP エクステンションを使用しますが、基本的な考えはこれらの他の実装にも適用できます。 SOAP は、 PHP オブジェクトのメソッドを外部のエンティティ(SOAP サービスを使用しているユーザ)にさらすことによって、動作します。まず、 SOAP サービスでさらすことになる機能の ``HelloService`` クラスを作成します。このケースでは SOAP サービスはメールを送信する ``hello`` のメソッドを、クライアントが呼ぶことができるようにしています。 :: namespace Acme\SoapBundle; 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`` オブジェクトを適切に作成する設定をすることができます。 .. configuration-block:: .. code-block:: yaml # app/config/config.yml services: hello_service: class: Acme\DemoBundle\Services\HelloService arguments: [mailer] .. code-block:: xml mailer 以下は、 SOAP リクエストを扱うことのできるコントローラの例です。 ``indexAction()`` が ``/soap`` ルートを通してアクセスができれば、 WSDL ドキュメントは、 ``/soap?wsdl``` を通して取得することができます。 .. code-block:: php namespace Acme\SoapBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; 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()`` を呼ぶようにしてください。この2つのメソッドは、 `output.buffering`_ を制御して、 ``$server->handle()`` の出力をまとめることができます。 Symfony はコントローラが "コンテント" としての出力を持つ ``Response`` オブジェクトを返すことを想定しているので、このバッファリングが必要になります。また、クライアントが想定するように "Content-Type" ヘッダを "text/xml" にすることも忘れないでください。 ``ob_start()`` メソッドを使用し、 STDOUT のバッファリングを始め、 ``ob_get_clean()`` メソッドで Response のコンテントに溜まったバッファを全部吐き出し、そして出力バッファをクリアします。そしてその結果、 ``Response`` を返す準備ができます。 以下が、 `NuSOAP`_ クライアントを使用してサービスを呼び出す例です。この例では、上記のコントローラの ``indexAction`` が ``/soap`` ルートでアクセスができることを想定しています。 :: route ``/soap``:: $client = new \soapclient('http://example.com/app.php/soap?wsdl', true); $result = $client->call('hello', array('name' => 'Scott')); WSDL の例は以下の通りです。 .. code-block:: xml Hello World .. _`PHP SOAP`: http://php.net/manual/en/book.soap.php .. _`NuSOAP`: http://sourceforge.net/projects/nusoap .. _`output buffering`: http://php.net/manual/en/book.outcontrol.php .. _`Zend SOAP`: http://framework.zend.com/manual/en/zend.soap.server.html .. 2011/11/08 ganchiku 368dcd210e12ce685bbc91ae2cd409c13c61e6c7