Laravel 4 – simple website with backend tutorial – Part 1


Laravel 4 app will be developed at the same time as writing this article, and everything will be up on Github. I’ll try to separate the tutorial parts in branches so it will be easier to follow. Github URL:

EDIT: The second part of Laravel 4 tutorial is available!!!

This is by no means a tutorial for beginners, there are plenty of those 😉 I assume you already know the basics on how to install Composer, pull down the Laravel 4 base application. You will need some mid-level knowledge on tools like Composer, Git, working in the terminal

I’m going to put up some links to resources on getting started with Laravel and Composer at the end of this article. Also keep in mind that at this point Laravel 4 is still in BETA, but it’s really stable and scheduled for release during May.

Installing Laravel 4 and all the dependencies

Since Laravel 4 already leverages a lot of third party packages, we’ll expand on that, and add some that could be useful for our application. Here are some of composer packages that we’re going to need:

  • Sentry – user authentication (cartalyst/sentry)
  • Imagine – image manipulation and resizing (imagine/Imagine)
  • Markdown – for converting markdown text to HTML (dflydev/markdown)

So, first let’s start by creating a new L4 app. We’re going to call our app simply “L4 Site”. You can call yours anything you like 😉

git clone -b develop git:// l4_site
cd l4_site

The next step is to setup our composer file. After adding our dependencies, it should look like this:

    "require": {
        "laravel/framework": "4.0.*",
        "cartalyst/sentry": "2.0.*",
        "dflydev/markdown": "v1.0.2",
        "imagine/Imagine": "v0.4.1"
    "autoload": {
        "classmap": [
    "scripts": {
        "post-update-cmd": "php artisan optimize"
    "config": {
        "preferred-install": "dist"
    "minimum-stability": "dev"

Then just run “php composer install” and wait for all the dependencies to download. This could take a couple of minutes.

When everything is finished downloading we need to check if the app actually works. For this I would recommend to setup a virtual host entry, or if you working on a machine with PHP 5.4 you can utilize the PHP built in server by running “php artisan serve” from the console.

For simplicity sake I’ll take the approach with the build in PHP server which will start the server on the URL http://localhost:8000/.
If you get the Hello World! page then everything is fine, but if you see any errors you should consult the Laravel 4 documentation.

Setup the database and migrations

The next step is to setup the database connection and create our migrations. I’ll be working with a MySQL database, but you can choose whatever database type you want as long as Laravel 4 supports it. If don’t know what migrations and seeding are, you can read more on that here:

My database is named “l4_site”, and now I am going to enter the database credentials into the database configuration file (app/config/database.php). This is pretty straightforward, but if you run into problems consult the Laravel 4 documentation.

Since we’re leveraging the Sentry package for our user authentication stuff, and Sentry already has some migration setup, we just need to run those migrations by running the following command in our console:

php artisan migrate --package=cartalyst/sentry

Sentry should create 4 DB tables: users, groups, users_groups and throttle. To complete installation for the Sentry package consult the Sentry docs:

EDIT: Some people complained there’s not enough info on installing Sentry, so basicaly you need to add the service provider and the alias to your app/config/app.php file:



'Sentry' => 'Cartalyst\Sentry\Facades\Laravel\Sentry',

I hope this clears it up.

Now that we have our authentication tables setup, we need to create tables that will contain the actual content. We will have 2 types of content entries, articles and pages. So the migrations that we need are these:

php artisan migrate:make create_articles_table --table=articles --create
php artisan migrate:make create_pages_table --table=pages --create

The migrations are created inside the directory “app/database/migrations“. To keep things simple, these are my migrations.


use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateArticlesTable extends Migration {

    public function up()
        Schema::create('articles', function(Blueprint $table)

    public function down()

and Pages:


use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePagesTable extends Migration {

    public function up()
        Schema::create('pages', function(Blueprint $table)

    public function down()

Now just run “php artisan migrate” and the tables are created. It’s magic 🙂

Our models

To actually work with the database we need to create our models. The models that we need are:

<?php namespace App\Models;

class Article extends \Eloquent {

    protected $table = 'articles';

    public function author()
        return $this->belongsTo('User');



<?php namespace App\Models;

class Page extends \Eloquent {

    protected $table = 'pages';

    public function author()
        return $this->belongsTo('User');


There’s already a default User model in the “app/models” folder, I just like to namespace it like the others under App\Models. Go ahead and check it out at:

Seeding the database

For the app to actually contain some data, I like to add some dummy content. This can be achieved easily by using the Laravel 4 seeds. The files should be located in the “app/database/seeds” directory, and here my setup for the app:


class DatabaseSeeder extends Seeder {

    public function run()
        $this->command->info('Sentry tables seeded!');

        $this->command->info('Content tables seeded!');


EDIT: Since we use the Sentry package I changed the way the user is created. We now use


for creation.

Also note that the User model is namespaced under App\Models, so you should also update you default model. Just take a look at everything here:



use App\Models\User;

class SentrySeeder extends Seeder {

    public function run()

            'email'       => '',
            'password'    => "admin",
            'first_name'  => 'John',
            'last_name'   => 'McClane',
            'activated'   => 1,

            'name'        => 'Admin',
            'permissions' => array('admin' => 1),

        // Assign user permissions
        $adminUser  = Sentry::getUserProvider()->findByLogin('');
        $adminGroup = Sentry::getGroupProvider()->findByName('Admin');




use App\Models\Article;
use App\Models\Page;

class ContentSeeder extends Seeder {

    public function run()

            'title'   => 'First post',
            'slug'    => 'first-post',
            'body'    => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
            'user_id' => 1,

            'title'   => 'About us',
            'slug'    => 'about-us',
            'body'    => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
            'user_id' => 1,


Now run “php artisan db:seed” in the console, and your database will be populated with the dummy data from the seeds. Nice.

Extra tip on database seeding

I created a couple of custom artisan commands to refresh the app. You can check them out:

This is useful for me when working on the app, and sometimes the data is modified, or some entries are deleted. Then I can easily reset the database to a fresh state by running:

php artisan app:refresh

Also, since the migrate command doesn’t migrate 3rd party packages, I added the Sentry migration to the command.
You can add your own commands, call other package migrations etc.

Tinker with our models

Laravel 4 comes with a nice tool for tinkering with out app.
What we can do now is test if the database was properly seeded. Just run “php artisan tinker” and we get into a simple REPL for our app.

Now to check if our pages and articles were seeded we just run the following inside the REPL:

echo App\Models\Page::all();


echo App\Models\Article::all();

And for each command we should get our database content entries in JSON format.

What is next?

For now we just created our database and models, added some dummy data to the database, and there isn’t really much to see in the browser yet.

In the next part we will start to create our backend panel so prepare yourself for some working with routes, controllers, views and assets.

The backend will be built with the Twitter Bootstrap package, since I find it’s the easiest to integrate.

You can now see the second part of Laravel 4 tutorial

About the author

Boris Strahija

Web developer with over 10 year of experience mostly in PHP. Currently working with Laravel 4 and Codeigniter.
I also enjoy drumming, playing squash and a little bit of design.

<span class="dsq-postid" data-dsqidentifier="1663">85 comments</span>

  • Can you please provide example for using with Visual Basic. I would prefer to use VB than the strange scripting language you are demonstrating.

    • You must be new here 😉

      Laravel is a PHP framework. It does not, and will never work with VB. They are completely different. To be honest, if you are serious about developing web sites, you would greatly benefit from learning PHP and/or Java. Nobody sane uses VB for web sites anymore.

  • Most of the API from L3 is the same. There are a few differences where L4 now uses camel case instead snake case for method names, but most of it remains the same. I guess the biggest differences are that there are no more bundles, you have to use composer packages. Swing by the Laravel forum and you will find enough resources on this topic in the L4 section.

    Also, why not build you app already with L4. It’s stable enough and so much better 😉

    • I’m going to be waiting for a full release on Laravel 4 as I’ve read several articles that already are outdated because things are changing in the development of it.

      • I don’t see a good reason to wait if you’re already building an app and are planning to rewrite it from L3 to L4 later. Seems like you’re gonna waste more time this way, than if you build it right away in L4 and just track the changes once a week. L4 will be out anyways in 3-4 weeks.

  • Thanks for the clean tutorial and cant wait for the next part, just a suggestion tho, i think its better if this back-end codes wrapped with the new package concept that introduced in L4

    • You mean build it as composer package? This is certainly one way to go, but it would add more complexity to the tutorial.

      It isn’t too difficult to create a package with the workbench feature (, and maybe as the last part of the tutorial I’ll convert most the code into a package. Would be a nice wrap-up 😉

      • sort of like that but more into modular scheme where each module loosely coupled, says admin, front-end, api each has separate models, view and controllers through workbench

        True the docs has given a starting point but still confusing in implementation, i make it work with some RTFM and trial/error but still not confident if mine is the correct implementations.

        would be great if theres a more detail guidances from those who understand laravel like you, thanks.

        • So not composer packages, but something like modules for app specific code? I did something like that in the CMS I’m working on, so I might write an article about that 😉

  • Hello, thanks a lot for the tuts, it’s what i was looking for to initiate L4

    Actually i get an error on the 1st step whene trying to install prerequisites with composer
    php composer.phar install give this :

    Failed loading D:/Servers/wamp/bin/php/php5.3.5/zend_ext/php_xdebug-2.1.0-5.3-vc6.dll
    Loading composer repositories with package information
    Installing dependencies from lock file
    Nothing to install or update
    Generating autoload files

    Could not scan for classes inside “app/commands” which does not appear to be a file nor a folder

    any idea i can i solve it ?

    • Well, first of all, this seems like an error on you local environment setup. I’m afraid I can’t help you with that.

      Second, Laravel 4 requires PHP 5.3.7, meaning you should upgrade 😉

      Third, regarding the “app/commands” error, if you want to create custom commands, create the folder, and your classes inside. If you don’t want that, then simply remove this line containing “app/commands” from your composer.json file.

  • This is one of the best tutorial on laravel 4.
    I hope you will go on with it.
    Thanks a lot in advance.

  • I had a small problem that took me way too long to figure out. When I tried to seed the database the ContentSeeder threw an error about not being able to find the Article class. I was sure this was a namespace problem but every seemed fine. I even replaced my models and seeders with the latest from the git repo, but still got the error. The fix was simple and stupid.

    I had to change:

    <?php namespace App\Models;


    namespace App\Models;

    Then everything worked and my database was seeded successfully! I finally got part 1 done, on to part 2!

    Thanks Boris!

    • I’m having the same issue but with the Sentry class not found. I’ve tried your method of returning the namespace to the second line, no luck. I also did dump-autoload. still throws error.

      not sure how to proceed.

      • Where exactly do you get the error? What’s the exact error?
        Did you properly install Sentry? You need to add the Sentry service provider and also define the facade in “app/config/app.php”.

    • Same problem here …, tried the composer dump, no good, tried the namespace in Article to line 2 and worked ….???

      replaced the namespace in Article, back to 1st line and works too …???
      probably a char related issue in copy$paste between <?php and namespace in Article file

  • Great head start tutorial – just what I was looking for! Up and running without a glitch and provides valuable coding samples.

    One question though: Could you elaborate a bit on why taking cartalyst and the Sentry stuff. Ok, you claim the laravel 4 authentication is too basic, but what is the status/stability of Sentry – or cartalyst in general?

    Thanks a lot!

    • I’ve been using on a couple of projects the last few months and haven’t had any problems. I think it should become stable when L4 comes out.
      I think the main reason to use it is because L4 doesn’t have any ACL functionality. I could have used L4s auth functionality for this tutorial, but I still haven’t decided how far I’ll take, so maybe at some point I’ll add some user roles/permissions, and without Sentry I would need to write this part myself.

  • Thank you for the tutorial. I can’t finish it unfortunately. I get

    Sentry tables seeded!

    [Illuminate\Database\Eloquent MassAssignmentException]

    db:seed [–class[=”…”]] [–database[=”…”]]

    when executing “php artisan db:seed”. Do you have any idea why? I checked everything multiple times, everything seems right; also issued “composer dump-autoload” prior to seeding. Thanks!

    • Well you’re missing the tables in your database, which means you probably skipped the sentry migration part:

      php artisan migrate --package=cartalyst/sentry

      • Don’t get so defensive. It is a great help you put this together for everybody but these guys are right. Perhaps something changed before the final release of L4 but something is not right if you follow this tutorial as is. Whether you do the auto-dump or use line 2. The errors still persist.

        • I’m not getting defensive, I’m just trying to explain that if you properly upgraded Laravel during the beta period this error shouldn’t happen. Nobody has given me enough information that I could take a look and see exactly what the problem is, I can only assume with the provided info. So let’s assume 🙂

          Open the file “app/database/seeds/DatabaseSeeder” (this is part of Laravel, so get the latest version first), and check if the method “run()” has “Eloquent::unguard();” before any seeder calls. If this still doesn’t help you, please provide me with a link to your app and I’ll take a look.

          • Hey Boris,

            You are right on.

            Here is the GitHub issue thread where Taylor says he added the “Eloquent::unguard()” method for these specific cases of seeding the database:

            The issue does not relate to any specific field, but only the first field attempting to be seeded. In this case “title” is the first field, so if “title” is removed or moved to the bottom of the list, the error will begin throwing “slug” as the culprit.

            This issue will not be present in other, application-specific, usage because the Eloquent Model will have either the “fillable” or “guarded” array defined.

            Thanks for writing this tutorial, Boris! You’re awesome! 🙂


          • in Laravel 4.1
            for secure reason ,must setting $fillable attribute in model
            protected $fillable = array(‘title’, ‘slug’, ‘body’,’user_id’);

            protected $fillable = array(‘title’, ‘slug’, ‘body’, ‘user_id’);

            then you no need use Eloquent::unguard(); to feeding

  • Hi Boris, thanks for the reply!

    I managed to solve this by adding


    at the top of the run() method from every *Seeder class. I’m not sure this has anything to do with changes in Laravel (I’m using Beta 5).

    Thank you again.

    • I think you should do a composer update because, if I remember right, Taylor added the unguard() call in the seeder automatically. So I guess you can try to update you L4 installation.

      • Boris, I followed your advice with latest Laravel version but the error message persisted. I tried Chris’s suggestion and it worked.

  • Thanks for this tutorial!

    One thing to note: I ran into a lot of problems copy/pasting from the code samples above. It appears it was due to tabs vs. spaces. Once I copied the raw code from Github, the migrations and seeding went just fine!

  • I had to add the line “use Eloquent” in my models’ files to get the tinker part of the tutorial working.

  • Hey!
    Thx for your nice tutorial. Just one thing I experienced.
    In my Models I had to set the fully qualified path with double backslashes in order to use relations with namespaces. So here for example:

    return $this->belongsTo(‘User’);

    I had to change it to:

    return $this->belongsTo(‘App\\Models\\User’);

    Before I got an Exception with Class “User” not found…

  • run command “php artisan db:seed”..but return segmentation fault (core dumped) in terminal…need help 🙁

    • I don’t think this has anything to do with this tutorial or with Laravel. There’s probably an issue with your PHP installation.

  • Hi!, Just wnated to say that I just completed your first tutorial and it really hleped a lot, so thanks for doing this!

  • […] Caution! this will erase your whole Database!  Note: this command is taken from the excellent laravel4 tutorial project by Boris […]

  • Hello,

    When seeding the database I managed to get this error.

    var/www/*****# php artisan db:seed
    Sentry tables seeded!
    PHP Fatal error: Class ‘App\Models\Article’ not found in /var/www/*****/app/database/seeds/ContentSeeder.php o n line 13
    {“error”:{“type”:”Symfony\\Component\\Debug\\Exception\\FatalErrorException”,”message”:”Class ‘App\\Models\\Article’ n ot found”,”file”:”\/var\/www\/*****\/app\/database\/seeds\/ContentSeeder.php”,”line”:13}}*****@*****:/

    Any ideas? 🙂

      • I didn’t run composer dump-autoload. I did so and it worked though that created a new error when accessing the site through the web browser.

        Error in exception handler: The stream or file “/var/www/*****/app/storage/logs/log-apache2handler-2013-07-05.txt” could not be opened: failed to open stream: Permission denied in /var/www/successbreak*****/bootstrap/compiled.php:7268

          • I’d say it’s a permissions issue due to the “Permission denied”, though looking at the docs and other issues involving files in the bootstrap folder like compiled.php and autoloader in relation to composer commands has made me none the wiser. I’ve tried changing the permissions, deleting the complied.php file and a few other things. I’m not sure I’m capable of fixing this one.

  • hello , for those of you who want to run this tutorial, please don’t copy paste the syntax from the syntaxhighlighter because it create whitespace that make your code don’t run with php. try to type the code manually.

    btw thank you for this great laravel tutorial 🙂

      • I think he meant “what’s wrong with the code in the email address field of the SentrySeeder”, since I’m also having problems seeding with this file. In your l4-site-tutorial/app/database/seeds/SentrySeeder.php git site there is no such javascript validation.

        Which one is right?


      • I presume Chris is talking about all of the that occurs in the email field?
        What is it for?
        Like the tutorial series though, more of this sort of thing 🙂

      • It looks like a hacker added a little SQL injection script to your app/database/seeds/SentrySeeder.php code example. It wasn’t even properly escaped so the worst that would happen is people would get php errors when trying to seed the database.

  • Thanks for clarifying the javascript part of the SentrySeeder! That’s very kind of you.

    • Ok it’s just a mistake in the page. It’s a script maybe to cloak the emails to bots or something. It may be caused by a plugin that weren’t supposed to show the code. Just remove it or download the files from the git site.

  • Thanks for this very interesting tutorial!
    Can i make two question?

    1- the command php artisan app:refresh does not work with me: There are no commands defined in the “app” namespace.
    What i did is go to github and copy the three files into app/commands.
    I have to do something else perhaps?

    2- When i try to run bd:seed i get an error in SentrySeeder.php on line 16. But i just copy it from the turorial.

    Thank you!!

    • Don’t forget to register the custom artisan commands in /app/start/artisan.php;;

      Artisan::add(new AppInstallCommand);
      Artisan::add(new AppRefreshCommand);
      Artisan::add(new AppSeedCommand);

  • Hello.
    I resolve the seeding issue deleting the javascript code and running composer dump-autoload.
    But still i am not able to make working the new commands. I have just to copy the files into App/Commands and they should work, no?

  • For php artisan tinker, I can’t execute with “\App\Model\”. It said the class not found. So, with only “Articles::all()” it runs well

  • Don’t forget to register the custom artisan commands in /app/start/artisan.php;;

    Artisan::add(new AppInstallCommand);
    Artisan::add(new AppRefreshCommand);
    Artisan::add(new AppSeedCommand);

  • Nice Job.
    Just a note for the custom commands tip
    don’t forget to register the commands in


    something like

    $artisan->add(new AppInstallCommand);

    $artisan->add(new AppRefreshCommand);

    $artisan->add(new AppSeedCommand);

  • Awesome, thanks a lot. I’m just starting out using Laravel and your post helped me a lot to get a better idea of all this magic!

  • Hi, I tried the above procedure. But i am getting the error regarding tables doesnt exist about groups, Users_groups and Users. I tried as per your reference link. Still not getting. can youi please provide those table structures plz.

      • Hello there, I am having this same problem while trying to seed the articles and pages content and when I try php artisan migrate –package=cartalyst/sentry it echos a message that “nothing to migrate”

  • Headups:
    The git command to install, installs 4.2.*. Had to down grade framework to 4.1.* and do composer update.

    also, couldn’t run db:seed with these in start/artisan.php

    Artisan::add(new AppInstallCommand);
    Artisan::add(new AppRefreshCommand);
    Artisan::add(new AppSeedCommand);

    had to comment out.

    UPDATE: The above doesn’t work, PHP fatal: Class ‘AppInstallCommand’ not found in [route to]/l4_site/app/start/artisan.php on line 14

  • While seeding on Laravel 4.1 I was getting the error: [IlluminateDatabaseEloquentMassAssignmentException]

    Which I was able to fix by adding the following line to the Articles and Page models:

    public static $unguarded = true;

    • I’ve same issue, but add, like the doc said on the mass-assignment :
      into both models, Article & Page :
      protected $fillable = array(‘title’, ‘slug’, ‘body’, ‘user_id’);
      And seeding ok 😉