Routing is a core concept in Laravel, and it works a little differently than some of the frameworks of the past. The Laravel Route system is very flexible, and although a little tricky at first, once you get a good grasp of the fundamentals, you’ll find yourself asking how you lived without it all along. Without further ado, let’s dig into Laravel Routes!
Set Up a Custom Development Domain
Way back when, during the Install Laravel on Windows tutorial, we created an application named blog by running a command such as: composer create-project laravel/laravel <strong>blog</strong> --prefer-dist
What that did for us was create our project in C:wampwwwblog
and in order to view our application in a browser, we had to visit something like http://localhost/blog/public/
Now this is probably not ideal, you just installed the most technically advanced PHP programming framework available and you’re loading up http://localhost/blog/public/
in the browser to view it?! Ah, no thanks. Let’s get our own awesome dev environment set up. We’ll set this up so we can just hit http://vegi.bit
and have our app load up nice. You can choose what you like for yours, maybe http://you.rock
if you like.
- Open the Notepad Application as Administrator (All Programs->Accessories-> right click ‘notepad’ and ‘Run as Administrator). We are going to edit our Windows
hosts
file and you will not be able to save changes without administrator privileges. - Find the line that says 127.0.0.1 localhost then right after it, add you development domain(s)
127.0.0.1 localhost 127.0.0.1 you.rock
Save the
hosts
file, close the hosts file. -
Navigate to
C:wampbinapacheApache2.4.4confextra
and openhttpd-vhosts.conf
. At the end of the file add:DocumentRoot "C:/wamp/www/blog/public" ServerName you.rock DocumentRoot "C:/wamp/www" ServerName localhost Save the
httpd-vhosts.conf
file. -
Navigate to
C:wampbinapacheApache2.4.4conf
and openhttpd.conf
Look for the line that says# Include conf/extra/httpd-vhosts.conf
and change it by removing the leading # like so:Include conf/extra/httpd-vhosts.conf
Save the
httpd.conf
file. - Click the wamp icon in the task tray and select, Restart All Services.
Visit Your First Custom Laravel Route
Ok! If everything went well, and we have something like the following in our routes.php
file ( located at C:wampwwwblogapp
). It almost looks similar to how Node.js handles routes.
Route::get('/', function()
{
return 'The first Laravel Route!';
});
We should be able to visit http://you.rock/
in your browser and be greeted with: The first Laravel Route!
Go shorty, its yo birtday, we goin party like its yo birt…
Ahem… Ok, that’s great, we have a cool naming convention set up, so now, no matter what you named your project when you created it, we can have a really cool URL for our development environment. Onward!!
Routing To Closures
Most of the tutorials so far have been dealing with very simple routing to closures, which is really the first step in learning Laravel. So when we’ve been doing this all along:
Route::get('/', function()
{
return 'The first Laravel Route!';
});
What we’ve been doing is routing to closures. This is really cool, and quite useful. In building small applications it might be all we need in fact.
Accessing Route Parameters
Now that we have some really basic routing setup, let’s start accepting parameters to our routes. In order to do this, we can use something like this code:
Route::get('mr/{name}', function($name)
{
return 'Misterrr '.$name;
});
On visiting http://you.rock/mr/anderson
we would see something like:
Optional Route Parameters
Adding a ?
to the wildcard and assigning null
to the closure argument will allow the parameter to be optional, otherwise you’ll get an error if you don’t include the parameter.
Route::get('mr/{name?}', function($name = null)
{
return 'Misterrr '.$name;
});
Set Default Parameter Values
Route::get('mr/{name?}', function($name = 'Andersonnnnnn')
{
return 'Misterrr '.$name;
});
Visiting http://you.rock/mr
Routes and Parameters in Action
This is really cool. Now we can use our new found powers to combine routes with eloquent to retrieve things from our database. Recall our Many to Many Relationships in Laravel article and let’s do something better than simply routing to /
Let’s set up a route for retrieving blogposts by tag, if no tag is given, we’ll default it to 1.
Route::get('blogposts/tag/{id?}', function($id = 1)
{
$tag = Tag::find($id);
return $tag->blogposts;
});
Now we can visit things like http://you.rock/blogposts/tag
or http://you.rock/blogposts/tag/1
, http://you.rock/blogposts/tag/2
, or http://you.rock/blogposts/tag/3
and we get the results we are looking for.
What about getting the values by name or string instead of by id?
Well, I’m glad you asked! Let’s change up this code so we can pass either the numeric id *or* the name of the tag in a string format:
Route::get('blogposts/tag/{id?}', function($id = 1)
{
if (is_numeric($id))
{
$tag = Tag::find($id);
return $tag->blogposts;
}
else
{
$column = 'name'; // This is the name of the column you wish to search
$tag = Tag::where($column , '=', $id)->first(); // find the name to id association
return Tag::find($tag->id)->blogposts; // find by id
}
});
`http://you.rock/blogposts/tag`
`http://you.rock/blogposts/tag/1`
`http://you.rock/blogposts/tag/2`
`http://you.rock/blogposts/tag/3`
`http://you.rock/blogposts/tag/laravel`
`http://you.rock/blogposts/tag/bootstrap`
`http://you.rock/blogposts/tag/windows`
For examples sake, here is http://you.rock/blogposts/tag/laravel
[ { "id": 3, "title": "Laravel Eloquent ORM Tutorial", "body": "Eloquent is the very powerful and expressive ORM or Object Relational Mapper in Laravel. If you know how to work with Objects in PHP, then you know how to use Eloquent! ", "created_at": "0000-00-00 00:00:00", "updated_at": "0000-00-00 00:00:00", "pivot": { "tag_id": 1, "blogpost_id": 3 } }, { "id": 4, "title": "Install Laravel on Windows", "body": "This is going to assume we are starting from scratch using a fresh install of WAMP 2.4 on Windows.", "created_at": "0000-00-00 00:00:00", "updated_at": "0000-00-00 00:00:00", "pivot": { "tag_id": 1, "blogpost_id": 4 } } ]
Search by Slug
We can also use this method to search by slug, provided we have a slug in our blogposts
table. Note: You will need to add one now if you’d like to test this.
Route::get('blogposts/title/{id?}', function($id = 1)
{
if (is_numeric($id))
{
$blogpost = Blogpost::find($id);
return $blogpost;
}
else
{
$column = 'slug'; // This is the name of the column you wish to search
return Blogpost::where($column , '=', $id)->first(); // find the name to id association
}
});
{ "id": 4, "title": "Install Laravel on Windows", "body": "This is going to assume we are starting from scratch using a fresh install of WAMP 2.4 on Windows.", "created_at": "0000-00-00 00:00:00", "updated_at": "0000-00-00 00:00:00", "slug": "install-laravel-on-windows" }
Implement Constraints on Your Routes
Maybe you’re not flexible and would like to force a variable into lock down mode upon your users. You have that power. Force them to use a numeric id only. As you giveth, you may also taketh away:
Route::get('blogposts/title/{id?}', function($id = 1)
{
if (is_numeric($id))
{
$blogpost = Blogpost::find($id);
return $blogpost;
}
else
{
$column = 'slug'; // This is the name of the column you wish to search
return Blogpost::where($column , '=', $id)->first(); // find the name to id association
}
})->where(array('id' => '[0-9]+')); // force an id upon them!
Route::get('blogposts/title/{id?}', function($id = 1)
{
if (is_numeric($id))
{
$blogpost = Blogpost::find($id);
return $blogpost;
}
else
{
$column = 'slug'; // This is the name of the column you wish to search
return Blogpost::where($column , '=', $id)->first(); // find the name to id association
}
})->where('id', '[A-Z-a-z]+'); // force a slug upon them!
Note! You can also do this globally by way of using Route::pattern('id', '[0-9]+');
or Route::pattern('id', '[A-Z-a-z]+');
instead of the where we added above.
Get Your Verbiage Right
Up until now we have been using the get
verb exclusively. There is more than one verb to use though young Laraveler! We have been using get
since this is what is used to capture the HTTP requests we have been making to our small applications.
Anytime a web browser makes a request, it does so with a verb. get
is the most common, since let’s face it, we are usually getting a web page to view on the internet. No matter the website you visit, the get
request is what allows you to view a webpage.
In addition to the get
request, the next most common is the post
. post
is used to send along some data with a request. The most common use case is submitting a form on a webpage.
So in addition to Route::get();
and Route::post();
Laravel also provides Route::put();
, Route::delete();
, and Route::any();
The methods listed here all take the same parameters which allows us to choose any verb for the right application. This is the beginnings of RESTful Routing. RESTful Routing will be a whole other tutorial as it does get a bit involved.
Parameters to Verbs
In all of our get requests so far, we have been handing it a string, and a closure. In a generic sense it looks like this:
Route::get('string', function(){ echo 'closure';});
It is nothing more than two parameters separated by a comma. The string
is the URL to match against, and the closure is simply an anonymous function with some action to take inside of it. Consult with Chuck Norris, I mean Douglas Crockford, for a mind bending exercise in understanding closures in all of their glory.
The Routing Takeaway
Routing in Laravel is the glue that holds it all together. In the beginning with our small applications, it is fine to use Explicit Routing and Routing to Closures. As we dig deeper into Routing, we are going to want to really explore RESTful Routing and Routing with Controllers in Laravel.