user1607625
user1607625

Reputation: 11

soap web service with symfony2

i need to create a webservices with symfony2 ive read the official article http://symfony.com/doc/current/cookbook/web_services/php_soap_extension.html in the example it creates a instance of SoapServer with a parameter routing a .wsdl file, what is this file? i didnt found too much documentation about soap in symfony. some help with this please?

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;
}

Upvotes: 1

Views: 6574

Answers (2)

Arash Dalir
Arash Dalir

Reputation: 91

I'm not sure if you've found your answer or not. Just for anybody else that might run into such a problem:

WSDL is the language in which the Web Services are defined and described. It's basically a XML file containing the input/output parameters of each and every function that are served by a server. it also contains some information about the server itself, that's providing the services.

in order to be able to create a webservice, you need to use the code you've provided, which would in fact prepare Symfony to serve the clients on "/path/to/hello.wsdl" (in my example this path is /YourDesiredPathFor/services.wsdl), and also, you need to provide a valid WSDL document that contains the information mentioned above in correct WSDL format. the problem is that Symfony (or even PHP itself for this matter) has no means of creating the file automatically.

to solve the matter, you need to use an external WSDL generator. I'd suggest using PHP-WSDL-Creator. It uses annotations written inside php files to create the WSDL file and also runs the SoapServer. that means that you won't even need the code that you've provided. it also has proper interfaces and addons that provide you with clients for different protocols and languages.

you need to tweak it a little bit though! if you want it to be by symfony standards, i think you would need to rewrite some parts of it; but if you'd like to use it as an external library, it could also work! the way i did it was by copying the extracted files into ./vendor/php_wsdl/lib/php_wsdl/src (long it is, isn't it? maybe an easier path would also work!); then defined a php_wsdl.php in ./vender/php_wsdl/lib/php_wsdl:

<?php

require_once __DIR__. '/src/class.phpwsdl.php';

class WSDL_PhpWsdl extends PhpWsdl{
}

next, in the "./app/autoload.php", i added the following line to enable Symfony to use the created extension:

require_once __DIR__. '/../vendor/php_wsdl/lib/php_wsdl/php_wsdl.php';

just one thing! the extension needs a "cache" folder in order to cache the created wsdl files and all. unfortunately because i need to finish the project quickly, i don't have enough time to manage the cache folder as it should be. there are definitely better ways than my way, and i would really be glad to know about them.

anyway, now you need to use the extension's capabilities! to do so, i created a "ServerController" for the bundle i was using:

<?php
namespace Tara\PageControllerBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;

class ServiceController extends Controller
{
    function wsdlAction(){

        \PhpWsdlServers::$EnableRest = false;

        $soap= \WSDL_PhpWsdl::CreateInstance(
            null,                               // PhpWsdl will determine a good namespace
            $this->generateUrl('service_wsdl', array(), true),  // Change this to your SOAP endpoint URI (or keep it NULL and PhpWsdl will determine it)
            __DIR__. '/cache',                  // Change this to a folder with write access
            Array(                              // All files with WSDL definitions in comments
                dirname(__FILE__). '/../Services/MyService.php'
            ),
            null,                               // The name of the class that serves the webservice will be determined by PhpWsdl
            null,                               // This demo contains all method definitions in comments
            null,                               // This demo contains all complex types in comments
            false,                              // Don't send WSDL right now
            false                               // Don't start the SOAP server right now
        );

        if($soap->IsWsdlRequested())            // WSDL requested by the client?
            $soap->Optimize=false;              // Don't optimize WSDL to send it human readable to the browser

        $soap->RunServer();
    }
}

as you can see, the path to the cache folder is on a local directory, which means it has to be created manually and in ./src/Tara/PageControllerBundle/Controller (obviously in my case; you will need to change the paths). I'm sure there are better ways to manage the cache folder. there is a line there:

dirname(__FILE__). '/../Services/MyService.php

this line tells the extension where to look for annotations in order to create the WSDL page. you also need to define a route to "service_wsdl":

service_wsdl:
    pattern: /YourDesiredPathFor/services.wsdl
    defaults: {_controller: TaraPageControllerBundle:Service:wsdl}

as you can see, the controller is ServiceController and the function responsible for it is wsdlAction; the exact function that was defined!

just as an example, i would provide my own MyService.php:

<?php

namespace Tara\PageControllerBundle\Services;


use Tara\PageControllerBundle\Model\...

/**
 * @service Tara\PageControllerBundle\Services\MyService
 */

class MyService
{
    /**
     * Function Create
     *
     * @param string $link
     * @param string $title
     * @param string $image
     * @param string $description
     * @return boolean Status of the creation
     * @pw_rest POST /YourDesiredPathForAction/create Create The Object
     *
     */

    public function Create($link, $title, $image, $description)
    {

        // your code that handles the data goes here. this is not a part of the annotations!
        return (bool)$result;
    }
}

now, you might be able to use a SoapClient to connect to your web service at

http: //your-server.something/YourDesiredPathFor/services.wsdl?wsdl

and call the Create function! you can also check the output of the extension by opening the above written address. the extension also provides a "human-readable" version at

http: //your-server.something/YourDesiredPathFor/services.wsdl.

i would be glad to know if this was any help to anyone! :)

Upvotes: 5

davidfmatheson
davidfmatheson

Reputation: 3567

SOAP is a more general concept that Symfony assumes you are familiar with. There is an example WSDL at the bottom of the page that you link to. Take a look at tutorials about SOAP and WSDL and then try to recreate what they're doing in the Symfony page.

SOAP Tutorial

WSDL Tutorial

Upvotes: 0

Related Questions