laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.44k stars 11k forks source link

[Proposal] Add more fine grained control to Route for routes supporting multiple HTTP methods #3058

Closed jamesrwhite closed 10 years ago

jamesrwhite commented 10 years ago

Sometimes I've found myself wanting a route to support more than one HTTP method, the most common example of this being a route that responds to GET and POST such as a shopping cart page for example. I know that Route::any() technically offers this but that leaves your route then responding to a lot more methods than you actually want/require.

My proposal is to use a bit of magic to allow people to specify routes like so:

Route::getOrPost('test', function() {

    echo 'yay!';

});

The syntax works as you'd expect, you concatenate http methods using 'Or' as the join, the order would not be important.

My current proof of concept of how this could work is by adding a __call() to the Router class like so:

/**
 * Used to allow the creation of multi method routes e.g getOrPost
 *
 * @param string $name
 * @param array $arguments
 * @return \Illuminate\Routing\Route
 */
public function __call($name, $arguments)
{
    // Split the method name by Or, e.g getOrPost become an array with get and Post
    $methods = explode('Or', $name);

    // Lowercase all method names
    $methods = array_map('strtolower', $methods);

    // Join all the method names with a |
    $methods = implode('|', $methods);

    // Add the methods to the method args
    array_unshift($arguments, $methods);

    return call_user_func_array(array($this, 'createRoute'), $arguments);
}

This works fairly well, at the moment a 500 is thrown when a route could not be matched instead of a 404 which obviously needs to be fixed but I don't think that should be too hard to figure out :)

Let me know what you think, I think this would be a small but nice addition to Laravel.

taylorotwell commented 10 years ago

Use the Route::match method. It accepts an array of verbs as its first argument.

jamesrwhite commented 10 years ago

Ah fair enough, it's not in the docs so I didn't know that existed. Thanks.