An extension to the CodeIgniter framework that would provide certain features out of the box such as basic authentication and authorization for a side project that a .NET programmer, Taylor Otwell was doing back in 2011, would grow to become the most used open-source PHP framework for novice and expert programmers alike. With an endless list of built-in tools, a plethora of resources, topped with a vibrant community, support, and ecosystem, Laravel allows a PHP developer to rapidly develop web applications using an elegant syntax, share it with other developers and deploy to a destination of choice without breaking a sweat. A PHP framework for web artisans it is.
Out of the box, Laravel supports testing, routing, authentication, authorization, mailing, eventing, asynchronous job handling, periodic task scheduling, web socket connections, a powerful templating engine for view generation as the framework follows the model view controller design pattern and if you wanna connect to your databases, the active record Eloquent ORM topped with database migrations makes everything a breeze. At its core an intelligent IoC container allows for dependency injection, making the framework itself very customizable as you can swap the default implementations with your custom if you wish to. Laravel has already laid the foundation — freeing you to create without sweating the small things.
The internet does a pretty good job of explaining the features outlined above, and I do not think there is much I can do to add to that. To that end, I thought it would be better if we quickly got our hands dirty and kill a puppy developing yet another to-do list application. My hopes are this will be enough to give you a rough overview of Laravel features and development workflow. For brevity I will not be explaining some of the features here as that would just make the post too long, we will discuss those features in greater depth in the upcoming posts. To follow along make sure you’ve installed Laravel by following through the installation guide on the official Laravel docs.
Throughout this guide, I will deliberately leave out some minor details that may cause errors when running the code in your environment. I’m sure it’s nothing that you won’t be able to fix on your own. My hope is that getting these errors and fixing them yourself will enhance your learning experience. If you do get stuck and need assistance feel free to DM me on Twitter, as always, don’t forget to google.
Creating a new project
To create a new Laravel project, open your terminal and simply navigate to the directory where you want to put your code, in my case this was
$HOME/Documents/code and execute the
laravel new todo command. This will create a directory named
todo containing a fresh Laravel installation with all of Laravel’s dependencies already installed. When Laravel is done creating the application navigate to the newly created
$ cd $HOME/Documents/code $ laravel new todo --auth $ cd todo
Writing the tests
Everyone tests their applications, whether you use print or log statements to view the results of your method calls, manually test the entire user flow in your browser or view JSON responses from your API inside Postman. As the application grows in size, however, manual testing methods become tedious, and refactoring existing codebases becomes scary as you will not be sure which parts of your application will break by changing a certain part of your codebase. Test-Driven Development allows the developer to be confident that their code still works, even after aggressive refactoring that changes the entire application architecture, as long as the API does not change. Automated testing allows us to introduce new features and edit existing codebases with speed and without worry, and Laravel is built with automated testing in mind.
When users add items to their to-do list we will store them in the database, and show them a list of their items on the homepage. We can verify this behavior by using tests. To create a new test execute the
make:test artisan command inside the newly created
todo application directory. The command below will create a new class
CreateTodoTest inside the
$ php artisan make:test CreateTodoTest
CreateTodoTest class, add the following code. It just verifies that when a user submits the form using HTTP method
POST to the
/todos URI then we should have an entry in the database matching the submitted data and we should see the newly added item on the returned page. To execute the tests execute the
test artisan command, of course, if we run it now the test will fail, telling us exactly why it failed and thus guiding our development direction.
$ php artisan test
The above command will fail, telling us something about the route
todos not being defined. Let’s work to make the test pass.
The mechanism that allows Laravel to decide which method is going to handle which request is routing. When a user sends a
GET request to the
/todos URI we want to show them a list of to-do items, similarly, when they send a
POST request, with a new to-do item to the same URI we will store the new item in the database and show them a list with the new item added. We define our routes inside the
routes/web.php file. Add the following code to that file.
The above snippet tells Laravel that when it receives a
GET request to the
/todos endpoint then it should call the
index method of the
TodoController class. Similarly, the
store method of the
TodoController class will be called when the application receives a
POST request to the
Creating the controller
Controller methods are the final destination of our requests and Laravel makes it very easy to create them using the
make:controller artisan command. Before creating our controller though let’s create a request class
CreateTodoRequest that will be responsible for validating the submitted request data and checking if the user making the request is allowed to perform that action in the first place. Using artisan you create a form request by executing the following command.
$ php artisan make:request CreateTodoRequest
This will create a
CreateTodoRequest class inside the
./app/Http/Requests directory. Open that file and add the following code.
authorize method is used to determine if the user is authorized to make the request, in our case only logged in users are allowed to create a new to-do item. The method
Auth::check() returns true if the user is authenticated. The
rules method returns the rules that should be applied to the request, in our case we won’t allow users to post to the
/todos endpoint without providing the
description field, and if provided the field should only be a maximum of 126 characters.
Now that our request class is created lets create the controller using the
make:controller artisan command and add the
store methods as required by our
routes/web.php route definitions.
$ php artisan make:controller TodoController
$this->middleware(‘auth’) makes sure that all our controller methods can only be called by a user who is logged in.
The Active Record implementation Eloquent ORM that comes with Laravel allows us to access data in the database through objects of a defined class. The database table corresponds to a class and an object instance is tied to a particular row in the database. In our setup, we will have two tables in our database
todos, for keeping track of registered users and each user’s to-do items respectively. The classes that will correspond to these tables are the
User class and the
Todo class each of these classes will extend the base
Model Eloquent class. Laravel comes with a
User model already defined for us so all we have to do is to create the
Todo model using the
make:model artisan command. The
-m option allows us to generate a migration that we can use to define the schema of our
$ php artisan make:model Todo -m
A user will have many to-do items stored in the database and inversely every to-do item will belong to exactly one user i.e the user who created the to-do item. Let’s define this relationship in our model classes.
Todo class lets add the following code.
If you check inside the
database/migrations directory you will see that the
create_todos_table migration has been created. It’s prefixed with a timestamp of sorts, along with other default migrations that Laravel comes with. Open that migration file and add the following code.
up method is called when we run our migrations using the
migrate artisan command. As you can see inside that we are creating a
todos table with a primary key column
id, a foreign key
user_id that keeps track of the user who created the todo item, a
description for the actual todo item and a
done column which indicates whether the task is completed or not: by default, it is set to false. The
down method is called when we are rolling back our migrations, in this case, the
todos table will be dropped if it exists.
If you want to run the migrations yourself using the
$ php artisan migrate command, you should first make sure to connect your application to a database by specifying your database credentials and which database to connect to inside the
.env file that comes with Laravel. If you’re running tests Laravel will use an in-memory SQLite database to make the tests run faster, you can check the provided
phpunit.xml file provided by Laravel.
If you take a look at both the
store method of our controller you will see that they both return views. Views are the HTML that will be rendered by the browser. Creating views with Laravel is very painless, in our case we are returning a view called
todos so let’s go ahead and create the
todos.blade.php file inside the
./resources/views directory and add the following code.
View files in Laravel have the
.blade.php extension as Laravel uses the Blade templating engine for view files. As you can see we are looping over the
todos list which is available to the view since we added it with the
view()->with(‘todos’…) method in our controller, and displaying the description of the todo together with a checkbox that will be checked if the task is done. For the action property of the form we are using the
route() method to generate the URL to the named route
todos.store, we defined a name for this route inside the
routes/web.php file before.
Are we done yet
It has been a very short journey and we’ve accomplished a lot in a few minutes. Just to verify if everything works fine simply run the
$ php artisan test command and now it should pass verifying that everything is working according to our specification. Alternatively you could manually test your application by running the
$ php artisan serve command, opening your browser and navigating to
http://localhost:8000/todos URL. Feel free to add more features to the app like task completion and deletion if you wish to do so.
Laravel is very mature framework with a lot of resources online to help you in your development carrier. @Jeffrey Way does a really good job providing the most concise Laravel video tutorials on Laracasts. If you wanna up your game Adam Wathan created a test driven laravel video course. Shuan from the net ninja created a very beginner friendly series on laravel on youtube. There's a lot of resources online to help you in your development journey and on top of that I'm going to go over the most used laravel features in the upcoming posts. But before we do that let's try and explain the Laravel's service container to a five year old.