Ø In a Laravel application, you will define your
“web” routes in routes/web.php and your “API” routes in routes/api.php.
Ø Web routes are those that will be visited by your
end users; API routes are those for your API, if you have one. For now, we’ll
primarily focus on the routes in routes/web.php.
Ø The simplest way to define a route is to match a
path (e.g., /) with a closure, as seen in Example 3-1.
// routes/web.php
Route::get('/', function ()
{
return 'Hello, World!';
});
Ø You’ve now defined that, if anyone visits / (the
root of your domain), Laravel’s router should run the closure defined there and
return the result. Note that we return our content and don’t echo or print it.
Ø Many simple websites could be defined
entirely within the web routes file. With a few simple
GET routes combined with some templates as illustrated in Example 3-2, you can can serve a
classic website easily.
Route::get('/', function () {
return view('welcome');
});
Route::get('about',
function ()
{
return view('about');
});
Route::get('products',
function ()
{
return view('products');
});
Route::get('services',
function ()
{
return view('services');
});
Ø If you have much experience developing PHP, you
might be surprised to see static
calls on the Route class. This is not actually a static method per se, but rather service location using
Laravel’s facades, which we’ll
Ø If you
prefer to avoid facades, you can accomplish these same definitions like this:
$router->get('/', function ()
{
return 'Hello, World!';
});
Route Verbs
Ø You might’ve noticed that we’ve been using Route::get
in our route definitions. This means we’re telling Laravel to only match for these
routes when the HTTP request uses the GET action.
Ø But what if it’s a form POST, or maybe some
JavaScript sending PUT or DELETE requests? There are a few other options for methods
to call on a route definition, as illustrated in Example 3-3.
Route::get('/', function ()
{
return 'Hello, World!';
});
Route::post('/', function ()
{});
Route::put('/', function ()
{});
Route::delete('/', function ()
{});
Route::any('/', function ()
{}); Route::match(['get', 'post'],
'/', function () {});
Route Handling
Ø As you’ve probably guessed, passing a closure to
the route definition is not the only way to teach it how to resolve a route.
Ø Closures are
quick and simple, but the larger your application gets, the clumsier it becomes
to put all of your routing logic in one file.
Ø Additionally, applications using route closures
can’t take advantage of Laravel’s route caching (more on that later), which can
shave up to hundreds of milliseconds off of each request.
Ø The other common option is to pass a controller
name and method as a string in place of the closure, as in Example 3-4.
Route::get('/', 'WelcomeController@index');
Ø This is telling Laravel to pass requests to that
path to the index() method of the App\Http\Controllers\WelcomeController
controller.
Ø This method will be passed the same parameters and treated
the same way as a closure you might’ve alternatively put in its place.
Route Parameters
Ø If the route you’re defining has parameters —
segments in the URL structure that are variable. it’s simple to define them in
your route and pass them to your closure (see Example 3-5).
Route::get('users/{id}/friends',
function ($id)
{
//
});
Ø You can also make your route parameters optional by
including a question mark (?) after the parameter name, as illustrated in Example 3-6. In this case, you should also provide a default
value for the route’s corresponding variable.
Route::get('users/{id?}',
function ($id
= 'fallbackId') {
//
});
Ø And you can use regular expressions (regexes) to
define that a route should only match if a parameter meets particular
requirements, as in Example 3-7.
Route::get('users/{id}',
function ($id)
{
//
})->where('id', '[0-9]+');
Route::get('users/{username}',
function ($username)
{
//
})->where('username', '[A-Za-z]+');
Route::get('posts/{id}/{slug}',
function ($id,
$slug) {
//
})->where(['id' => '[0-9]+',
'slug' => '[A-Za-z]+']);
Ø As you’ve probably guessed, if you visit a path
that matches a route string, but the regex doesn’t match the parameter, it
won’t be matched.
Ø Since routes
are matched top to bottom,users/abc would skip the first closure in Example 3-7, but it would be matched by the second closure, so
it would get routed there.
Ø On the other hand, posts/abc/123 wouldn’t match any
of the closures, so it would return a 404 Not Found error.
Route Names
Ø There’s a url() helper to simplify that linking in
your views, if you need it; see Example 3-8 for an example. The
helper will prefix your route with the full domain of your site.
<a href="<?php echo url('/'); ?>">
Ø However, Laravel also allows you to name each
route, which enables you to refer to it without explicitly referencing the URL.
Ø This is
helpful because it means you can give simple nicknames to complex routes, and
also because linking them by name means you don’t have to rewrite your frontend
links if the paths change (see Example 3-9).
// Defining a route with name in
routes/web.php:
Route::get('members/{id}',
'MembersController@show')->name('members.show');
// Link the route in a view using the route() helper
<a href="<?php echo route('members.show', ['id' => 14]);
?>">
Ø This example illustrates a few new concepts. First,
we’re using fluent route definition to add the name, by chaining the name() method
after the get() method.
Ø This method allows us to name the route, giving it a
short alias to make it easier to reference elsewhere.
Ø
In our example,
we’ve named this route members.show; resourcePlural.action is a common
convention within Laravel for route and view names.
R OUTE NAMING
CONVENT IONS
You can name your route anything you’d like, but the common
convention is to use the
plural of the resource name, then a period,
then the action. So, here are the routes most common for a resource named photo:
photos.index photos.create
photos.store photos.show photos.edit photos.update photos.destroy
|
Ø We also introduced the route() helper. Just like
url(), it’s intended to be used in views to simplify linking to a named route.
If the route has no parameters, you can simply pass the route name: (route('members.index'))
and receive a route string http://myapp.com/members/index).
Ø If it has parameters, pass them in as an array as
the second parameter like we did in this example.
Ø
In general, I
recommend using route names instead of paths to refer to your routes, and
therefore using the route() helper instead of the url() helper. Sometimes it
can get a bit clumsy — for example, if you’re working with multiple subdomains
— but it provides an incredible level of flexibility to later change the
application’s routing structure without major penalty.
When your route has parameters
(e.g., users/{id}), you need to define those parameters when you’re using
the route()
helper to generate a link to the
route.
There are a few different ways to
pass these parameters. Let’s imagine a
route defined as users/{userId}/comments/{commentId}. If the user ID is 1 and the comment ID is 2, let’s look at a few options we have available to us:
Option
1:
route('users.comments.show', [1,
2])
Option
2:
route('users.comments.show', ['userId'
=> 1, 'commentId'
=> 2])
Option
3:
route('users.comments.show', ['commentId'
=> 2, 'userId'
=> 1])
Option 4:
route('users.comments.show', ['userId'
=> 1, 'commentId'
=> 2, 'opt'
=> 'a'])
As you can see, nonkeyed array values are assigned in order; keyed array
values are matched with the route parameters matching their keys, and anything
left over is added as a query parameter.
No comments:
Post a Comment