Cómo utilizar métodos HTTP además de GET y POST en rutas

El método HTTP de la petición es uno de los requisitos que se pueden comprobar al ver si coincide con una ruta. Este se introduce en el capítulo de enrutado del libro «Enrutando», con ejemplos del uso de GET y POST. También puedes utilizar otros verbos HTTP de esta manera. Por ejemplo, si tienes una entrada del blog entonces podrías usar la misma ruta URL para mostrarla, hacerle cambios y eliminarla emparejándola con GET, POST y DELETE.

  • YAML
    blog_show:
        path:     /blog/{slug}
        defaults: { _controller: AcmeDemoBundle:Blog:show }
        methods:   [GET]
    
    blog_update:
        path:     /blog/{slug}
        defaults: { _controller: AcmeDemoBundle:Blog:update }
        methods:   [PUT]
    
    blog_delete:
        path:     /blog/{slug}
        defaults: { _controller: AcmeDemoBundle:Blog:delete }
        methods:   [DELETE]
    
  • XML
    <?xml version="1.0" encoding="UTF-8" ?>
    
    <routes xmlns="http://symfony.com/schema/routing"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
    
        <route id="blog_show" path="/blog/{slug}" methods="GET">
            <default key="_controller">AcmeDemoBundle:Blog:show</default>
        </route>
    
        <route id="blog_update" path="/blog/{slug}" methods="PUT">
            <default key="_controller">AcmeDemoBundle:Blog:update</default>
        </route>
    
        <route id="blog_delete" path="/blog/{slug}" methods="DELETE">
            <default key="_controller">AcmeDemoBundle:Blog:delete</default>
        </route>
    </routes>
    
  • PHP
    use Symfony\Component\Routing\RouteCollection;
    use Symfony\Component\Routing\Route;
    
    $collection = new RouteCollection();
    $collection->add('blog_show', new Route('/blog/{slug}', array(
        '_controller' => 'AcmeDemoBundle:Blog:show',
    ), array(), array(), '', array(), array('GET')));
    
    $collection->add('blog_update', new Route('/blog/{slug}', array(
        '_controller' => 'AcmeDemoBundle:Blog:update',
    ), array(), array(), '', array(), array('PUT')));
    
    $collection->add('blog_delete', new Route('/blog/{slug}', array(
        '_controller' => 'AcmeDemoBundle:Blog:delete',
    ), array(), array(), '', array('DELETE')));
    
    return $collection;
    

Faking the Method with _method

Nota

The _method functionality shown here is disabled by default in Symfony 2.2 and enabled by default in Symfony 2.3. To control it in Symfony 2.2, you must call Request::enableHttpMethodParameterOverride before you handle the request (e.g. in your front controller). In Symfony 2.3, use the http_method_override option.

Desafortunadamente, la vida no es así de simple, ya que la mayoría de los navegadores no son compatibles con el envío de peticiones PUT y DELETE. Afortunadamente Symfony2 te proporciona una forma sencilla de trabajar en torno a esta limitación. Al incluir un argumento _method en la cadena de consulta o en los parámetros de una petición HTTP, Symfony2 lo utilizará como el método a coincidir con las rutas. Esto se puede hacer fácilmente en formularios con un campo oculto. Supongamos que tienes un formulario para editar una entrada de blog:

<form action="{{ path('blog_update', {'slug': blog.slug}) }}" method="post">
    <input type="hidden" name="_method" value="PUT" />
    {{ form_widget(form) }}
    <input type="submit" value="Update" />
</form>

La petición presentada ahora coincide con la ruta blog_update y usará el updateAction para procesar el formulario.

Del mismo modo puedes cambiar el formulario de eliminación para que se parezca a esto:

<form action="{{ path('blog_delete', {'slug': blog.slug}) }}" method="post">
    <input type="hidden" name="_method" value="DELETE" />
    {{ form_widget(delete_form) }}
    <input type="submit" value="Delete" />
</form>

Entonces, este coincidirá con la ruta blog_delete.

Bifúrcame en GitHub