Nasrul Hazim Bin Mohamad

Laravel: Observer


Assalamualaikum & Hi,

Eloquent models fire several events, allowing you to hook into the following points in a model’s lifecycle: retrieved, creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored. Events allow you to easily execute code each time a specific model class is saved or updated in the database.

Based on events above, we can capture all the events mentioned above either by setup in model’s property called $dispatchesEventsor we can setup an observer to capture all the events above.

Here I’m going to show how to setup observer and then how you can manage your observers.


Create a new Laravel Application laravel new observer-app

Go into observer-app directory.

Create a directory called Observers in app directory and create a new file called OnCreatingObserver.php in app/Observers

OnCreatingObserver class will capture Eloquent event on creating a new record for a given model.

Now you need to register your model, to the OnCreatingObserver. Open up your app/Providers/AppServiceProvider.php and add the following in boot method.

Lastly, update your user’s migration file to add in new column called hashslug.

Run php artisan migrate


I always love to run and test things using Tinker, rather than test my backend codes on front-end – web.

Now create a folder in your application tinkers and add in a new file called create_user.php.

Open up create_user.php and add the following codes to create a new user.

Now run php artisan tinker tinkers/create_user.php. You should have something like the following:

Create user via tinker

Notice that we have our hashslug inserted – but we don’t even assign the value in the tinker (create_user.php)!

So, that’s how a simple user case on observe events emiited by Eloquent.

Problem Statement

So you know, you have the an observer and it’s awesome. Easy for you. But imagine you have more than 10 models need to observe the OnCreatingObserver. It’s a tedious job to manage and your AppServiceProvider‘s boot method will be bloated.


Three issues here:

  1. Bloated Codes
  2. Unmanageable Codes
  3. Single Observer, observe by many models.


Bloated Codes, UnManageable Codes

For the issue no. 1, the strategy, which I apply to my recent works – refer to how Laravel provide us to register custom commands in their app/Console/Kernel.php.

Same thing I will apply for the Bloated Codes.

Create a file name Kernel.php in app/Observers directory.

Add the following codes in app/Observers/Kernel.php. This kernel.php it’s an endpoint for register all your observers.

Above code will register all your model-observer based on your setup in $observers property. An example of the usage on how you should register your model and observer:

Once you’re done setup your model and observer, you may replace your \App\User::observe(\App\Observers\OnCreatingObserver::class); in AppServiceProvider.php with \App\Observers\Kernel::make()->observes();

Now you observers will be much cleaner and manageable.

BUT, another issue raised – what if you have a single observer, observed by many models? It’s a tedious job to register the same observer for different models.

Single Observer, Observe By Many Models.

For the previous issue, let’s refactor a bit:

Now, to add capability to register multiple models for an observer, we going to add two things:

Add property $observedBy:

Add method observeBy():

Now update your observes() to run both observeSingle() and observeBy().

You’re done now! Here some example on how you can setup your $observeBy property:

Final Kernel File for Observer

Observer App

Live: Laravel 101



It’s been a while since the last time I post in my blog.

Now just to share a bit of Laravel, 101 on my Facebook Live.

Training: Laravel – Batch 4


Registration Open Now!

Please register at Laravel – Batch 4

Course Details

Date: 16th & 17th April 2016


Fee: RM 300

Syllabus Details


The Basic
– Routing
– Controllers
– Views
– Blade Templates

– Migrations
– Seeding

Eloquent ORM
– Relationship

– User Management
– Access Control List

Training: Web Application Development with Lumen(API)


Date: Saturday, 6th February 2016

Available Seats: 25

Fee: Student – RM 100, Public – RM 250

Location: Level 2, above Yamaha Motorsport Shop Lot



To learn how to develop an API with micro-framework Lumen


Following items need to be install first before coming to the class:

  • Laragon
  • Git & GitHub Account
  • Sublime Text 3
  • Postman (


PHP & MySQL is compulsory. A good understanding of OOP is value added.


Software developers with PHP and MySQL background.


  • Installation
  • Routing
  • Controllers
  • Responses
  • Database
  • Migrations
  • Eloquent Queries
  • API Integration



Lumen: API Development – Episode II


In this episode, we will configure the environment of the API, and setup some fake data. For those not yet read the Episode I, you can read it here.

In general, we have these steps:

  1. Configure .env
  2. Create model
  3. Create migration script & do migration
  4. Create seed script & do DB Seeding

For the first few steps will straightforward before we continue with Eloquent.

  1. Rename .env.example to .env
  2. Generate 32 random characters and update the APP_KEY – I use textmechanic to generate random characters
  3. Next, open up bootstrap/app.php and uncomment the following lines:
    • Line 6 – to enable to load .env file
    • Line 25 – to enable Eloquent

Now we’re done with minimum requirement configuration for our API. Next, we going to setup our fake data.

Before proceed to the next section, if you noticed that I did not change much in .env. This is due we’re using homestead – everything is ready for our development, including the database. So, no need to further change the configuration file .env, unless we’re moving to production, you may want to configure for production.

For our fake data, I have a table called departments. The departments table have the id, name and ordering.

In this section, we will learn about Model, Migration and Seeds.

First, create a model for departments and save it in app directory.

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Department extends Model
	// for security concern, only allow these fields for mass assignments
	//
	protected $fillable = ['id','name','ordering'];

	// limit attributes displayed in model's array or JSON
	protected $hidden = ['created_at','updated_at'];

Next, we need to create Migration scripts for departments table. Run the following in Git Bash.

php artisan make:migration create_departments_table --create=departments

And open up the database/migrations/[date-time]_create_departments_table.php and update the up method as following. This will preparing our departments table schema.

<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateDepartmentsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('departments', function (Blueprint $table) { $table->increments('id');

     * Reverse the migrations.
     * @return void
    public function down()

Now connect to homestead via vagrant ssh and then run the migration script

php artisan migrate

Next, we need to add some fake data using the faker. Open up database/factories/ModelFactory.php and paste in the following codes in it:

<?php $factory->define(App\Department::class, function ($faker) {
    return [
        'name' => $faker->name,
        'ordering' => mt_rand(1,50)

[Update 20/1/2016]
Next, to insert our data, open up database/seeds/DatabaseSeeders.php and add the following lines in method run.


use Illuminate\Database\Seeder;

// include the model
use App\Department;

class DatabaseSeeder extends Seeder
     * Run the database seeds.
     * @return void
    public function run()
    	DB::statement('SET FOREIGN_KEY_CHECKS = 0');

    	// empty table first

    	// create 50 records
    	factory(Department::class, 50)->create();

        // $this->call('UserTableSeeder');

Now enter the vagrant ssh and go to document root of the API, then run php artisan db:seed. You may verify your data by login to MySQL.

So, that’s done for preparing our data, using some fake data. Next episode will be talking about Route & Controller. Stay tuned for next episode!

Web Services: Slim Framework + Eloquent(Laravel)


Setting up the Restful API is easy with Slim Framework & Eloquent(Laravel). Here are the steps:

  1. Install required components via composer – Slim Framework + Eloquent(Laravel)
  2. Create a database called web_services and create users table.
  3. Setting up Eloquent
  4. Setting up Routes
  5. Final Touch
Web Service Restful API

Web Service Restful API

Install the necessary components using composer – create a composer.json and save it in a working directory and run composer install.

    "name": "Web Services",    
    "require": {
        "php": ">=5.3.0",
        "slim/slim": "2.*",
        "slim/views": "0.1.*",
        "illuminate/database": "5.0.*",
        "illuminate/events": "5.0.*"
    "autoload": {
        "classmap": [

We’re creating a simple web services for Users – Simple CRUD. Create a database called web_services and run the following SQL statement to create user table.

CREATE TABLE `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `phone` varchar(45) DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)

Next, setting up the Eloquent. Create a database.php in config folder(Please create this folder in the working directory) folder.

$database = [
    'driver'    => 'mysql',
    'host'      => 'localhost',
    'database'  => 'web_services',
    'username'  => 'root',
    'password'  => '',
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',

use IlluminateDatabaseCapsuleManager as Capsule;

$capsule = new Capsule;


// Set the event dispatcher used by Eloquent models... (optional)
use IlluminateEventsDispatcher;
use IlluminateContainerContainer;
$capsule->setEventDispatcher(new Dispatcher(new Container));

// Make this Capsule instance available globally via static methods... (optional)

// Setup the Eloquent ORM... (optional; unless you've used setEventDispatcher())

Once we’re done with Eloquent, next we going to set up the routes for Users CRUD operations. Save your time, copy & paste the following codes and save it in config/routes.php.


$app->get('/api/users', function () {
    echo User::all()->toJson();

$app->get('/api/users/:id',  function($id) {
	try {
		echo User::find($id)->toJson();
	} catch (Exception $e) {
		echo '{"error":{"text":'. 'Unable to get the web service. ' . $e->getMessage() .'}}';

$app->get('/api/users/search/:query', function($query) {
	echo User::where('name', '=', $query)->get()->toJson();

$app->post('/api/users/add', function() use ($app) {
    try {
        $user = new User;

        $user->name = $app->request()->post('name');
        $user->phone = $app->request()->post('phone');
        $user->email = $app->request()->post('email');

        if($user->save()) {
            echo '{"message":"Successfully add new user"}';
        } else {
             echo '{"message":"Failed to add new user"}';
    } catch (Exception $e) {
        echo '{"error":{"text":'. 'Unable to get the web service. ' . $e->getMessage() .'}}';


$app->put('/api/users/update/:id', function($id) use ($app) {
    try {
        $user = User::find($id);

        $user->name = $app->request()->post('name');
        $user->phone = $app->request()->post('phone');
        $user->email = $app->request()->post('email');

        if($user->save()) {
            echo '{"message":"Successfully update user info"}';
        } else {
             echo '{"message":"Failed update user info"}';
    } catch (Exception $e) {
        echo '{"error":{"text":'. 'Unable to get the web service. ' . $e->getMessage() .'}}';

$app->delete('/api/users/:id', function($id) {
	$user = User::find($id);
    if($user->delete()) {
        echo '{"message":"Successfully delete user"}';
    } else {
         echo '{"message":"Failed to delete user"}';

OK, here the final touch! 2 things to do, one the index.php and the other one is .htaccess. Here the index.php. Please take note, we require the header("Access-Control-Allow-Origin: *");, to ensured that we can access this Restful API from other domains. There might be security issues. Comments are welcomed.

try {
	header("Access-Control-Allow-Origin: *");
	require 'vendor/autoload.php';
	require 'config/database.php';
	require 'config/initialize.php';
} catch (Exception $e) {
	echo '{"error":{"text":'. 'Unable to start up the web service. ' . $e->getMessage() .'}}';

The .htaccess.

RewriteEngine On

# Some hosts may require you to use the `RewriteBase` directive.
# If you need to use the `RewriteBase` directive, it should be the
# absolute physical path to the directory that contains this htaccess file.
# RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

Source code available at: Web Service(Restful API)

I Have 3 demo available:

  1. Web Service App
  2. Web Service Demo
  3. Web Service Mobile Demo