Differences between Laravel 3 and Laravel 4

This post is one of the lessons that will be published in my new Udemy course. I decided to have a few lessons available for free for anyone to act as a reference.

If you have used Laravel framework before you might know that Laravel version 3 was a very decent release of Laravel. It was fast, easy to work with, extendable through “bundles” and brought a lot of positive change into PHP world. Development was fun again! Some of my applications still use Laravel 3 and there’s nothing wrong with using Laravel version 3 for your applications. The old documentation is still available at http://three.laravel.com/docs.

Version 4 of the framework was released by Taylor Otwell in May 2013. And once again Laravel has shaken the PHP world and has brightened its future.

Most of framework’s functionality has remained the same. For example such things as the eloquent and clean syntax, most method names, concepts behind building the applications are still the same. You will see a detailed function comparison towards the end of this lesson.

Under the hood of Laravel though, a lot has changed. Laravel now uses Composer to manage its dependencies (libraries and parts of the core). Composer is the best and easiest to use dependency manager out there for PHP. Laravel 4 itself consists of a set of Composer packages so it is now more modular and in turn more testable. Even though it might seem a bit harder to get started (since it requires to install composer) the long term benefits of maintenability will be obvious as you use it. I encourage you to try Composer if you haven’t done so yet, it is easy to get started with it : http://getcomposer.org/doc/00-intro.md

Laravel 4 is a lot more powerful than Laravel 3 and that power comes from new features such as :

  • Using queues for processor heavy tasks (kind of like cron jobs but more flexible and could be offloaded to another server).
  • Expanded Eloquent ORM operations like soft deletes, collections, scopes, better protection of passed data.
  • Expanded Routing features such as pattern based filters, sub domain routing, model binding for routes.
  • Change of syntax to conform to PSR-0 and PSR-1 standards. snake_case has been replaced with camelCase : get_index is now getIndex, etc…
  • Seeding of DB.
  • Built in Mail component.
  • Expanded Events features with ability to queue events and also addition of model events.
  • Easy extension with over 16000 packages available through Composer (comparing to 200 bundles in L3).
  • More unit tests (over 2000 tests for framework’s components) and more testable environment for your application.
  • IoC container improvements.

If you want some more specific differences in Laravel 3 and 4, here are a few:


Route parameters are now enclosed in curly braces instead of parenthesis, example:

Route::get('posts/{id}', function($id) { ... });

You can now limit the route parameters to only respond to specific URL patterns by attaching “where” to the end of the route declaration:

Route::get('user/{name}',function($name){ ... })->where('name','[A-Za-z]+');

There are a lot more dynamic ways to work with the routes now, check with the documentation here: http://laravel.com/docs/routing


All controllers are now RESTful by default! No need to do $restful = true for the controllers.

Routing to controllers has changed a bit too, the action would in controller would be prefixed with the method, example:

Route::get('posts/{id}', 'PostController@view'); 
  class PostController 
    public function getView($id){ ... } 

Also, assigning a controller to all actions what follows “posts” (such as ‘posts/all’, posts/view/1 , etc) in the URL:

Route::controller('posts', 'PostController'); 
class PostController { 
  public function getAll(){ ... } 
  public function getView($id){ ... } 
  public function postView($id){ ... } 

Laravel is now more than ever suitable for building APIs with the use of Resource routes, for example a definition like this would give us a nice RESTful route following conventions:

class PostController{
  public function index(){ ... }
  public function create(){ ... }
  public function store(){ ... }
  public function show($id){ ... }
  public function edit($id){ ... }
  public function update($id){ ... }
  public function destroy($id){ ... }	

Actions handled by this resource controller

Method Path Action Route Name
GET /posts index resource.index
GET /posts/create create resource.create
POST /posts store resource.store
GET /posts/{resource} show resource.show
GET /posts/{resource}/edit edit resource.edit
PUT/PATCH /posts/{resource} update resource.update
DELETE /posts/{resource} destroy resource.destroy


The main differences are now in how the layout components are named. For example:

@layout becomes @extends

@endsection becomes @stop

@forelse is removed

@render is now @include

For AngularJS lovers, there is a new way to not process a string wrapped in curly braces by appending “@” before the echo statement:

@{{This will not be processed byBlade}}

Displaying language lines can now be done in the following way:




Models and DB:

Lots of good changes here, for example the Eloquent relationships have now expanded with Polymorphic relationships besides the standard one-to-one, one-to-many and many-to-many. Polymorphic relationships allow you to use the same table for multiple types of data.


There are some few minor changes in the conventions:

public static $table = ‘table_name’

is now protected $table = ‘table_name’

public static $key = ‘key_name’

is now protected $primaryKey = ‘key_name’

public static $timestamps = false

is now public $timestamps = false

Advanced querying

You can now query nested relations, for example this would retrieve only comments that have title “foo” attached to the post with ID of 1:

$comments = Post::find(1)->comments()->where('title','=','foo')->first();


New addition to Laravel 4 called scopes allow you to define a query that you can simply reuse anywhere in your application. For example:

class Post extends Eloquent { 
  public function scopePopular($query)
    return $query->where('comments_cache', '>', 100);

use it:

$popularPosts = Post::popular()->get();

Caching of queries now can be done with this simple appendix”remember(howManyMinutes)” to your queries before the get() or paginate():

Posts::where('title','my cool title')->remember(10)->get();

Soft Deletes

Soft deleting provides you with a way to not remove the data from the database but instead places a deleted_at timestamp and provides you with a way to still work with your data and if necessary access the deleted data.


Artisan has many new commands, you can see the full list by typing “php artisan list” in the terminal!

As you can see, there are a lot of nice changes that make Laravel even more powerful and those new features don’t come at cost, using the new Laravel will be beneficial for all your new projects!

What do you think? Based on your experience, what else is different in L3 and L4?

Liked it? Take a second to support Maks Surguy on Patreon!
Become a patron at Patreon!

You may also like

One comment

  • aditya menon October 18, 2013  

    Awesome, thanks for the useful roundup! Could you consider writing another couple posts, with: 1) The coolness of how Composer makes Laravel better (what is it I can do now that I couldn’t before in this context) and 2) A deep look into Eloquent 4 (I know the docs are hard to outdo here :)).

Leave a comment