In 2015 I started a software development business called Off Grid Engineering, originally to build software for Off Grid Energy Systems using embedded controllers, but as luck would have it my first gig was to write a web based Application completely unrelated to that area. For the new app the client needed a responsive interface (like Bootstrap), administration forms and some workflow logic for the business layer.
My language of choice was going to be PHP, as I had written plenty of web based support apps in the past using micro frameworks (written in PHP) that I had knocked up and refined over the years. But times change and I thought it was a good time to learn a new mainstream framework with a modern technology stack that also catered for scalability in the cloud.
Some of the design requirements are as follows:
- Cloud hosted (on Linux).
- Scalable via distributed Servers when load capacity grows.
- Clustered storage for user content.
- Capable of being deployed across database servers.
- Flexible software framework.
- Modern Technology stack.
- No License fees.
I spent a bit of time designing the architecture of the app and decided that a pre-built framework was a better option than crafting one from scratch. Enter Laravel!
I reviewed a number of frameworks and Laravel attracted my interest, so a few months down the track I’m now coding in it and liking the coding facilities it offers.
However, the path has not been easy and a blog post I saw recently proposed the question “Is Laravel 5 too hard for beginners?”. This gave me the idea to write up a rapid application development blog article, so I made notes as I went and as I learnt new aspects of the framework.
Why don’t the examples work?
One of the first issues was getting the installation of Laravel 5 working on Centos 7 and running the numerous examples. I installed the PHP Composer and then the Laravel 5 package and soon discovered much of the documentation on the web relates to Laravel 4.2 and below. It seams a lot has changed between versions and as a beginner this caught me out early on. The install is easy and has a few steps that you need to perform afterwards to get functional apps going.
Laravel 5 has already progressed to 5.1 but 5.1 needs PHP version 5.5.9 while v5.0 needs the earlier PHP 5.4.x so I decided to just go with 5.0 initially and worry about PHP 5.5 later.
The Composer tool allows you to install PHP packages, I’m not fully clued up on it but the following installs it and then I moved and renamed the composer.phar file to /usr/local/bin so it was able to be run anywhere:
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
Next I tried to install Laravel into a working web directory in /var/www/vhosts/<doman-name> so I ran the Composer tool to download and install the preferred Laravel packages using the following:
composer global require “laravel/installer=~1.1”
composer create-project laravel/laravel –prefer-dist
The result was not good, as I discovered the version miss-matches:
Installing laravel/laravel (v5.1.4)
– Installing laravel/laravel (v5.1.4)
Created project in /var/www/vhosts/<domain-name>/laravel/laravel
Loading composer repositories with package information
Installing dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
– This package requires php >=5.5.9 but your PHP version (5.4.16) does not satisfy that requirement.
– laravel/framework v5.1.4 requires php >=5.5.9 -> your PHP version (5.4.16) does not satisfy that requirement.
– laravel/framework v5.1.3 requires php >=5.5.9 -> your PHP version (5.4.16) does not satisfy that requirement.
– laravel/framework v5.1.2 requires php >=5.5.9 -> your PHP version (5.4.16) does not satisfy that requirement.
– laravel/framework v5.1.1 requires php >=5.5.9 -> your PHP version (5.4.16) does not satisfy that requirement.
– laravel/framework v5.1.0 requires php >=5.5.9 -> your PHP version (5.4.16) does not satisfy that requirement.
– Installation request for laravel/framework 5.1.* -> satisfiable by laravel/framework[v5.1.0, v5.1.1, v5.1.2, v5.1.3, v5.1.4].
To get around this I went with version 5.0 rather than 5.1, I will upgrade later and move my code across later.
composer create-project laravel/laravel drs 5.0 –prefer-dist
This resulted in a functional working installation in a directory called “drs“. Next I ran “chown” to make the files owned by the Apache web server using:
chown -R apache:apache /var/www/vhosts/<my-domain-name>/laravel/drs/*
Starting the Application
The Laravel 5 welcome page is displayed when the index.php file is run in the public directory. This means your document root needs to be set to the Laravel 5 “public” directory, in my case:
If you have installed the code correctly you should get the Welcome screen. If not, have a look in your web server logs for any clues.
After the Welcome screen is viewable, some configuration settings need to be set. Firstly your database and secondly some additional declarations for Forms and HTML libraries that appear to have been moved from the core code and into something called the “Laravel Collective”. The configuration settings are in config/app.php, open this file with vi and add the following line in the “providers” section:
In the “aliases’ section add the following after the “view” entry:
The first gocha I found is database access, there appears to be two places where this is set, the first and most logical is config/database.php. I have a mysql (mariadb) DataBase server installed specifically for this app, so I created a database called lv5, with user and password details in hand I edited config/database.php. I then discovered there is a file called .env in the base directory. This file also contains the same database configuration parameters, so I set these accordingly. I’m not entirely sure why the .env file exists but that will be researched and presented in a later article.
So to wrap up the basic “getting started process” is:
- install Composer, install laravel/laravel (vendor/package)
- configure httpd
- configure DB and additional libraries
- Booting up Welcome from public/index.php
Design and Build your Application
I’m sure there are lots of experts who can tell you their ideas on the best way to get up and running with Laravel 5. For me its been some degree of experimentation and applying previous experience from building lots of other Intranet web applications. For this project there is User Workflow Functionality and an administration sub-system needed. After discussion with the client on the requirements I decided to tackle database tables, administration forms and routing first. This would require me to get to grips with the MVC concepts used by Laravel.
MVC stands for Model-View-Controller, it is a nifty software architectural pattern for implementing user interfaces and relating it to the underlying data, think of it as a framework for separating your web app into logical partitions, its not a new technology as the term first appeared decades ago. Depending on your view point, if you think of the Model being the logic needed to control your data, the View being how you control rendering the passed in data and the Controller represents the classes needed to associate the data and the view. There are also several variants of MVC but they basically do the same thing.
You meed to get up to speed on the MVC concept as most of your development time is spent in these 3 areas of you app directory structure (more on this later).
During the creation of new files using the artisan tool it pays to run a command to cause the composer tool to update all its files:
I found this command fixes odd issues when files are created but nothing happens until the artisan tool is run later.
Referring back to our “Models” in the MVC definition above, we need to create classes that contain our logic to manipulate our database, typically all your CRUD code goes in the Model classes. The basic functions I add to a Model file are:
- getCount() – returns row count for the table
- Insert – Usually a single insert is all thats needed to insert a row.
- Update – Usually a few variants of Update, at least by ID, dates, status, specific parameter combinations for the various columns.
- Delete – Usually a DeleteByID($id) method and maybe one or two others. in this design, a Logical delete (changing the status to ‘X’).
- Various select methods, ideally with an index defined for each combination of select parameters to ensure quick data fetches rather than sequential table reads.
Using the artisan tool I created my initial model:
php artisan make:model Users
This does two things, it creates a file called app/Users.php and a database migration file in database/migration, in my case it was:
The first issue with models is when you run the artisan tool to make a Model file for you, it dumps the file in the app directory. There appears to be no specific “Models” directory. I created app/Models and put my model file for the users table in it and then tried to add an instantiation of the Users object into the welcome controller as a test – no luck!
In my app/Models/Users.php I created a getCount() function:
public function getCount()
The code I used to call it was:
$USERS = new \App\Users();
$count = $USERS->getCount();
Pretty basic, it uses the Laravel Eloquent to get the row count. However I received a class not found error. After some exploration on the web I located a command line to add to the composer.json file in the base directory:
After this I ran the command composer dump-autoload from the root directory of the application and things started to work. I had issues with extending the Models class from Models or Eloquent. I settled on “Eloquent” so my app/Models/Users.php file looks like:
<?php namespace App;
# 2015-07-05 Model for users table
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class Users extends Eloquent
public $timestamps = false;
public function getCount()
I’m still not clear on which class you need to extend a model from. More research in a future article!
From this point it pays to create a Model for each database table, so if you have 20 tables, then you will have 20 models. Having worked on apps with 600+ tables, this is a small amount. The section of the Laravel Documentation you need to skill up with when writing models is the Eloquent ORM, it does all the hard work for you in terms of constructing SQL calls. So far I have not had to write a specific SQL statement, instead call chaining has provided basic functionality.
In a future article I will add more functionality into the Users model, specifically I will add the CRUD layer so we can insert rows, delete rows and update rows as well as a number of select methods for getting the data back.
I should point out that Laravel does come with a user and password_reset models but I didn’t use these in my app design.
Additional information of value on the ORM (and Eloquent) used in the models files can be found here:
Laravel 5 provides a mechanism to create database tables using a concept it calls “Migrations“. Basically you create a PHP class (partially done for you when you create a model) that represents the configuration of your table and run a command to then create the table (or multiple tables defined in multiple files). To create this class see the “Models” section above.
The command to run the migrations is (from the base directory):
php artisan migrate
What this does is execute all the PHP code in the database/migrations directory provided it has not already run them previously. It keeps track of what has been run using a table called “migrations“. While you can manually create the table files, the artisan utility can be run to do the templated work for you, in the processes it creates a file which has a file name that is constructed from the current time so that code is executed in order. This concept means you need to define base tables in order so that indexes and foreign keys can be defined. It has a lot of advantages over writing SQL scripts, particularly if you change database vendors.
As I started there were lots of changes to make to many tables as more functionality was coded in, Laravel does provide the ability to script column additions and removals nicely. But during development I found it easier to just blow the database away and create a new one, then run the migrations and have the database structure ready in a single go. This is great during development but not do-able after production deployment.
The artisan tool can be used to make skeletons of a migration file, I suggest you use it so you get the time stamp correct. If you do find later that you need a parent table before a new child table, you can copy the child and rename it to the parent table and then decrement the time stamped file name so it runs before the child (hope that makes sense). That way your foreign key relationships will work when you run a fresh migrate command on a fresh new database.
Here is a typical table definition using a PHP class:
class CreateUsersTable extends Migration
public $timestamps = false;
public function up()
Schema::create(‘users’, function(Blueprint $table)
public function down()
Another trap I found was to define a default for dates. Initially I used the PHP date function but now I just set ‘0000-00-00’. When you seed a database table which has a date, the seeder fails if the date field is not defined with a valid value. I have also found you can just specify a date of ‘0000-00-00’ if needed, then when you do an insert you include the current date using $today=date(‘Y-m-d’); to set todays date and insert that into all the ‘date’ specific fields needed.
This brings me onto “Seeding”.
Filling in the tables with default data is called “seeding” and the artisan tool supports seeding your database using the command:
php artisan db:seed
The seed files are also PHP classes and defined in the database/seed directory. In addition, the seed classes must be defined in a PHP file called DatabaseSeeder.php. There are some traps to seeding, I had no need to timestamp my files so I needed to specifically disabled time stamping. This is achieved by adding the line to each migration file:
public $timestamps = false;
The Development Cycle
As soon as I started to build Models and craft database creation code I needed to display the data in a View and this requires a Controller class to get the data and call the view, there is also Authentication to be added to secure the appropriate Views.
In part 2 I will start on the Controllers and how to setup view files and call them with data.
Part 2 – Controllers and Views
Wrapping Up Part 1
- The design process is not fixed, it can be done many ways;
- Design your database tables in order so the foreign key relationships are valid when you try to create tables.
- For each table, create a model file with the basic CRUD layer.
- Create Database seeders to get initial data into your Database tables.