Skip to content

Instantly share code, notes, and snippets.

@weierophinney
Created February 12, 2014 16:46
Show Gist options
  • Save weierophinney/8959426 to your computer and use it in GitHub Desktop.
Save weierophinney/8959426 to your computer and use it in GitHub Desktop.
Example of creating a SOAP controller for handling both WSDL and SOAP requests in ZF2.
<?php
return array(
'router' => array('routes' => array(
'soap' => array(
'type' => 'Literal',
'options' => array(
'route' => '/soap',
'defaults' => array(
'controller' => 'Soap\Controller\SoapController',
'action' => 'soap',
),
),
),
)),
'service_manager' => array(
'factories' => array(
'Soap\Controller\SoapController' => 'SomeFactoryYouWillNeedToWrite',
),
),
);
<?php
namespace Soap\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Soap\AutoDiscover as SoapWsdlGenerator;
use Zend\Soap\Server as SoapServer;
class SoapController
{
protected $route;
protected $soap;
protected $wsdlGenarator
public function __construct($route, SoapServer $soapServer, SoapWsdlGenerator $wsdlGenerator)
{
$this->route = $route;
$this->soap = $soapServer;
$this->wsdlGenerator = $wsdlGenerator;
}
public function soapAction()
{
$request = $this->getRequest();
$response = $this->getResponse();
switch ($request->getMethod()) {
case 'GET':
$this->wsdlGenerator->setUri($this->url($this->route));
$wsdl = $this->wsdlGenerator->generate();
$response->getHeaders()->addHeaderLine('Content-Type', 'application/wsdl+xml');
$response->setContent($wsdl->toXml());
break;
case 'POST':
$this->soap->setReturnResponse(true);
$soapResponse = $this->soap->handle();
if ($soapResponse instanceof SoapFault) {
$soapResponse = (string) $soapResponse;
}
$response->getHeaders()->addHeaderLine('Content-Type', 'application/xml');
$response->setContent($soapResponse);
break;
default:
$response->setStatusCode(405);
$response->getHeaders()->addHeaderLine('Allow', 'GET,POST');
break;
}
return $response;
}
}
@weierophinney
Copy link
Author

Notes:

  • You'll need to create a factory for the SoapController that will inject the appropriate route name ("soap" in this case), a Zend\Soap\Server instance, and a Zend\Soap\AutoDiscover instance. There are examples of setting those up in the manual.
  • I'm not 100% sure the fault response will be done correctly with this, but reasonably sure.

@EvanDotPro
Copy link

class SoapController should be class SoapController extends AbstractActionController.

@gennadiylitvinyuk
Copy link

There are some more typos, but it works!!!

Thank you, @weierophinney

@pdizz
Copy link

pdizz commented Jan 28, 2016

You can use 'method' type child-routes to route the request to different controller actions to handle GET and POST instead of handling them both in the same action

<?php

return array(
    'router' => array('routes' => array(
        'soap.test.route' => array(
            'type' => 'literal',
            'options' => array(
                'route' => '/soaptest',
            ),
            'child_routes' => [
                'get' => [
                    'type' => 'method',
                    'options' => [
                        'verb' => 'get',
                        'defaults' => [
                            'controller' => 'SoapTest\Controller\SoapTestController',
                            'action' => 'get'
                        ],
                    ],
                ],
                'post' => [
                    'type' => 'method',
                    'options' => [
                        'verb' => 'post',
                        'defaults' => [
                            'controller' => 'SoapTest\Controller\SoapTestController',
                            'action' => 'post'
                        ],
                    ],
                ],
            ],
        ),
    )),
    'controllers' => array(
        'invokables' => array(
            'SoapTest\Controller\SoapTestController' => 'SoapTest\SoapTestController',
        ),
    ),
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment