Laravel 5: Repositories

Laravel 5: Repositories


Repositories help to make your app future-proof and testable, by loosely coupling your controllers to database logic, e.g. Eloquent, so you can switch your data storage anytime without affecting rest of your app.

A few words to start with …

When you build your application, you choose how you handle your data.
Most likely you are going to choose MySQL and manage it via Query builder, or Eloquent ORM.
It is extremely unlikely, you’d ever change this.
But what, if you’d choose to switch to NoSQL Mongo, or some other file based storage?
You’d be in a world of hurt … and a big time.
Unless, you made a right choice to begin with and chose to use Interface powered Repositories.
If you did, you can start celebrating the right choice, as switch will be easy.

I will do step by step, how to get repository going and how to use loose coupling between data managing solution, e.g. Eloquent and place, where you use fetched data e.g. Controller.
step 1: create repository folder

If you do not have it yet, lets create Repositories folder (directory) inside of /app.
Our Repository folder will hold all our repositories.
If you design some huge app, you may consider sub-folders inside, so you will not end up with 50 or more repository class files one under another.

step 2: create repository class

Now, lets create our repository class.
Since we do not have any Artisan shortcut, we have to do it by hand.
Lets select some naming convention for our repositories and try to stick to it throughout our whole app.
Lets call our repo: DbUserRepository.
So, all my repositories will have Db prefix.

Here is my class – it will be still adjusted below in step 3:

I have 2 simple methods:

  • get all users
  • get selected user by id
step 3: create Interface for Repository

I could call this Repository directly in Controller, but then the whole repository concept would be manhandled.

Basically, we move database logic out of Controller to allow for a loose coupling, so later on, if for any reason we want to change database storage engine, e.g. to NoSQL Mongo, we can do this without major app rework.

And for that loose coupling we need interface.

There is nothing to it.

create Interfaces directory

If you do not have Interface folder yet, I suggest creating it in /app directory.
Since Interface is a sort of contract, you could call this folder Contracts as well.

create interface class

Lets create UserRepositoryInterface inside of Interfaces folder.

Interface not only connects to proper repository, but being a contract, it also forces us to include all listed methods in any new implementation we create for a different database engine, e.g. for Mongo – if we decide to switch to it.

But we are not done yet.
Our DbUserRepository does not know yet, that it is linked to our UserRepositoryInterface.

All we have to do is to implement it, like this:

Above line comes from repository.
Full code of repository is a bit above on this page.

step 4: binding interface to repository

So, we have our DbUserRepository implementing UserRepositoryInterface, but Laravel Container – place responsible for injecting dependencies – still is unaware of connection between DbUserRepository and UserRepositoryInterface.
Lets change that.

Best place to talk to Laravel’s Container is through some ServiceProvider.
We could create a dedicated one, but I think that existing AppServiceProvider is just the right place.

We will bind Interface to Repository in method register():

Now, Laravel knows all it needs to and we can use repository to fetch data in Controller.

step 5: use repository in controller

Lets say I will use HomeController accessible via domain.com/home route:

And this is my HomeController:

I am asking for a use with id: 1, and here what I get:

So, as you see, all works as intended

Summary

Now, if I want to switch to a new data engine, all I have to do is to write another repository and change binding in ServiceProvider to that new repository.
Everything else in my app will work without a hiccup.

All files from steps above in full
DbUserRepository

UserRepositoryInterface

AppServiceProvider

HomeController

We are done …

 

Laravel 5: Errors & Logging

Laravel 5: Errors & Logging


Even best coded app will get in trouble and generate errors.
Your app will have to be able to recover from errors and be able to tell you about them, so you can (possibly) fix them.

Configuration
Error Detail

On error page show just message (se to false), or message and all that crap that makes you scratch your head ho to read it, but which sometimes can be helpful (set to true).

Controlled by APP_DEBUG
Defined in file: config/app.php
Setup in file: .env

Values:

  • true (development)
  • false (live/production)
Log Storage

Tells Laravel how and where to store your error logs.

Controlled by APP_LOG
Defined in file: config/app.php
Setup in file: .env
values: “single“, “daily“, “syslog“, “errorlog

single:
All errors single file: storage\logs\laravel.log

daily:
Errors for each day in a single, dated file: storage\logs\laravel-2017-02-06.log (example).
By default, only 5 files are stored with sixth (newest) removing oldest.
It can be changed by setting log_max_files directive in config/app.php.
It is best to define constant in app.php:

… and set it in .env file

syslog:
This is for really big apps having a separate log server called syslog – read more here.

errorlog:
This is main Apache error log.
Look for it here: \apache\logs
If in file: apache\conf\extra\httpd-vhosts.conf you set different location for error log via directive ErrorLog, e.g.
ErrorLog “u:/www/_logs/la5-error.log”, as I on my XAMPP, then look for errors there.

Log Severity Levels

Here are security levels from least to most severe:

  • debug,
  • info,
  • notice,
  • warning,
  • error,
  • critical,
  • alert,
  • emergency

If you select any of these levels, it will store its own error messages and all more severe ones.
Example: ‘alert‘ will store alert level messages and emergency level ones.

By default, Laravel comes with level ‘debug‘, which stores all messages, which is good for development.

Live/production, should have this set to ‘error‘.

The Exception Handler – Custom Error Pages
Custom, ‘place anywhere’ exception

The HttpException instance raised by the abort function will be passed to the view as an $exception variable.

Custom HTTP Error Pages

To make a custom exception page (error page), follow this procedure.
e.g. you want to make exception for 404 HTTP status code ‘not found‘, you create a blade template in:

Now just make all needed error page using HTTP status codes.
You can find them here.

How to Log Message Using Laravel
Logging info

You may write information to log file (as configured above) using the Log facade, e.g.:

Logging other (all) messages

Log level methods are as follows:

  • Log::emergency($message);
  • Log::alert($message);
  • Log::critical($message);
  • Log::error($message);
  • Log::warning($message);
  • Log::notice($message);
  • Log::info($message);
  • Log::debug($message);
Contextual Log Information

Second argument in form of an array will be added to log message:

 

Laravel 5: Contracts

Contracts


Laravel’s Contracts are a set of interfaces that define the core services provided by the framework.

Contract (or Interface) is nothing more, or less than a pointer to concrete class.
It is useful, if ever in the future you’d want to use different concrete class.
All you have to do then, is to point contract to this other class.
No fuss, simple, fast – something like this.

contract

So, as you see, this is all about decoupling, but not decoupling understood as making your code framework independent.

More: read here.

 

Laravel 5: Facades

Facades


Facades provide a “static” interface to classes that are available in the application’s service container.

If you read above carefully, you will see that Laravel Facade is NOT a static way of calling methods.
It is a static accessor that builds a fully fledged and testable object for you.

So, instead of going via all this hurdles to build an object for yourself, Laravel Facade:

  • instantiating object for us
  • passes dependencies
  • and all works otherwise, you’d need to do yourself.

 

All available Facades are listed in: \config\app.php – then scroll down to: ‘aliases’

In order to use facades, you need too import facade accessor class, e.g.:

to use:

BTW:
Laravel facades are not static, untestable functions!
See accessor class for clues.


example 1:

When you do this using Facade:

… you actually sending Laravel a command to resolve object with keyword ‘form’ pointing to it and then call open method:

If you are puzzled about that: keywords mentioned above, see: here to find out more about Service Container binding.

 


example 2:

Let us see how it works on real life example – ‘Laravel Collective‘ – a component that used to be a part of Laravel, but it is not anymore and is maintained by community.

Laravel Collective has to be installed separately and once installed, it can be found here:

Once inside find this file and open it:

Inside you will find this code:

Now, we need to find this keyword. Best place to look is Service Provider.

Right in Laravel Collective directory, we can find this provider:

And inside of this file we have our keyword ‘form’:

As you can see above, our keyword bounds to this class:

… and if you look inside of this class, you will see all the methods you can chain to, e.g.:

And above frame can be used to build your own functionality and to define facades for them

 


What you find in example 2 applies to all other Facades, which can be found here:

… and in many other places in framework.
To find them all, just search for this phrase:

“protected static function getFacadeAccessor()”

 


Some more info

There are more ways to access data, besides facade, are mentioned here.
Also look at helper methods described on over 100 pages on this site.

PHP facade pattern vs. Laravel Facades in a nutshell:

  • Laravel Facade: clever way to simplify coders life (via auto-construction of objects behind scenes) without sacrificing testability etc.
    In a sense, this may have a bit to do with factory pattern, which also is primarily used to build object
  • PHP Facade Pattern: attaching switchboard-like class on top of other, worker classes, allowing to change/adjust worker classes without too much hassle to entire system – more info about facade patternread this.

 

Laravel 5: Service Provider

Service Provider


Service providers are the central place of all Laravel application bootstrapping.
Your own application, as well as all of Laravel’s core services are bootstrapped via service providers.

OK, let’s talk plain English.

Laravel needs to know, what it has at its disposal and all that info is being channeled (bootstrapped) to it via Service Provider.

Here what we can place in Service Provider:
  • service container bindings,
  • event listeners,
  • middleware,
  • routes
How binding is done was explained (as far as simple binding is concerned) here.
Service provider can be generated using Artisan CLI, like this:

Generated provider file will be placed in directory:

Newly generated Service Provider must be registered.
You can do this in:

Just add it to array of providers – look for this and follow way other providers were registered:

Deferred providers.

Sometimes you may want to have providers loaded lazy (when needed only).

For that use deferred providers.

You do it same way as other providers, with two differences:

you are setting protected property and set its value to true:

then you are creating property provides() and pacing reference to deferred provider right there:

That is all.
MyProviderKeyword provider will load on-demand only.

This approach may speed up your app.

 


More about providers in Laravel docs.

 

Laravel 5: Redis – Setup and Stuff

Redis: setup and stuff


Redis is an open source, advanced key-value store.
It can contain strings, hashes, lists, sets, and sorted sets.
It can be used in Laravel in: queues, cache, broadcasting.
Redis can also be used as a fast, persistent database – great for horizontal projects (many servers), as it can easily replicate on these servers (nodes).

Redis for Windows

Most likely you will need it for local development, as I do.

I develop using XAMPP with PHP 7 on Windows 8.1, so I need Redis for my win-dev environment.
When I am done developing, I will push it onto Linux box, but it does not change the fact, that I need something for Windows now.

Here where Redis for Windows can be found.

NOTE:
For development do not use password, or anything you do using console is going to drive you bananas, as it will scream for that password.

 


Redis for Linux

To get Redis for Linux:

  1. sudo apt-get install redis-tools
  2. sudo apt-get install redis-server
  3. go inside of installation dir and you can use redis-cli command

You can also see here.

 


Using Redis CLI

On Windows, Redis is located int:

So, to access it on console, you have to cd to Redis directory first:

… and then use:

It works same on Linux, just you have to cd to different directory.

Available Redis commands are here.

 


Using redis with Laravel

You have two choices:

  • Predis and
  • PhpRedis

Some links: PhpRedis  (see also here) and Predis.
Both scripts provide the same access wrapper to Redis server.

So, you need to have Redis installed first!

PhpRedis is written directly in C, while Predis is written in PHP, so in some cases Phpredis is faster.

How much faster?
Well Aleksey Korzun took his time to run some benchmarks and here are the results.

 


Redis version

To check Redis version, use this command from within Redis directory in console:

 


To check, if Redis is up, you may use ping

Redis is going to answer with: pong.

 


Setting password

Password can be set in redis.conf file.
In Windows, this file is called: redis.windows.conf.
Password is set around line#443.
Just uncomment this line and add password to it:

Note:
In Windows, any changes made in redis.windows.conf will take effect only after computer is restarted.
So, if you come across same kind of a problem, you need to apply password using console, like this:
Make your password very complex, to avoid being hacked.
Something like: rTY6UNMeyAkjL23YTX*qXG8X1p1u#RDd4v85rQNW@82FM4q should do the trick.
Important:
If out of the blue, you get an error: “failed: NOAUTH Authentication required” and you are on Windows (not tested on Linux/Unix), it may mean that you attempted to set password (requirepass) in file redis.windows.conf (and failed). In such case, after next computer restart, you can get this unexpected error.
Actually, that is why you failed to apply your password in first place, because computer restart is required to get this going.
Solution:
Just comment that out and restart Windows again, or pass your new password, whenever you interact with Redis in your app.
Frankly, when developing, it is good to develop with password in place, as later, it can be tedious to put it in all the right places. Unless you use .env based Redis constant password. Just I am not sure, if you can use it in *.js files, like node scripts. Haven’t tested that yet. Drop me a line, if you did.

 


Protect redis by loopback
Loopback and password
If you protect Redis by loopback, you are taking it effectively from direct access from web.
So, in such case, there is no need for using password.
As long as connecting client is secure and connection is secure (SSL) – in case it is not localhost – Redis is protected.

Protect redis by loopback interface – uncomment (if commented) in redis.conf:

If your redis is not on same server (so 127.0.0.1 cannot be used), explicitly state allowed client:

You can write as many interfaces (IPs) as you need, by listing them with space between IPs, as shown above.

If you are explicitly binding localhost, you may do this including IPV6 notation:

This part:

is IPV 6 equivalent of:

… in IPV4 format.

 


Order of commands in CLI (console) are important!

This will NOT work:

This WILL work:

As you can see, password has to go first and then rest of commands.

If server has no password set, anything passed via ‘-a’ is being disregarded.

 


How to start Redis server.

On Windows, when you install downloaded MSI file (installer), it will start Windows equivalent of daemon process.
Deamon process in Linux is a background, long running process.

But, if for any reason, you stop such process, e.g. by using console command:

… Windows ‘daemon’ is ‘exorcised’ 😉 and thus dead.

To get Redis again, you can:

use console

From within redis folder run command:

note:
Windows do not run daemons, so console will be disabled by process and process will die, when console is closed.

setup Windows task

Start it as Windows task – see here, how it is done.
Example is about running pseudo-chron job based on Windows native tasking system, but this task can be setup in the same way.

One difference:
in ‘New Action’ tab, do not add ‘New Arguments’.