Laravel Artisan Sample
Laravel Artisan Sample
Laravel Artisan Sample
Johnathon Koster
This book is for sale at http://leanpub.com/laravelartisan
This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing
process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools
and many iterations to get reader feedback, pivot until you have the right book and build
traction once you do.
2. Illuminate\Translation\FileLoader . . . . . . . . . . . . . . . . . . . . . . . . 16
2.1 FileLoader Public API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.1.1 load($locale, $group, $namespace = null) . . . . . . . . . . . . 17
2.1.2 addNamespace($namespace, $hint) . . . . . . . . . . . . . . . . . . 17
2.2 Translation Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
8. Writing Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
8.1 Command Input and Command Signatures . . . . . . . . . . . . . . . . . . . 50
8.1.1 Input Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
8.1.2 Input Parameter Default Values . . . . . . . . . . . . . . . . . . . . . . . 51
8.1.3 Adding Descriptions to Command Parameters . . . . . . . . . . . . . . . 52
8.1.4 Command Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
8.1.5 Command Option Default Values . . . . . . . . . . . . . . . . . . . . . . 53
8.1.6 Adding Descriptions to Command Options . . . . . . . . . . . . . . . . . 54
8.1.7 Command Option Shortcuts . . . . . . . . . . . . . . . . . . . . . . . . . 54
8.1.8 Using Command Options as Flags . . . . . . . . . . . . . . . . . . . . . . 55
8.1.9 Array Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
8.1.10 Array Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
8.1.11 Making Input Arguments Optional . . . . . . . . . . . . . . . . . . . . . 58
8.1.12 Command Input Syntax Reference . . . . . . . . . . . . . . . . . . . . . 59
8.1.13 Command Signature Alternatives . . . . . . . . . . . . . . . . . . . . . . 59
8.2 Retrieving User Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
8.2.1 argument($key = null) . . . . . . . . . . . . . . . . . . . . . . . . . 68
8.2.2 hasArgument($name) . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
8.2.3 option($key = null) . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
8.2.4 hasOption($name) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
8.3 Default Command Options (Global Command Options) . . . . . . . . . . . . 72
8.3.1 Application Version and Command Environments . . . . . . . . . . . . . 73
8.3.2 Command Verbosity Levels and Output Control . . . . . . . . . . . . . . 74
8.4 Prompting for User Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
8.4.1 Prompting for User Input . . . . . . . . . . . . . . . . . . . . . . . . . . 78
8.4.2 Suggesting Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
8.4.3 Prompting for Sensitive User Input . . . . . . . . . . . . . . . . . . . . . 84
8.4.4 Providing Choices for User Input . . . . . . . . . . . . . . . . . . . . . . 85
8.4.5 The --no-interaction Default Option . . . . . . . . . . . . . . . . . . 90
CONTENTS
9. Command Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
9.1 General Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
9.2 Outputting Lines with Colors . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
9.3 Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
9.4 Progress Bars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
9.5 Additional Output Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
9.5.1 block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
9.5.2 title . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
9.5.3 section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
9.5.4 listing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
9.5.5 writeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
9.5.6 write . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
9.5.7 newLine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
9.5.8 text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
9.5.9 comment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
9.5.10 success . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
9.5.11 error and warning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
9.5.12 note . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
9.5.13 caution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Why?
When this project (the collection of notes, and eventually this book) started back in the Laravel
4.x days, the documentation was not as great as it is today (a lot of hard work and effort has gone
into the recent Laravel documentation by many talented and dedicated people). The following
collection of notes were created as a sort of supplemental documentation to reinforce ideas and
concepts learned about the framework while developing projects and ideas.
i
About the Book ii
This icon will be used when defining a term. This icon is not used often, and usually
only applied when there may be confusion about or term, or when sufficient ambiguity
already exists around a term.
This icon is used to present the thoughts or opinions of the author(s) and acts as an
invitation for conversation. These sections also feature a title styling that is more subtle.
Look for this icon in the text to learn about any appendices that may additional
reference material for a given section.
This icon indicates information that is important or the cause of general errors.
This icon is used to point out or explain the cause of specific errors or problems that
may arise during development.
This icon is used to point out additional information that might be useful in the context
of a given chapter, but is not required.
After these sections have been written I intend to write the “beginning” of the book. This will
cover an introduction to Laravel, Homestead, Valet, etc.
²https://leanpub.com/
³http://brackets.io/
⁴https://github.com/JohnathonKoster/brackets-spellcheck
About the Book iv
Here be dragons!
.~))>>
.~)>>
.~))))>>>
.~))>> ___
.~))>>)))>> .-~))>>
.~)))))>> .-~))>>)>
.~)))>>))))>> .-~)>>)>
) .~))>>))))>> .-~)))))>>)>
( )@@*) //)>)))))) .-~))))>>)>
).@(@@ //))>>))) .-~))>>)))))>>)>
(( @.@). //))))) .-~)>>)))))>>)>
)) )@@*.@@ ) //)>))) //))))))>>))))>>)>
(( ((@@@.@@ |/))))) //)))))>>)))>>)>
)) @@*. )@@ ) (\_(\-\b |))>)) //)))>>)))))))>>)>
(( @@@(.@(@ . _/`-` ~|b |>))) //)>>)))))))>>)>
)* @@@ )@* (@) (@) /\b|))) //))))))>>))))>>
(( @. )@( @ . _/ / / \b)) //))>>)))))>>>_._
)@@ (@@*)@@. (6///6)- / ^ \b)//))))))>>)))>> ~~-.
( @jgs@@. @@@.*@_ VvvvvV// ^ \b/)>>))))>> _. `bb
((@@ @@@*.(@@ . - | o |' \ ( ^ \b)))>> .' b`,
((@@).*@@ )@ ) \^^^/ (( ^ ~)_ \ / b `,
(@@. (@@ ). `-' ((( ^ `\ \ \ \ \| b `.
(*.@* / (((( \| | | \ . b `.
/ / ((((( \ \ / _.-~\ Y, b ;
/ / / (((((( \ \.-~ _.`" _.-~`, b ;
/ / `(((((() ) (((((~ `, b ;
_/ _/ `"""/ /' ; b ;
_.-~_.-~ / /' _.'~bb _.'
((((~~ / /' _.'~bb.--~
(((( __.-~bb.-~
.' b .~~
:bb ,'
~~~~
Laravel: The Basics
“I learned very early the difference between knowing the name of something and knowing
something.”
– Richard P. Feynman (1918 - 1988), Theoretical Physicist
1. Introduction
In this chapter we will begin the process of learning about the Laravel framework, and how it
operates on a higher level before diving into various framework features in detail. So what exactly
is Laravel? Doing a quick search for “What is Laravel” yields results that repeat some variation of
the phrase “a framework that follows the model-view-controller (MVC) architectural pattern”.
While this is true, it assumes that the reader has a rather large knowledge base of software
design; this may include things such as the design, organization and architecture of web software
systems. While this knowledge is definitely a benefit when approaching frameworks like Laravel,
it is best to attempt to describe things as simply as possible when introducing any technology.
And more often than not, it can be found that the reader does in fact know more than they
thought, it’s just that they could not apply a specific name to a thing. To this end, Laravel can be
described as a well thought out, opinionated collection of individual pieces of software that all
elegantly work together to help make the process of building web applications easier.
To help achieve it’s goal of making web development easier and more elegant, Laravel often
exposes many of its own, simpler APIs and systems to accomplish common web development
tasks. Most of these APIs are designed to be easy to read and understandable, even if the naming
of functions and methods sacrifice brevity. Under the guidance of this philosophy, Laravel often
provides a very elegant method syntax. For example, the following might be used to retrieve all
the users with an active account from some database system (the specific details on implementing
such a code example will follow in later chapters):
2
Introduction 3
1 <?php
2
3 use App\User;
4
5 // Retrieve all users with an active status of `true`.
6 $user = User::where('active', '=', true);
The style of syntax used in the previous example can be found throughout many of the
consumable framework APIs (here consumable framework API is referring to any framework
API that is intended to be used by developers). The system used in that code example is the
Eloquent object-relational mapping (ORM) system, a simple ActiveRecord implementation for
interacting with database systems, or other data storage systems. It is just one of the many default
systems that Laravel provides.
The following sections briefly highlight some of the offerings of the Laravel framework:
Configuration Systems
One thing that becomes quickly apparent when working with the Laravel framework
is how easily customizable it is; one of the major features for accomplishing this is the
configuration systems that are available as part of the core system. Laravel provides a sim-
ple, streamlined API for accessing and modifying configuration values throughout your
application. This configuration system also supports multiple application environments.
Routing
Routes are, fundamentally, a way to provide controlled and explicit access to your
application; routes map a URI to some action within your application. Laravel provides
a very powerful routing system that is capable of handling complex database situations,
URI grouping and ways to easily create REST APIs, amongst many other powerful features.
HTTP Abstractions
Laravel, building on top of the Symfony framework’s battle-tested feature-set, provides
convenient APIs for accessing and managing cookie, session and request data.
While the previous list of features is impressive in its own right, it is only the beginning of what
Laravel offers developers to create elegant and feature-rich web applications. The remaining
sections in this chapter will cover topics that are helpful when learning the Laravel framework,
such as namespaces, autoloading, the Composer autoloader as well as other various topics.
If you are comfortable with the topics presented in each of these sections, feel free to skip them.
On the other hand, if any of the subjects presented prove difficult, it may be beneficial to learn
a little more about each of the subjects before embarking on the journey of learning the Laravel
framework in detail.
This book is an attempt to cover all major framework features in detail. Throughout the journey
there will be many different ideas introduced, new terminology used and the occasional rabbit
trail will be explored. Each section of the book has been designed to stand apart on its own,
separate from the others, but great efforts have been made to ensure the continuous flow of
thought throughout the entire work.
oriented programming (OOP) language. Many of the features that Laravel provides are often
abstractions built on top of libraries and features that are available in the core PHP framework
(here framework is referring to PHP’s extensive function library as well as PHP’s Standard PHP
Library (SPL) offerings).
While not a file system management command, the man command is one of the most useful
commands to know when working with Linux-based operating systems. This command will
display the help information for other commands, which can be supplied as an argument to the
first parameter:
The cd (change directory) command is what is used to actually move around Linux-based
operating systems. It is the command that you use to essentially tell the operating system where
to go.
For example, the following could be used to change the current directory to a Homestead
directory:
¹https://leanpub.com/serversforhackers
²https://laracasts.simplecast.fm/
³https://laracasts.simplecast.fm/38
Introduction 6
The ls command is used to list the contents of a directory. The following examples demonstrate
how to use the ls command to view directory contents:
After the above command has been issued, depending on the exact directory structure, the
following output might appear (another thing to keep in mind is that most commands will not
return any output if they were executed successfully):
Additional information can be retrieved about the file system by passing in options. The l option
can be used to show extra information about each file (or directory), such as the file mode,
number of links, owner name, group name, etc (the full list of what is displayed can be learned
by using the man command):
1 John:Homestead john$ ls -l
2 total 72
3 -rw-r--r-- 1 john staff 1077 Mar 20 20:11 LICENSE.txt
4 -rw-r--r-- 1 john staff 921 Mar 20 20:11 Vagrantfile
5 -rw-r--r-- 1 john staff 603 Mar 20 20:11 composer.json
6 -rw-r--r-- 1 john staff 6245 Mar 20 20:11 composer.lock
7 -rwxr-xr-x 1 john staff 317 Mar 20 20:11 homestead
8 -rw-r--r-- 1 john staff 311 Mar 20 20:11 init.bat
9 -rw-r--r-- 1 john staff 270 Mar 20 20:11 init.sh
10 -rw-r--r-- 1 john staff 151 Mar 20 20:11 readme.md
11 drwxr-xr-x 14 john staff 476 Mar 20 20:11 scripts
12 drwxr-xr-x 4 john staff 136 Mar 20 20:11 src
Options can be combined, just like when calling Artisan commands. The a option can be added
to show hidden files (or dot files):
Introduction 7
The mkdir command is used to create (or make) directories on the file system. It also has a very
useful p option that will create directories recursively. The following examples demonstrate its
usage:
Typically, in my experience, the command that is most often called after the mkdir command is
the cd command (usually combined using the && boolean operator):
This will create a new directory and then change into it. This is manageable for short directory
names, but can quickly become inconvenient when creating larger directory structures. We can
use the $_ bash parameter, which will return the arguments supplied to the previous command
to make this easier:
The touch command can be used to create a new file, if it does not exist. If a file does exist, it
will update the files modification and access times.
The rm (or unlink command, if you prefer longer command names) is used to remove file entries
from a directory (there is also rmdir command that is used specifically to remove directories,
but the rm command can do both). The following examples demonstrate the usage of the rm
command:
1 # Remove a file
2 rm filename.txt
3
4 # Remove a directory recursively
5 rm -r directory/path
A PHP developer who has any experience interaction with the file system within their
applications will notice that a lot of PHP’s functions are named similarly to the command names
presented in this section, and that they do most of the same things. This is not an accident, and
this pattern can be seen throughout many of the functions present in PHP’s framework. A little
knowledge of Linux-based operating systems will go a long way when learning PHP in general,
not just when working with Laravel.
Introduction 9
1.1.3 Composer
Composer⁴ is a dependency manager for PHP. It allows for the seamless reuse of existing,
primarily open-source, software packages. Most of these software packages are hosted on services
like GitHub⁵. Composer is primarily used to use the dependencies (things like libraries or
frameworks) that any particular project requires (this is in contrast to package managers such as
PEAR, which installs packages on a system-wide basis).
At the end of the day, Composer just makes it easier to use various software frameworks and
libraries inside your project without too much thinking and tinkering involved. Take some time
to read through the documentation located at https://getcomposer.org/doc/⁶. It is well written,
and includes instructions on how to install it many different platforms. The rest of the book will
assume a working installation of Composer as well as some basic knowledge Composer.
• src/Illuminate/Support/Manager.php
• src/Illuminate/Queue/Capsule/Manager.php
• src/Illuminate/Database/Capsule/Manager.php
Each of these files are stored within the src/ directory, neatly within their own structured
subdirectory. If we were to open the src/Illuminate/Support/Manager.php file, as an
example, we would see the following code at the beginning of the file:
1 <?php
2
3 namespace Illuminate\Support;
4
5 use Closure;
6 use InvalidArgumentException;
7
8 abstract class Manager
9 {
10 /**
11 * The application instance.
12 *
13 * @var \Illuminate\Foundation\Application
⁴https://getcomposer.org/
⁵https://github.com/
⁶https://getcomposer.org/doc/
Introduction 10
14 */
15 protected $app;
16 /**
17 * The registered custom driver creators.
18 *
19 * @var array
20 */
21 protected $customCreators = [];
22
23 // ...
24
25 }
seem similar to using PHP’s require or import functions, but there are some additional features
that make the use operator very powerful (as well as being understood by autoloading systems).
One of the most powerful features of namespaces is the ability to alias imported class, function or
namespaces. This is useful when importing classes, functions or namespaces whose names might
conflict with the current namespace or entity name (here entity will refer to the class, function or
namespace). There will be times when we are required to import an entity with the same name
as the class or interface that exists in the current file (there are only so many good names for
classes and interfaces after all). While this may not seem like something that would happen very
often, it comes up fairly often, especially when coding to an interface (as most of the Laravel
core does) or when utilizing code from third parties (such as when adding project dependencies
using dependency manager tools, such as Composer). To get around these naming conflicts, PHP
allows us to alias the classes, functions and interfaces we are importing; i.e, we have the ability
to rename classes, functions and interfaces to whatever we want without modifying the source
code of those things.
The following examples demonstrate the different aliasing features and scenarios:
1 <?php
2
3 namespace App;
4
5 // Import the `Auth` facade.
6 use Illuminate\Support\Facades\Auth;
7
8 // Import the `Auth` facade; give it an alias.
9 use Illuminate\Support\Facades\Auth as AuthFacade;
10
11 // Import a global class (from the global or root namespace).
12 use Closure;
13
14 // Import a function (example only).
15 use function App\Support\functionName;
16
17 // Alias a function.
18 use function App\Support\functionName as betterFunctionName;
19
20 // Import a constant (declared using the const keyword).
21 use const App\Support\someConstant;
1.1.5 Traits
PHP is an object-oriented language, and as such, it supports the concept of inheritance.
Inheritance allows us developers to design abstract or base classes that can be other objects
can inherit properties and methods from. One of the most widely used base classes from the
Laravel framework is the base Eloquent model (Illuminate\Database\Eloquent\Model).
Using inheritance, we gain the ability to reuse many, or all, of the features provided by the base
(referred to as a parent or superclass) in our own classes (referred to as a child or subclass); the
main goal of inheritance is to provide a mechanism for code reuse. However, many languages,
including PHP, do not allow any given subclass to inherit from more than one parent class; there
are many good reasons for this, many of which are out of scope for this book. The paper CZ:
Multimethods and Multiple Inheritance Without Diamonds⁸ by Donna Malayeri and Jonathan
Aldrich provides an excellent overview of the problems associated with multiple inheritance.
However, there are times when it is beneficial to reuse code without inheriting from a base class;
in PHP the mechanism to accomplish this are Traits⁹.
Traits are functionally a language assisted code copy and paste feature, with benefits. Traits are
similar to classes, in that they can define methods and properties, but they cannot be instantiated
on their own; they are defined with the trait keyword rather than the class keyword. A great
way to mentally think about the difference is that classes define objects while traits add new
abilities to that class. Common use cases for traits are to provide a common implementation
of a given interface (again, without the need for inheritance), or even to “mark” a given class
as having some extra ability to treat it differently (this could include things such as marking a
class as Queueable or Serializable, for instance); Laravel provides many helper utilities for
interacting and working with traits. Classes that use traits are often referred to as the exhibitor
class, a class that exhibits some property or ability that the trait provides.
The following is an example trait from the Laravel code-base:
1 <?php
2
3 namespace Illuminate\Notifications;
4
5 trait Notifiable
6 {
7 use HasDatabaseNotifications, RoutesNotifications;
8 }
Examining the code, we see that on line three we have the namespace declaration (traits can also
be namespaced), followed by the trait definition on line five. On line seven is where things get
interesting since we are reusing the use operator in a different context. When the use operator is
used within a class, PHP interprets this as referencing a trait. This example also shows that traits
can also reference other traits (traits use other traits, rather than extend them; traits have no
concept of inheritance). The following is the code for the HasDatabaseNotifications (which
is referenced on line seven) trait:
⁸http://www.cs.cmu.edu/~donna/public/malayeri.TR09-153.pdf
⁹http://php.net/manual/en/language.oop5.traits.php
Introduction 13
1 <?php
2
3 namespace Illuminate\Notifications;
4
5 trait HasDatabaseNotifications
6 {
7 /**
8 * Get the entity's notifications.
9 */
10 public function notifications()
11 {
12 return $this->morphMany(DatabaseNotification::class, 'notifiable')
13 ->orderBy('created_at', 'desc');
14 }
15 /**
16 * Get the entity's unread notifications.
17 */
18 public function unreadNotifications()
19 {
20 return $this->morphMany(DatabaseNotification::class, 'notifiable')
21 ->whereNull('read_at')
22 ->orderBy('created_at', 'desc');
23 }
24 }
Here we can see a trait that is defining its own methods. When a class uses this trait, it will
also gain access to all the methods and properties defined in this class. Within the method
bodies, we can see that the trait is referencing $this as if it were a class. This is because
when the code methods and properties within a trait are evaluated and executed, they will be
doing so within the context of the exhibitor class. On lines 12 and 21, we can see that the trait
is making a call to a morphMany method that it does not define itself. This method must be
supplied be either another trait, or the exhibitor class itself. The take away here is that traits
can be written with the assumption of a particular type of exhibitor class (in the case of the
HasDatabaseNotifications trait, the intended exhibitor class would be any instance of the
Illuminate\Database\Eloquent\Model class).
While PHP does not allow multiple inheritance it does allow for classes to use more than one
trait. Because of this, there can be times when multiple traits are used that define methods with
the same name. When this occurs, a fatal error is generated because PHP cannot decide which
method should be used (in essence, there is some ambiguity that cannot be explicitly resolved).
To overcome this, we can indicate which method implementation to use, or even use both by
aliasing a method on the trait itself.
The following examples demonstrate how to resolve method name ambiguity.
Introduction 14
1 <?php
2
3 trait FirstTrait
4 {
5
6 public function conflictingMethod()
7 {
8 return 'Hello';
9 }
10
11 }
12
13 trait SecondTrait
14 {
15
16 public function conflictingMethod()
17 {
18 return 'Goodbye';
19 }
20
21 }
22
23 class HarmoniousResolution
24 {
25 use FirstTrait, SecondTrait {
26 // Use the conflictingMethod() from FirstTrait instead
27 FirsTrait::conflictingMethod insteadof SecondTrait;
28
29 // Use the conflictingMethod() from SecondTrait instead.
30 SecondTrait::conflictingMethod insteadof FirstTrait;
31
32 // Use both of them, but one must be renamed.
33 FirstTrait::conflictingMethod as nonConflictingMethod;
34 }
35 }
In the previous example, the insteadof operator is used to indicate which which method should
take precedence. The method on the left side of the operator will be used over (or instead of) any
method with the same name that exists within the trait on the right hand side of the operator.
In some more advanced scenarios, it may be required to actually change the visibility of the
methods exhibited from a trait. This is done supplying a method visibility keyword after the as
operator:
Introduction 15
1 <?php
2
3 // ...
4
5
6 class HarmoniousResolution
7 {
8 use FirstTrait {
9 // Change the visibility of conflictingMethod to protected.
10 conflictingMethod as protected;
11
12 // Change the visibility of conflictingMethod to private.
13 conflictingMethod as private;
14
15 // Change the visibility of conflictingMethod to public.
16 conflictingMethod as public;
17 }
18 }
There is much more that can be accomplished with traits that what has been discussed here.
However, the ideas presented in this section should be enough to cover most of the scenarios and
use-cases encountered when working with the Laravel framework.
Laravel provides localization features to help retrieve strings in various languages. These features
will collectively be referred to as the “translation component” throughout the remainder of this
section. The translation component has the following sub-components:
• Illuminate\Translation\Translator
• Illuminate\Translation\FileLoader
2. Illuminate\Translation\FileLoader
The FileLoader is the class that is responsible for loading the translation files from the file
system. The language files are loaded from the /resources/lang/ directory by default. The
lang/ directory contains the en (English from the ISO 639-1¹ standard) sub-directory by default.
Each sub-directory within the lang/ directory corresponds to a particular locale.
Each locale directory may contain various PHP files returning arrays. These arrays contain a
key/value pair, indicating the key of the translation and the value of the language translation.
For example, the following is the contents of the /resources/lang/en/passwords.php file:
1 <?php
2
3 return [
4
5 /*
6 |-------------------------------------------------------------------------
7 | Password Reminder Language Lines
8 |-------------------------------------------------------------------------
9 |
10 | The following language lines are the default lines which match reasons
11 | that are given by the password broker for a password update attempt
12 | has failed, such as for an invalid token or invalid new password.
13 |
14 */
15
16 'password' => 'Passwords must be at least six characters and match the
17 confirmation.',
18 'user' => "We can't find a user with that e-mail address.",
19 'token' => 'This password reset token is invalid.',
20 'sent' => 'We have e-mailed your password reset link!',
21 'reset' => 'Your password has been reset!',
22
23 ];
The individual PHP files containing the translation lines are referred to as “groups”. So for a
fresh Laravel installation, the following groups exist:
¹http://www.loc.gov/standards/iso639-2/php/English_list.php
16
Illuminate\Translation\FileLoader 17
1 // The following function calls are assuming the 'en' locale, using
2 // the default Laravel translation groups.
3
4 // Retrieving a language value without a namespace.
5 $passwordReset = trans('passwords.reset');
6
7 // Retrieving a language value with the default namespace.
8 $passwordResetTwo = trans('*::passwords.reset');
After the above code is executed, both $passwordReset and $passwordResetTwo would
contain the same Your password has been reset! value.
Adding custom namespaces is simple. Assuming the directory /storage/lang_custom/ exists,
it could be added to the file loader like so:
1 $loader = app('translation.loader');
2 $loader->addNamespace('custom', storage_path('lang_custom'));
Assuming there was a locale directory en with the following passwords.php group file:
1 <?php
2
3 return [
4
5 'reset' => 'This is a custom reset message.',
6
7 ];
The value for reset can be retrieved from the custom namespace like so:
1 $defaultReset = trans('password.reset');
2 $customReset = trans('custom::password.reset');
After the above code is executed, the $defaultReset variable would have the value Your
password has been reset! and the value of $customReset would be This is a custom
reset message..
3. Hashing: One Way Encryption
Hashing data is a common task in software development. Hashing is similar to encryption,
with the difference that hashing is a one-way process. The goal is that the original message
cannot be retrieved from the resulting hash. Hashing is accomplished through the use of a hash
function. A hash function generally accepts some input, called a message and transforms the
message to produce a given output, a digest. Laravel, as it does with many other things, defines
a Illuminate\Contracts\Hashing\Hasher interface, which can be implemented to create
new hashing providers that Laravel can use.
Any type that implements the Hasher interface must be able to generate a hash (by imple-
menting the make($value, array $options = []) method), check that a value matches
a hashed value (by implemented the check($value, $hashedValue, array $options =
[]) method) and a hasher must be able to determine if a given hashed value needs to be rehashed
(by implementing the needsRehash($hashedValue, array $options = []) method).
Hashing Confusion
A lot of newcomers to Laravel, and programming in general, seem to be confused about
the differences between hashing and encryption. Hashing is one way; the point is that
the final result is not recoverable. Encryption, conversely, is two-way; and the final
result is reversible given enough information. Another point of confusion is where
Laravel stores the salts for password hashes in the database. In the case of newer PHP
password hashing API’s, the salt, along with any other information required to compute
the hash, is stored with the hash in the database.
Laravel internally utilizes a Hasher implementation in a few scenarios, mostly having to deal
with users and their passwords. At the time of writing, Laravel uses hashing in the following
classes/services:
Class Purpose
Illumiante\Auth Validates a user against credentials
\EloquentUserProvider that are passed into the
validateCredentials method.
Illumiante\Auth Validates a user against credentials
\DatabaseUserProvider that are passed into the
validateCredentials method.
Laravel provides one Hasher implementation right out of the box: the Illuminate\Hashing\Bcrypt
hasher, which provides bcrypt¹ password hashing, a hashing function based on the Blowfish²
cipher. The Bcrypt hasher implements all methods defined in the Hasher interface, and also
provides one extra: setRounds($rounds), which is used to set work factor for the bcrypt
¹https://en.wikipedia.org/wiki/Bcrypt
²https://en.wikipedia.org/wiki/Blowfish_(cipher)
19
Hashing: One Way Encryption 20
hashing function.
The Bcrypt hasher is also used by the bcrypt application helper function. It actually uses
the above method to resolve the Bcrypt hasher from the service container. This means that
any other service provider that modifies the hash service container entry will also affect the
bcrypt helper function. The bcrypt helper function is also used internally in the Illumi-
nate\Foundation\Auth\ResetPasswords trait; specifically, it is used in the implementation
of the resetPassword($user, $password) method.
The following sections will explain the Bcrypt hasher’s various methods.
3.1.1 setRounds($rounds)
The setRounds method is simple way to control how many rounds, or iterations the make
method will use when calculating the final hash. An argument passed to $rounds must be a
positive integer between 4 and 31 (including both 4 and 31). If an integer outside the stated
range is supplied an instance of ErrorException will be thrown. The internal default value for
$rounds is 10.
1 /**
2 * Get a new instance of Hahser from the service container.
3 *
4 * @var \Illuminate\Contracts\Hashing\Hasher $hasher
5 */
6 $hasher = app('Illuminate\Contracts\Hashing\Hasher');
7
8 // Generate hashes for integers 0 - 9
9 // using the default work factor.
10 for ($i = 0; $i < 10; $i++) {
11 echo $hasher->make($i),PHP_EOL;
12 }
1 $2y$10$jVlNmKI5Gg0j.3nER7tevuUaesWYIuwoxzghpIKfb2LvNMoTGaac6
2 $2y$10$DZzbYPf88wWo6nFW4LOAje4oJsWxZK.vg.k6vqxouXmb/6lsx045y
3 $2y$10$7CKZ0rmSOVxjvc2XG3diLOpalxjMkjcdw1.zKeqZPiSa7dD8K7GdS
4 $2y$10$qpiLO4hCLgYWmK4WJp0tTuv7klAM6RO5QrAnEqn1ULN92S.V5U4B6
5 $2y$10$no8cpUgVPiLw9rYOBknKWeiO2fC45.dzzhxE.rW8qn9ZojixXvoq.
6 $2y$10$31BmbMpivMGz1bsf5PAwTeEFhnS0GMS4GOkjNp.TWh9PZsZ0jLVWC
7 $2y$10$76T.L071J.8ewnnI3oocoukJtC8QljZiIesebdgewyMKygsl20QU2
8 $2y$10$nCE.5KTwPR8g6mrm4M9jlecoBpITCavThwRT0IZVQuMRg8qHQXaea
9 $2y$10$8uQ/0uc6wB1OQ7220wA2Ze54WqMzKTxWPQyi./bODTiBL/I7QgwgW
10 $2y$10$2ywQnQZKXAHMRqmj4iCr5O9Lr67Gv9u1BjXEiVspSRO.gWV1ROF7a
⁴http://php.net/manual/en/function.password-verify.php
Hashing: One Way Encryption 22
1 /**
2 * Get a new instance of Hahser from the service container.
3 *
4 * @var \Illuminate\Contracts\Hashing\Hasher $hasher
5 */
6 $hasher = app('Illuminate\Contracts\Hashing\Hasher');
7
8 // Generate a hash for "Ave Maria"
9 $hash = $hasher->make('Ave Maria');
10
11 // true
12 $isValid = $hasher->check('Ave Maria', $hash);
13
14 // false
15 $isValid = $hasher->check('Ave maria', $hash);
16
17 // false
18 $isValid = $hasher->check('password', $hash);
The following example will generate twenty hashes for the string Ave Maria and check the
original string against all hashes. This demonstrates that even though the hashes are different
each time a string is hashed, enough information is stored with the hash that a password can be
checked successfully;
1 /**
2 * Get a new instance of Hahser from the service container.
3 *
4 * @var \Illuminate\Contracts\Hashing\Hasher $hasher
5 */
6 $hasher = app('Illuminate\Contracts\Hashing\Hasher');
7
8 // Generate 20 hashes for "Ave Maria"
9 for ($i = 0; $i < 20; $i++) {
10 $validHashes[] = $hasher->make('Ave Maria');
11 }
12
13 // Check "Ave Maria" against all 20 differnet hashes.
14 // They should all be valid.
15 foreach ($validHashes as $hash) {
16 $isValid = $hasher->check('Ave Maria', $hash);
17
18 // Improve the readability of the output.
19 $isValid = ($isValid) ? 'true' : 'false';
20
21 echo $hash, ' valid: ', $isValid, PHP_EOL;
22 }
Hashing: One Way Encryption 23
The above code would generate something similar to the following output (the exact hashes will
change each time it is ran):
1 /**
2 * Get a new instance of Hahser from the service container.
3 *
4 * @var \Illuminate\Contracts\Hashing\Hasher $hasher
5 */
6 $hasher = app('Illuminate\Contracts\Hashing\Hasher');
7
8 // Generate a hash with fewer rounds than the default.
9 $lessRounds = $hasher->make('Ave Maria', ['rounds' => 4]);
10
11 // Generate a hash with the default number of rounds.
12 $defaultRounds = $hasher->make('Ave Maria');
Hashing: One Way Encryption 24
13
14 // Generate a hash with more rounds than the default.
15 $moreRounds = $hasher->make('Ave Maria', ['rounds' => 11]);
16
17 // All of these are valid.
18 $isValid = $hasher->check('Ave Maria', $lessRounds);
19 $isValid = $hasher->check('Ave Maria', $defaultRounds);
20 $isValid = $hasher->check('Ave Maria', $moreRounds);
21
22 // This hash needs to be rehashed because it was generated with
23 // fewer rounds than the current number of rounds (default).
24 $needsRehash = $hasher->needsRehash($lessRounds);
25
26 // This hash does not need to be rehashed because it was generate
27 // with the same number of rounds as the current number of rounds.
28 $needsRehash = $hasher->needsRehash($defaultRounds);
29
30 // The $moreRounds hash also needs to be rehashed because it has more rounds
31 // than the current number of rounds (the default number), even though it
32 // has a higher work factor.
33 $needsRehash = $hasher->needsRehash($moreRounds);
1 use Illuminate\Support\Facades\Hash;
2
3 // All of the following calls are functionally
4 // equivalent. The output will differ only
5 // because bcrypt hashes will differ.
6 $hash = Hash::make('test');
7 $hash = app('hash')->make('test');
8 $hash = app('Illuminate\Contracts\Hashing\Hasher')->make('test');
** The SHA-2 family of hashing functions have had no publicly disclosed successful
attacks against all rounds of the function. NIST is currently working on the SHA-3
family⁸ of hashing functions.
Appendix A: Available Hash Functions contains a listing of all the hash functions that
are available for use with PHP’s hash function.
The following table contains the characters from the alphabet ./0-9A-Za-z, which is used by
many of the hashing functions in PHP. It has been arranged so that the characters appear in the
order if you were to create a function to convert an integer to base64. It is also important to note
that the table includes spaces to improve readability and are not part of the alphabet.
⁶Regarding CRYPT_SHA256 and CRYPT_SHA512, a value supplied for the number of rounds that falls out of the range 1 to 999 999 999,
inclusive, will cause the supplied value to be truncated to the nearest limit.
⁷http://php.net/manual/en/function.password-hash.php
⁸http://csrc.nist.gov/groups/ST/hash/index.html
Hashing: One Way Encryption 26
Symbols . /
Numeric 0 1 2 3 4 5 6 7 8 9
Lowercase Alpha a b c d e f g h i j k l m n o p q r s t u v w
x y z
Uppercase Alpha A B C D E F G H I J K L M N O P Q R S T U V W
X Y Z
“I see no reason to believe that a creator of protoplasm or primeval matter, if such there be, has
any reason to be interested in our insignificant race in a tiny corner of the universe, and still
less in us, as still more insignificant individuals. Again, I see no reason why the belief that we
are insignificant or fortuitous should lessen our faith.”
– Rosalind Franklin (1920 - 1958), Physical Chemist, X-Ray Crystallographer
The Artisan Command Line Environment (CLI) is a terminal based application that can be used
to ease development with Laravel. Artisan ships with many commands by default as well as
exposes APIs to create your own custom commands.
Many of the commands available are commands to either generate database tables, manage
existing tables or clear various application caches. The commands are organized by command
namespaces; for example, the clear command under the view namespace would clear the
previously cached views and is written as view:clear.
4. Database Management
Commands
This section will provide a reference for the commands that are used to create and manage
database tables. Each command will be discussed in greater detail in later sections.
28
5. Cache Management Commands
This section will provide a reference for the commands that are used to generate or clear various
caches used by your application. Each command will be discussed in greater detail in later
sections.
Command Description
cache:clear Flushes the application cache.
config:cache Creates a cache file to improve configuration performance.
config:clear Removes the configuration cache file.
route:cache Create a cache file to improve router performance.
route:clear Remove the route cache file.
view:clear Clear all compiled view files.
29
6. Default Artisan Commands
The following sections will discuss each of the default Artisan commands.
30
Default Artisan Commands 31
The following examples will demonstrate the different ways to call the migrate command. The
examples are using the default create_users_table, create_password_resets_table and
create_cache_table migrations.
After the above command has executed the migrations will be ran and the migrations table will
look similar to the following:
migration batch
2014_10_12_000000_create_users_table 1
2014_10_12_100000_create_password_resets_table 1
2016_04_10_041139_create_cache_table 1
In contrast, if we had set the --step flag, each migration would have a different batch number:
would result in a table that contains value similar to the following (note the differences in the
batch values):
Default Artisan Commands 32
migration batch
2014_10_12_000000_create_users_table 1
2014_10_12_100000_create_password_resets_table 2
2016_04_10_041139_create_cache_table 3
Output similar to the following wold be displayed in the terminal (line breaks have been added
to improve readability):
1 CreateUsersTable:
2 create table `users` (
3 `id` int unsigned not null auto_increment primary key,
4 `name` varchar(255) not null,
5 `email` varchar(255) not null,
6 `password` varchar(255) not null,
7 `remember_token` varchar(100) null,
8 `created_at` timestamp null,
9 `updated_at` timestamp null
10 )
11 default character set utf8 collate utf8_unicode_ci
12
13 CreateUsersTable:
14 alter table `users` add unique `users_email_unique`(`email`)
15
16 CreatePasswordResetsTable:
17 create table `password_resets` (
18 `email` varchar(255) not null,
19 `token` varchar(255) not null,
20 `created_at` timestamp not null
21 )
22 default character set utf8 collate utf8_unicode_ci
23
24 CreatePasswordResetsTable:
25 alter table `password_resets` add index `password_resets_email_index`(`email`)
26
27 CreatePasswordResetsTable:
28 alter table `password_resets` add index `password_resets_token_index`(`token`)
29
30 CreateCacheTable:
31 create table `cache` (
32 `key` varchar(255) not null,
33 `value` text not null,
Default Artisan Commands 33
The following example sets the path to the database migrations. It uses the default migrations
path, just as an example.
The following example sets the database connection name. It uses the default connection name
as an example.
A common cause of confusion is the name of the --database option. The value
supplied for this option is really the name of the database connection, not the name
of the actual database.
The following example would force the migrations to be ran in a production environment:
The following example would run the db:seed command after the migrations have been created:
When specifying the --psr flag, the optimize command will call the composer
dump-autoload command. Without the --psr flag, the Composer command
composer dump-autoload -o will be called instead.
When using HHVM for development and testing purposes, HHVM must be at least
version 3.8.0 to use the internal development server.
”… it is shameful that there are so few women in science… In China there are many, many
women in physics. There is a misconception in America that women scientists are all dowdy
spinsters. This is the fault of men. In Chinese society, a woman is valued for what she is, and
men encourage her to accomplishments yet she remains eternally feminine.”
– Chien-Shiung Wu (1912 - 1997), Physicist
It is often very useful to create custom Artisan commands specifically for your application or
package. Custom commands are, by default, stored in the app/Console/Commands directory
(commands can be stored at any path that can be autoloaded based on the applications
composer.json settings).
The app/Console/Commands directory contains an Inspire command by default (stored in
the app/Console/Commands/Inspire.php file). This command is extremely simple and just
displays one of the following messages at random:
The Inspire command is very short and readable (as it is defined in the routes/console.php
file):
1 Artisan::command('inspire', function () {
2 $this->comment(Inspiring::quote());
3 });
Re-implementing this command as a class, as opposed to using the console.php file approach,
might look something like this (stored within the app/Console/Commands/ directory):
Default Artisan Commands 37
1 <?php
2
3 namespace App\Console\Commands;
4
5 use Illuminate\Console\Command;
6 use Illuminate\Foundation\Inspiring;
7
8 class Inspire extends Command
9 {
10 /**
11 * The name and signature of the console command.
12 *
13 * @var string
14 */
15 protected $signature = 'inspire';
16
17 /**
18 * The console command description.
19 *
20 * @var string
21 */
22 protected $description = 'Display an inspiring quote';
23
24 /**
25 * Execute the console command.
26 *
27 * @return mixed
28 */
29 public function handle()
30 {
31 $this->comment(PHP_EOL.Inspiring::quote().PHP_EOL);
32 }
33 }
It is this class-based implementation of the Inspiring command that will be used throughout
the remainder of this section.
Commands, at their most basic, contain a $signature, $description and a handle() method.
A commands signature is similar to a method or function signature in that it defines the name,
parameters and options of the command. The description is simply a helpful description of what
the command does. The handle() method implementation is the code that actually performs
the action described in the commands description. The Inspire command can be executed like
so:
After the command has executed it would display one of the random quotes listed above.
Default Artisan Commands 38
It is entirely possible that when attempting to execute the inspire command the following error
will be displayed instead of a random quote:
1 [Symfony\Component\Console\Exception\CommandNotFoundException]
2 Command "inspire" is not defined.
This error is caused when the application cannot locate a command. The most common cause
of this is that the command has not been included in the applications console commands. The
following section “The Application Console Kernel” will explain this in further detail.
7. The Console Kernel
Each application contains a console kernel. The console kernel is defined in the app/Console/K-
ernel.php (this will be referred to as the application console kernel) file. The kernel class that
exists in that file extends Laravel’s console kernel (which can be found in the vendor/lar-
avel/framework/src/Illuminate/Foundation/Console/Kernel.php file; this kernel will
be defined as the framework console kernel). From the applications point of view, the application
console kernel is responsible for specifying which custom commands should be made available
to users and when to automatically execute various commands and tasks (by using the task
scheduler).
It is important to note that while this the application and console kernels are separated into
their own sections, they are the same thing, and are only being differentiated in this book to
make explaining them easier. The “application” console kernel, located in the app/Console/K-
ernel.php file, is simply a convenient way to expose the features of the “framework” console
kernel to your application. Any features, limitations, or otherwise that are discussed in the section
“The Framework Console Kernel” can be applied to the application console kernel class.
The kernel is fairly simple by default (the vast majority of the logic is contained within the
framework’s console kernel):
1 <?php
2
3 namespace App\Console;
4
5 use Illuminate\Console\Scheduling\Schedule;
6 use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
7
8 class Kernel extends ConsoleKernel
9 {
10 /**
11 * The Artisan commands provided by your application.
12 *
13 * @var array
39
The Console Kernel 40
14 */
15 protected $commands = [
16 ];
17
18 /**
19 * Define the application's command schedule.
20 *
21 * @param \Illuminate\Console\Scheduling\Schedule $schedule
22 * @return void
23 */
24 protected function schedule(Schedule $schedule)
25 {
26
27 }
28
29 /**
30 * Register the Closure based commands for the application.
31 *
32 * @return void
33 */
34 protected function commands()
35 {
36
37 }
38
39 }
The kernel has an empty $commands array and an empty schedule() method. The $commands
property is used to specify which commands are to be loaded when the console application
(Artisan) starts. In the introduction to this chapter the following error message was discussed
briefly:
1 [Symfony\Component\Console\Exception\CommandNotFoundException]
2 Command "inspire" is not defined.
The most common cause of this error is the command that a user is attempting to run has not
been added to the $commands array. The act of adding the name of a class to the $commands
array is referred to as registering the command with the application.
To register a command with the application, simply add the fully qualified name to the command
class to the $commands array. In earlier versions of Laravel (targeting older versions of PHP), this
was done by specifying the class name as a string; however, starting with PHP version 5.5, the
::class class constant. It is also important to remember to include the class if it is located in
a different namespace (using the use PHP keyword). Application commands are, by default,
stored within the app/Console/Commands/ directory (under the App\Console\Commands
namespace). Alternatively, commands can be registered using the command shorthand syntax.
The Console Kernel 41
The commands method is automatically called by the framework and is a convenient place to
register commands using the shorthand syntax.
In the introduction to this chapter, the inspire Artisan command was used as an example.
This command is stored within the app/Console/Commands/Inspire.php file and can be
accessed by using the App\Console\Commands\Inspire class (this is the fully qualified name
of the Inspire command). The following examples demonstrate how to register the Inspire
command with the application.
The following example uses the ::class class constant, and is generally the recommended way
of referring to classes:
1 <?php
2
3 namespace App\Console;
4
5 use Illuminate\Console\Scheduling\Schedule;
6 use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
7
8 class Kernel extends ConsoleKernel
9 {
10 /**
11 * The Artisan commands provided by your application.
12 *
13 * @var array
14 */
15 protected $commands = [
16 // Remember that namespaces are relative so the
17 // `Commands\Inspire` class is resolved in
18 // relation to the current App\Console
19 // namespace to get the final class.
20 Commands\Inspire::class
21 ];
22
23
24 // Schedule method omitted.
25
26 }
The following example registers the Inspire command by supplying the fully qualified class
name as a string:
The Console Kernel 42
1 <?php
2
3 namespace App\Console;
4
5 use Illuminate\Console\Scheduling\Schedule;
6 use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
7
8 class Kernel extends ConsoleKernel
9 {
10 /**
11 * The Artisan commands provided by your application.
12 *
13 * @var array
14 */
15 protected $commands = [
16 'App\Console\Commands\Inspire'
17 ];
18
19
20 // Schedule method omitted.
21
22 }
7.2.1.1 all
The all method is used to get all of the commands that have been registered with the console
application. The commands will be returned as an array with the command name as the key and
the command’s class instance as the value. This method will bootstrap the application as well as
force the loading of deferred service providers.
The following example demonstrates one way to call this method:
The Console Kernel 43
1 <?php
2
3 use Illuminate\Contracts\Console\Kernel;
4 use Illuminate\Support\Facades\Artisan;
5
6 // Get a console instance.
7 $console = app(Kernel::class);
8
9 // Get the registered console commands.
10 $registeredCommands = $console->all();
11
12
13 // The following facade method would be equivalent
14 $registeredCommands = Artisan::all();
After the above code has executed, the $registeredCommands variable would be an ar-
ray containing all of the console commands that have been registered. #### registerCom-
mand($command)
The registerCommand method is used to register a command with the console application.
In older versions of Laravel, it was required to use this method to register any custom
commands with the console kernel. The registerCommand method expects a $command
argument to be supplied; the supplied $command must ultimately be an instance of Sym-
fony\Component\Console\Command\Command (this means that any Symfony command or
Laravel derived command would be acceptable).
The following example demonstrates the registerCommand method usage:
1 <?php
2
3 use Illuminate\Support\Facades\Artisan;
4 use Illuminate\Contracts\Console\Kernel;
5 use App\Console\Commands\Inspire;
6
7 // Get a console instance.
8 $console = app(Kernel::class);
9
10 // Register the default `Inspire`
11 // command with the application:
12 $console->registerCommand(app(Inspire::class));
13
14 // The following facade method would be equivalent:
15 Artisan::registerCommand(app(Inspire::class)):
After the above code has executed, the Inspire command would be available to the console
application. We could check to ensure it’s existence by using the all method:
The Console Kernel 44
The above coder would check to see if a particular console command has been registered with
the application. It does this by checking to see if the name of the command is included in the
array returned by the kernel’s all method. Since the all method returns an array where the
registered command names are the keys, this would be sufficient for an existence test. ####
call($command, array $parameters = [])
The call method is used to execute an Artisan command from somewhere else in your
applications code. It accepts the name of the command via an argument supplied for the
$command parameter and an array of $parameters that should be supplied to the command.
The exit code returned by the command will be the return value of the call method.
The following simple example calls the inspire (assuming it has been registered) command
from some application code:
1 <?php
2
3 use Illuminate\Contracts\Console\Kernel;
4 use Illuminate\Support\Facades\Artisan;
5
6 // Get a console instance.
7 $console = app(Kernel::class);
8
9 // Execute the inspire command:
10 $console->call('inspire');
11
12 // The following facade method would be equivalent:
13 Artisan::call('inspire');
The inspire command outputs a random inspiration quote. The outputted quote would not be
returned from the call method. The output method would be used to get the output from the
last ran Artisan command:
Assuming the last ran command was the inspire command, the $output variable would
contain one of the randomly chosen inspiration quotes.
The Console Kernel 45
The following example demonstrate how to execute Artisan commands while also supplying
arguments and options. Arguments are supplied as an array to the $parameters parameter. The
supplied array should contain the name of the argument or option as the key and the associated
value as the value for the given key.
We can take the following Artisan command that would normally be executed at the command
line:
1 <?php
2
3 use Illuminate\Contracts\Console\Kernel;
4 use Illuminate\Support\Facades\Artisan;
5
6 // Get a console instance.
7 $console = app(Kernel::class);
8
9 // Generate a new migration from within our
10 // application using the `make:migration`
11 // Artisan command.
12 $console->call('make:migration', [
13 'name' => 'create_drinks_table',
14 '--path' => 'database/setup_migrations'
15 ]);
It is important to note that the name of the argument or option must be supplied as the key if
they are used, even if they are not required when executing the command from the terminal.
The names of options must also start with the -- prefix.
7.2.1.2 output
The output method is used to retrieve the generated output from the Artisan console command
that was executed last using the call method. The following example will assume that the
inspire command has been registered.
1 <?php
2
3 use Illuminate\Contracts\Console\Kernel;
4 use Illuminate\Support\Facades\Artisan;
5
6 // Get a console instance.
7 $console = app(Kernel::class);
8
9 // Execute the inspire command:
10 $console->call('inspire');
11
12 // The following facade method would be equivalent:
13 Artisan::call('inspire');
To retrieve the output from the inspire command, we can use the output method:
After the above code has executed, the $output variable would contain the output from the
inspire command, which should be a randomly selected inspirational message.
The output method does not remove any newline characters or special characters
from the returned output. It is important to keep this mind when presenting command
output to users.
The queue method is called in exactly the same way as the call method. It accepts the
name of the command via an argument supplied for the $command parameter and an array of
$parameters that should be supplied to the command. The exit code returned by the command
will be the return value of the call method. Just like with the call method, the name of
arguments and options must be supplied as the key if they are used, even if they are not required
when executing the command from the terminal. The names of options must also start with the
-- prefix.
The major difference between the queue and call methods is that the queue method will
cause the Artisan command to be processed in the background by the configured queue workers.
The following example demonstrates how to call the queue method (the same example will be
used from the call method section; generally more intensive tasks would be queued instead of
generating migrations, such as the sending of emails):
The Console Kernel 47
1 <?php
2
3 use Illuminate\Contracts\Console\Kernel;
4 use Illuminate\Support\Facades\Artisan;
5
6 // Get a console instance.
7 $console = app(Kernel::class);
8
9 // Generate a new migration from within our
10 // application using the `make:migration`
11 // Artisan command.
12 $console->queue('make:migration', [
13 'name' => 'create_drinks_table',
14 '--path' => 'database/setup_migrations'
15 ]);
16
17 // The following facade method would be equivalent:
18 Artisan::queue('make:migration', [
19 'name' => 'create_drinks_table',
20 '--path' => 'database/setup_migrations'
21 ]);
8. Writing Commands
The first step to creating custom commands is to generate the basic structure, or scaffolding,
for the new command. This can be done by issuing the make:console Artisan command from
the terminal. The make:console command accepts the name of the new command class, as
well as accepts an optional --command option that can be used to specify the terminal command
name (for example, make:console is the terminal command name of the ConsoleMakeCommand
class).
By default, custom Artisan commands are stored in the app/Console/Commands directory,
and are namespaced under the App\Console\Commands namespace. The following command
would create a new class called CreateFileCommand and set the terminal command name to
create:file. The command scaffolding would be generated and saved to the app/Console/-
Commands/CreateFileCommand.php file.
1 <?php
2
3 namespace App\Console\Commands;
4
5 use Illuminate\Console\Command;
6
7 class CreateFileCommand extends Command
8 {
9 /**
10 * The name and signature of the console command.
11 *
12 * @var string
13 */
14 protected $signature = 'create:file';
15
16 /**
17 * The console command description.
18 *
19 * @var string
20 */
21 protected $description = 'Command description';
22
48
Writing Commands 49
23 /**
24 * Create a new command instance.
25 *
26 * @return void
27 */
28 public function __construct()
29 {
30 parent::__construct();
31 }
32
33 /**
34 * Execute the console command.
35 *
36 * @return mixed
37 */
38 public function handle()
39 {
40 //
41 }
42 }
As can be seen in the above output, each command contains a $signature and $description
property. The $signature property is used to specify what arguments and options the command
can accept (this property did not exist in Laravel versions prior to version 5.1; options and
arguments used to be defined using the getOptions and getArguments methods). The
$description property can be used to provide a description for the newly generated command.
Just because the command has been generated, does not mean it is available for use within the
Artisan console application. If the following was executed:
In order for the command to be available, it needs to be registered with the application’s console
kernel (located in the app/Console/Kernel.php file). The following can be added to the
$commands property within the Kernel.php file to register the newly generated command (only
the $commands property is being shown here):
Writing Commands 50
1 protected $commands = [
2 // ...
3 CreateFileCommand::class
4 // ...
5 ];
After saving the Kernel.php file, the create:file command should be available for use. If the
command still cannot be found, regenerating Composer’s class auto-loader file generally resolves
the issue. To do this, simply issue the following command within the application’s root directory:
At this point, a simple CreateFileCommand command exists, but does not accomplish anything.
When a command is executed from the terminal, or elsewhere, its handle method is ultimately
called. It is within the handle method that the command’s logic should be placed, even if it is
to make calls to other libraries or services.
The following handle method implementation would simply create a new file with the current
time inside a custom directory in the applications storage directory:
The above example references a directory that is not included in the application storage
directory by default. The create_file directory must be created manually before
attempting to execute the example command or else an error stating something similar
to “Unable to create file because no such file or directory exists” will be issued.
Each time the CreateFileCommand command is called, a new file will be created inside the
app/storage/create_file directory.
Parameters and options are defined in the command’s $signature property. The $signature is
a simply a string constructed from specialized syntax for defining parameters and options). The
signature must start with the terminal name of the command (such as make:model). Following
the terminal name, any number of parameters or options can be defined as long as they are
enclosed within curly braces ({ and }). When defining options within the signature, options
must still start with the -- option prefix (options can also have shortcuts, which start with the -
prefix).
Since the {firstName} and {lastName} input requirements were defined as parameters and do
not define a default value, the command requires that arguments be supplied for them. Running
the following command (without arguments):
The error message is indicating that the arguments for the firstName and lastName parameters
have not been supplied. Arguments are given to command parameters in the order they appear
in the command’s signature. Supplying input to Artisan commands is as simple as supplying the
value, separated by a space character. The following example would call the example:command
command again with John being the value for firstName and Doe as the value for lastName:
Now, when a user is executing the command, an argument for the lastName parameter is not
required. The following two command calls would are equivalent:
Any parameters that define default values are considered optional parameters.
These parameters must be defined after any required parameters. A signature
of example:command {firstName} {lastName=Doe} is valid; a signature of
example:command {lastName=Doe} {firstName} is invalid and would raise an
error stating something similar to “Cannot add a required argument after an optional
one”.
The following information would be included in the output (the “Options” section of the output
has been omitted for this section):
1 Usage:
2 example:command <firstName> [<lastName>]
3
4 Arguments:
5 firstName
6 lastName [default: "Doe"]
The help information shows us each of the arguments, their order and any default values. As
expected, a default value for lastName is shown (and is set to Doe). All of this information
comes from the command’s signature. As nice as the help information is, there are times when
extra clarification for what an input argument is used for is not clear. To work around this issue,
descriptions can be added to any input parameter or option by separating the argument or option
declaration and description using a colon : character. The argument or option declaration should
appear on the left side of the : character, and the description should appear on the right. The
revised signature might look something like this:
Writing Commands 53
The resulting information would not include the descriptions in its output:
1 Usage:
2 example:command <firstName> [<lastName>]
3
4 Arguments:
5 firstName The first name of the user.
6 lastName The last name of the user [default: "Doe"]
Notice, in the above example, that the --age option has a trailing equals (=) sign. This indicates
that the end user can supply a value to the option. The absence of the trailing equals sign indicates
that the option behaves like a switch or flag; flags can only assume a true or false value (a
flag evaluates to true if the user specifies the flag and false if they do not).
A command with the signature above could be executed like so:
The new --age option will also appear in the help information:
1 Usage:
2 example:command [options] [--] <firstName> [<lastName>]
3
4 Arguments:
5 firstName The first name of the user.
6 lastName The last name of the user [default: "Doe"]
7
8 Options:
9 --age[=AGE] [default: "0"]
The help information would now display the description for the --age option:
1 ...
2
3 Options:
4 --age[=AGE] The age of the user (optional); "0" indicates age not\
5 disclosed. [default: "0"]
6
7 ...
An options shortcut requires a slightly different prefix. Instead of using the double hyphen (--)
prefix, shortcuts use a single hyphen (-) prefix. Executing a command with the above signature
might look something like this:
Any option shortcuts that have been defined will also appear in the commands help output.
Shortcuts will appear before the option in the output. Shortcuts will appear before the full option
name in the help output.
The example command that has been used so far would produce help information similar to the
following:
1 ...
2
3 Options:
4 -a, --age[=AGE] [default: "0"]
5
6 ...
In the above example signature the default value for the lastName parameter has been
removed. This is because adding a default value to the lastName parameter makes it
an optional parameter. Arguments cannot appear after optional arguments (an error
stating something similar to “Cannot add a required argument after an optional one”
would be displayed). Additionally, we could not have simply changed the order of
the arguments because array parameters must appear last (an error stating something
similar to “Cannot add an argument after an array argument” would be displayed).
Displaying the help information for this command would display something similar to the
following output. Pay attention to how the websites parameter is expressed in the usage section:
1 Usage:
2 example:command [options] [--]
3 <firstName> <lastName> <websites> (<websites>)...
4
5 Arguments:
6 firstName The first name of the user.
7 lastName The last name of the user
8 websites The websites the user contributes to.
Writing Commands 57
An array parameter can be identified by the repeated parameter name in parenthesis. In the
above example, it can be seen that the websites parameter is in fact an array because it is
represented as <websites> (<websites>)... in the usage section.
The following example demonstrates how to execute a command with a signature similar to the
previous example. The firstName is set to John; the last name is set to Doe; and the websites
supplied are laravel.com, laracon.us and laracon.eu.
There is now way to define a default value for an array argument in the command’s signature.
However, an effect similar to default array argument values can be achieved in the implemen-
tation of the command itself.
Unlike when defining command arguments, options can be defined in any order
without worrying about errors related to optional and required arguments being
displayed. However, command options are usually defined after all the arguments.
Notice that the websites option includes both the prefix and the =* suffix. The =* suffix is
important and array options will not work without it. The following help information output
shows how the command array option will be represented when viewing the help information.
Array options can be identified easily since the name of the option will appear in brackets (this
is [=WEBSITES] in the example output) as well as have the trailing text (multiple values
allowed).
Writing Commands 58
1 Options:
2 ...
3 --websites[=WEBSITES] The websites the user contributes to.
4 (multiple values allowed)
5 ...
A command with a signature similar to the above example could be executed like so:
When the command above is issued, the firstName value would be John, the lastName value
would be Doe and the array of websites would contain laravel.com and laracon.us.
Similar to array arguments, array options cannot define a default value in the command’s
signature. A similar effect could be added later in the command’s implementation.
There are a few things to take note of when viewing the help information for a command with
a signature similar to the previous example:
1 Usage:
2 example:command [<system>]
3
4 Arguments:
5 system The system architecture.
In the “Usage” section, we can see that the <system> argument has been placed inside brackets.
Any argument or option that appears in brackets in the usage section is an optional argument or
option.
A command with a signature similar to the previous example could be executed like so:
Writing Commands 59
Any type of command argument can be made optional, including argument arrays.
1 <?php
2
3 namespace App\Console\Commands;
4
5 use Illuminate\Console\Command;
6
7 class NewCommand extends Command
8 {
9 /**
10 * The name and signature of the console command.
11 *
12 * @var string
13 */
14 protected $signature = 'new:command';
15
16 /**
17 * The console command description.
18 *
19 * @var string
20 */
21 protected $description = 'Command description';
22
23 // Methods omitted...
24
25 }
The first thing to notice is that there are two protected variables. One is named $signature and
the other is named $description; for this section, the $description variable is irrelevant.
When the $signature variable is present in the command class, Laravel will expect there to be
a valid command signature. It will then parse it and use that to determine the command’s name,
parameters and options.
The following code example is the start of a typical command class from older versions of the
Laravel framework (again, instance methods have been omitted):
1 <?php
2
3 namespace App\Console\Commands;
4
5 use Illuminate\Console\Command;
6
7 class NewCommand extends Command
8 {
9 /**
10 * The name and signature of the console command.
11 *
Writing Commands 61
12 * @var string
13 */
14 protected $name = 'new:command';
15
16 /**
17 * The console command description.
18 *
19 * @var string
20 */
21 protected $description = 'Command description';
22
23 // Methods omitted...
24
25 }
At first glance there does not look to be any difference between the two code examples. However,
in the second example there is a $name protected variable instead of a $signature protected
variable. When this is the case, Laravel will use the getArguments and getOptions instance
methods to determine the input expectations for the command.
If you would like to use the getArguments or getOptions methods for defining
input expectations, or simply want to ease the transition from an older code base, the
$signature property cannot be defined in your command class. The signature will
be used if it is present, not necessarily if it has been supplied a value. This means that
if both a $name and a $signature property have been defined, the signature method
for defining input expectations will take precedence.
The getArguments and getOptions methods should return an array containing arrays that
represent the command arguments (referred to as parameters in previous sections) and options.
The format for defining arguments versus options is slightly different.
The following table shows the difference between the formats for options and arguments. Both
of arguments and options are represented as an array:
As you can see, the only difference between the two formats is that options can specify a shortcut.
When working with the getOptions and getArguments methods, there are two classes that
are useful to work with. Both the options and arguments are part of the Symfony code base
(Laravel’s console application is an extension of Symfony’s console application). The following
two classes are required:
The InputArgument class defines a few constants that are required when adding command
arguments to the getArguments method. These constants are used to set each of the arguments
mode. The following table lists each of these constants, a description of them and their value
(the value can be used in situations where you do not want to import the class, but this practice
is generally not recommended).
Default values can only be defined for arguments that are using the OPTIONAL mode.
The InputOption class is similar to the InputArgument class in that it defines useful constants
that are required when implementing the getOptions method. Like the arguments, the
constants below set the mode of the option. The following table lists each of these constants:
The following sections will take a second look at all the previously explored examples using the
getOptions and getArguments instance methods. Each section will contain code samples for
both methods as well as the equivalent command signature.
1 test:command {firstArgument}
1 <?php
2
3 use Symfony\Component\Console\Input\InputArgument;
4
5 // Beginning of class omitted...
6
7 public function getArguments()
8 {
9 return [
10 ['firstArgument', InputArgument::REQUIRED]
11 ];
12 }
13
14 // End of class omitted...
In the above example you will notice that we did not have to specify a description or default
value when defining the input argument, but we did have to specify a value for the mode. All of
the values for the input argument have a default value, except for the name. The default value for
the mode is set to InputArgument::OPTIONAL, the description has an empty string as a default
value and the arguments default value is set to null by default.
The signature that will be implemented using the getArguments method is:
1 test:command {firstArgument=DefaultValue}
1 <?php
2
3 use Symfony\Component\Console\Input\InputArgument;
4
5 // Beginning of class omitted...
6
7 public function getArguments()
8 {
9 return [
10 ['firstArgument', InputArgument::OPTIONAL, '', 'DefaultValue']
11 ];
12 }
13
14 // End of class omitted...
Writing Commands 64
The signature that will be implemented using the getArguments method is:
1 <?php
2
3 use Symfony\Component\Console\Input\InputArgument;
4
5 // Beginning of class omitted...
6
7 public function getArguments()
8 {
9 return [
10 ['firstArgument', InputArgument::REQUIRED, 'This is the description']
11 ];
12 }
13
14 // End of class omitted...
1 test:command {--optionName}
1 <?php
2
3 use Symfony\Component\Console\Input\InputOption;
4
5 // Beginning of class omitted...
6
7 public function getOptions()
8 {
9 return [
10 ['optionName']
11 ];
12 }
13
14 // End of class omitted...
In the above example we only had to set the name of the option to optionName. When using the
getOptions method we do not have to prefix option names with the double hyphen (--) prefix.
Additionally, the shortcut, mode, description and default value for the option did not have to be
set.
The following table details the default values that are assigned to each property of an InputOp-
tion if none are supplied:
The signature that will be implemented using the getOptions method is:
1 test:command {--optionName=DefaultValue}
1 <?php
2
3 use Symfony\Component\Console\Input\InputOption;
4
5 // Beginning of class omitted...
6
7 public function getOptions()
8 {
9 return [
10 ['optionName', null, InputOption::VALUE_OPTIONAL, '', 'DefaultValue']
11 ];
12 }
13
14 // End of class omitted...
The signature that will be implemented using the getOptions method is:
1 <?php
2
3 use Symfony\Component\Console\Input\InputOption;
4
5 // Beginning of class omitted...
6
7 public function getOptions()
8 {
9 return [
10 ['optionName', null, InputOption::VALUE_NONE, 'Option description.']
11 ];
12 }
13
14 // End of class omitted...
The signature that will be implemented using the getOptions method is:
1 test:command {--q|optionName}
1 <?php
2
3 use Symfony\Component\Console\Input\InputOption;
4
5 // Beginning of class omitted...
6
7 public function getOptions()
8 {
9 return [
10 ['optionName', 'q']
11 ];
12 }
13
14 // End of class omitted...
The signature that will be implemented using the getOptions method is:
1 test:command {argumentName=*}
1 <?php
2
3 use Symfony\Component\Console\Input\InputOption;
4
5 // Beginning of class omitted...
6
7 public function getArguments()
8 {
9 return [
10 ['argumentName', InputArgument::IS_ARRAY | InputArgument::REQUIRED]
11 ];
12 }
13
14 // End of class omitted...
The signature that will be implemented using the getOptions method is:
1 test:command {--optionName=*}
1 <?php
2
3 use Symfony\Component\Console\Input\InputOption;
4
5 // Beginning of class omitted...
6
7 public function getOptions()
8 {
9 return [
10 ['optionName', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE\
11 _OPTIONAL]
12 ];
13 }
14
15 // End of class omitted...
In the above example two option mode values have been combined. If you were to specify just
the InputOption::VALUE_IS_ARRAY option an error stating something similar to “Impossible
to have an option mode VALUE_IS_ARRAY if the option does not accept a value”.
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 // Get the firstName argument. In this
8 // example, the $firstName value would
9 // be set to 'John'.
10 $firstName = $this->argument('firstName');
11
12 // Get the lastName argument. In this
13 // example, the $lastName value would
14 // be set to 'Doe'.
15 $lastName = $this->argument('lastName');
16
17 // Get all the arguments from the user.
18 // The $input variable would then
19 // reference an array containing
20 // all the input that the user
21 // supplied when executing
22 // the command.
23 $input = $this->argument();
24 }
25
26 // ...
When a command similar to the above example has been executed, the $input variable would
contain an array similar to the following output:
1 array [
2 "command" => "example:command"
3 "firstName" => "John"
4 "lastName" => "Doe"
5 ]
In the above output you can see that there are arguments returned by the argument method. The
first element of the commands input arguments will always be the name of the command (this
item is set early on in the command execution life cycle). The remaining items will be the input
arguments in the order they were defined in the command’s signature. The items are stored such
Writing Commands 70
that the key of the argument is the name given to the argument and the associated value is either
the user supplied value or the specified default value of the argument.
8.2.2 hasArgument($name)
The hasArgument method can be used to determine if an argument exists by name. It accepts
the $name of the argument as its only argument. This method returns a boolean value indicating
whether or not the argument exists.
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 // Check if an argument exists.
8 if ($this->hasArgument('firstName')) {
9 // The firstName argument was supplied.
10 }
11 }
12
13 // ...
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 // Get the psr option value. Since the option
8 // is acting like a flag, its value will be
9 // either true or false, depending on if
10 // the options presence when executed.
11 $psr = $this->option('psr');
12
13 // Get the option value of the path option.
14 $path = $this->option('path');
15
16 // Get all the input options.
17 $options = $this->option();
18 }
19
20 // ...
When a command similar to the above example has been executed, the $psr variable would
hold a value of true since the psr option was present when the command was executed. If
the psr option was not present when the command was executed (such as when issuing the
command example:command—with no options) the $psr variable would contain a value of
false. The $path variable would hold the value storage/framework (since that was specified
in the example command execution).
When options are not supplied and do not have a default value their value will be set to null.
As an example, issuing the following command will result in the path option value to be set to
null:
Similar to how arguments have a command value that is always set, there are numerous default
options that are available to your commands. After the above example command has been
executed the $options variable would reference an array similar to the following output:
Writing Commands 72
1 array [
2 "path" => "storage/framework"
3 "psr" => true
4 "help" => false
5 "quiet" => false
6 "verbose" => false
7 "version" => false
8 "ansi" => false
9 "no-ansi" => false
10 "no-interaction" => false
11 "env" => null
12 ]
Any options that your command explicitly defines will appear at the beginning of the resulting
array. The default options that appear serve different purposes that are common to most
commands.
8.2.4 hasOption($name)
The hasOption method is used to determine if an option exists. It accepts the $name of the
option as its only argument. This method returns a boolean value indicating whether or not the
option exists.
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 // Determine if an option is present.
8 if ($this->hasOption('no-interaction')) {
9 // The `--no-interaction` option has been set.
10 }
11 }
12
13 // ...
The following table provides a general overview of each of the global options. Each global option
will also be discussed in its own section with more details.
Option Shortcut Description
help h Displays help information about the
command.
version V Displays the application version.
ansi Enable output coloring (ANSI
output), if available.
no-ansi Disables output coloring (ANSI
output).
no-interaction n Disables any interactive questions.
env Determines the environment the
command should run under.
quiet q Suppresses any messages the
command may generate.
verbose v, vv, vvv Determines the verbosity of
messages the command generates.
The above example commands would output something similar to Laravel Framework ver-
sion 5.2.29. The actual phrasing and version number will possibly be different from your
results.
The --env option can be used to set which environment the command should be ran under.
The env command shows the current configured Laravel environment. Assuming the default
environment is local we can observe the effects of the --env option by running the following
example commands. The command output appears above the commands as a comment.
Commands often output numerous messages or interactively ask for input. The --quiet option
can be used to suppress all output from the command. As an example the following command
invocations would not display any output in the console:
The --verbose option is the logical opposite of the --quiet option. The --verbose option
can be used to specify the verbosity of the messages a command generates. While this option is
available on all commands it is up to each individual command to recognize the verbosity levels
and update its output accordingly. The verbosity levels are defined as constants in Symfony’s
Symfony\Component\Console\Output\OutputInterface class. The following table details
the verbosity levels, their integer value and their corresponding option:
The following code example can be used to determine which verbosity level is currently in use.
Writing Commands 75
1 <?php
2
3 use Symfony\Component\Console\Output\OutputInterface;
4
5 // Beginning of class omitted...
6
7 function handle()
8 {
9 // First get the verbosity level.
10 $verbosity = $this->output->getVerbosity();
11
12 if ($verbosity == OutInterface::VERBOSITY_QUIET) {
13 // Verbosity level is quiet.
14 // Set by using the --quiet or -q options.
15 } else if ($verbosity == OutputInterface::VERBOSITY_NORMAL) {
16 // Verbosity level is normal.
17 // Set by not supplying any verbosity options.
18 } else if ($verbosity >= OutputInterface::VERBOSITY_VERBOSE) {
19 // Verbosity level is at least verbose.
20 // Set using the --verbose or -v options.
21 } else if ($verbosity >= OutputInterface::VERBOSITY_VERY_VERBOSE) {
22 // Verbosity level is at least very verbose.
23 // Set using the -vv option.
24 } else if ($verbosity >= OutputInterface::VERBOSITY_DEBUG) {
25 // Verbosity level is at the highest level.
26 // Set using the -vvv option.
27 }
28
29 }
30
31 // Ending of class omitted...
Laravel also exposes a few methods to make comparing verbosity levels easier. The following
example shows a cleaner way to check verbosity levels compared to the previous example:
1 <?php
2
3 // Beginning of class omitted...
4
5 function handle()
6 {
7
8 if ($this->output->isQuiet()) {
9 // Verbosity level is quiet.
10 }
11
Writing Commands 76
12 if ($this->output->isVerbose()) {
13 // Verbosity level is at least verbose.
14 }
15
16 if ($this->output->isVeryVerbose()) {
17 // Verbosity level is at least very verbose.
18 }
19
20 if ($this->output->isDebug()) {
21 // Verbosity is at the highest level.
22 }
23
24 }
25
26 // Ending of class omitted...
Sometimes when interacting with commands exceptions are thrown. For example, the following
command purposely throws an exception:
1 <?php
2
3 // Beginning of class omitted...
4
5 function handle()
6 {
7 throw new \Exception('An example exception');
8 }
9
10 // Ending of class omitted...
When the above command is executed the default behavior is to simply indicate that an exception
has been thrown and would display something similar to the following output:
1 [Exception]
2 An example exception.
1 [Exception]
2 An example exception.
3
4
5 Exception trace:
6 () at /home/vagrant/Code/Laravel/app/Console/Commands/ExampleCommand.php:42
7 App\Console\Commands\ExampleCommand->handle() at n/a:n/a
8 call_user_func_array() at /home/vagrant/Code/Laravel/vendor/laravel/
9 framework/src/Illuminate/Container/Container.php:507
10 Illuminate\Container\Container->call() at /home/vagrant/Code/Laravel/vendor/
11 laravel/framework/src/Illuminate/Console/Command.php:169
12 Illuminate\Console\Command->execute() at /home/vagrant/Code/Laravel/vendor/
13 symfony/console/Command/Command.php:256
14 Symfony\Component\Console\Command\Command->run() at /home/vagrant/Code/
15 Laravel/vendor/laravel/framework/src/Illuminate/Console/Command.php:155
16 Illuminate\Console\Command->run() at /home/vagrant/Code/Laravel/vendor/
17 symfony/console/Application.php:791
18 Symfony\Component\Console\Application->doRunCommand() at /home/vagrant/Code/
19 Laravel/vendor/symfony/console/Application.php:186
20 Symfony\Component\Console\Application->doRun() at /home/vagrant/Code/
21 Laravel/vendor/symfony/console/Application.php:117
22 Symfony\Component\Console\Application->run() at /home/vagrant/Code/Laravel/
23 vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:107
24 Illuminate\Foundation\Console\Kernel->handle() at /home/vagrant/Code/
25 Laravel/artisan:35
The --no-interaction default option will be discussed in the section “Prompting for User
Input”. The --no-interaction option (when specified) will effectively disable all the features
discussed in that section.
Method Description
secret Prompt the user for input without showing the answer
in the console.
choice Allows the user to select an answer from a defined set
of answers.
confirm Prompts a user with a yes or no question.
Each of the mentioned methods provide numerous options to customize the behavior of the
prompt that is displayed to the user. All of the methods accept default values as well as allow
you to customize the message that is displayed to the end user when the command executes.
All input interactive input methods will return the user’s input to the command. Each of these
methods will be discussed in greater detail in their own sections.
1 <?php
2
3 namespace App\Console\Commands;
4
5 use Illuminate\Console\Command;
6
7 class ExampleCommand extends Command
8 {
9
10 protected $signature = 'example:command';
11
12 function handle()
13 {
14 // Ask the user for their name.
15 $name = $this->ask('What is your name?');
16 }
17
18 }
When the command is executed, the user will see something similar to the following in their
terminal:
If the user attempts to continue execution of the command without specifying a value they will
receive an error stating “[ERROR] A value is required”. This error can be avoided by providing
a default value that will be used when the user does not supply a value:
Writing Commands 79
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 // Ask the user for their name.
8 $name = $this->ask('What is your name?', 'John Doe');
9 }
10
11 // ...
Another useful thing to prompt users for is an answer to a simple “yes or no” question. The
following code example demonstrates a naive attempt at implementing this behavior. It simply
asks the user if they want to continue the execution of the command; it does this by checking the
user’s input. If the user supplied the string n (or even N since everything is converted to lowercase)
the command will stop execution; everything else will cause the command to continue running.
1 <?php
2
3 // ...
4
5 public function handle()
6 {
7 $shouldContinue = $this->ask('Do you want to continue? [Y|n]', 'Y');
8
9 if (strtolower($shouldContinue) == 'n') {
10 // Do not continue.
11 return 0;
12 }
13
14 // Other command actions.
15
16 }
17
18 // ...
Laravel provides a simpler way to accomplish this via the confirm instance method. The
confirm method defines two parameters. The first is required and is the message to prompt
the user with. The second argument that can be supplied to the confirm method is the default
response. The following examples demonstrate the confirm method:
Writing Commands 80
1 <?php
2
3 // ...
4
5
6 function handle()
7 {
8 $shouldContinue = $this->confirm('Do you want to continue?');
9
10 if (!$shouldContinue) {
11 // Do not continue.
12 return 0;
13 }
14
15 // Other command actions.
16 }
17
18 // ...
When the above command is executing the following prompt would be displayed to users:
The confirm method will present the user with the supplied message as well as the accepted
values (in this case the acceptable values are either yes or no) in parenthesis. The method will also
display the default value in square brackets (in the previous example, and by default, that value
is no). The default value can be changed by supplying a boolean value as the second argument
to the confirm method:
1 <?php
2
3 // ...
4
5
6 $shouldContinue = $this->confirm('Do you want to continue?', true);
7
8 // ...
Now when the user executes the command they will see the following prompt (take note of the
default value that is being displayed):
Writing Commands 81
The confirm method is not very customizable. It defaults to expecting either a yes or no
response. There are times when it might be beneficial to customize the default behavior. The
confirm method is a helpful wrapper around Symfony’s ConfirmationQuestion. We can
directly instantiate an instance of this class to customize the behavior. The definition for the
ConfirmationQuestion constructor is:
1 /**
2 * Constructor.
3 *
4 * @param string $question The question to ask to the user
5 * @param bool $default The default answer to return, true or false
6 * @param string $trueAnswerRegex A regex to match the "yes" answer
7 */
8 public function __construct(
9 $question,
10 $default = true,
11 $trueAnswerRegex = '/^y/i') {}
The first argument that must be supplied to the ConfirmationQuestion is the question that will
be asked of the end user. The other two parameters are not required by default and are used to
customize the default behavior. An argument for the $default parameter determines the default
behavior (or response) of the question. The $trueAnswerRegex works in conjunction with the
$default value; it should contain a regular expression that represents the accepted value for
the truth answer. The following example demonstrates how to use the ConfirmationQuestion
within a Laravel command:
1 <?php
2
3 namespace App\Console\Commands;
4
5 use Symfony\Component\Console\Question\ConfirmationQuestion;
6 use Illuminate\Console\Command;
7
8 class ExampleCommand extends Command
9 {
10
Writing Commands 82
11 // ...
12
13 public function handle()
14 {
15 $question = new ConfirmationQuestion(
16 'Do you want to continue? (HIja’/ghobe’)',
17 true,
18 '/^h/i'
19 );
20
21 $shouldContinue = $this->output->askQuestion($question);
22
23 if (!$shouldContinue) {
24 // Do not continue.
25 return 0;
26 }
27
28 // Other command actions.
29 }
30
31 }
When a command similar to the previous example has executed the user would see something
similar to the following output. The question will accept HIja’ yes as the answer for yes.
The above example still contains the (yes/no) [yes] default string. This string is hard-coded
into Symfony’s Symfony\Component\Console\Helper\SymfonyQuestionHelper. The Sym-
fonyQuestionHelper is used internally by Symfony’s SymfonyStyle, which in turn is used
by Laravel’s OutputStyle. This default text can be changed but would require overriding many
methods and classes in the inheritance hierarchy.
1 /**
2 * Prompt the user for input with auto completion.
3 *
4 * @param string $question
5 * @param array $choices
6 * @param string $default
7 * @return string
8 */
9 public function anticipate($question, array $choices, $default = null) {}
An argument for the $question parameter will become the prompt that is displayed to the user.
An array of $choices must be supplied as these will become the options that are suggested to
the end user. An optional default value can be supplied (via the $default parameter) which will
be used if the user does not enter a value.
The following example demonstrates the usage of the anticipate method (note that the
askWithCompletion method is used in exactly the same way):
1 <?php
2
3 // ...
4
5
6 function handle()
7 {
8 $favoriteNut = $this->anticipate('What is your favorite nut?', [
9 'Peanuts',
10 'Almond',
11 'Cashew'
12 ]);
13 }
14
15 // ...
When the user executes the command in a terminal, they will see something similar to the
following figure:
As the user types any matching choices will be suggested to them. In most terminals the style
changes and displays the suggestion with a different background color (such as in the image
above). Other terminals may even display a list of suggestions that match the user’s input.
Writing Commands 84
1 /**
2 * Prompt the user for input but hide the answer from the console.
3 *
4 * @param string $question
5 * @param bool $fallback
6 * @return string
7 */
8 public function secret($question, $fallback = true) {}
It accepts a $question, or message, that will be displayed to the user as the prompt. The
method also defines a $fallback parameter (which defaults to true) which accepts a truth
value as its argument. The $fallback argument is used to determine if the command should
continue to collect the user’s input if the user’s input cannot be hidden. If $fallback is set
to true, the command will continue to collect user input even if the user’s input cannot be
hidden in the console. If $fallback is set to false and the input cannot be hidden an instance
of Symfony\Component\Console\Exception\RuntimeException will be thrown with the
message “Unable to hide the response”.
Laravel internally relies on Symfony to attempt to hide the user’s input from the console. On
Windows systems the hiddeninput.exe binary will be used to attempt to hide input from
the user. On Linux and Unix systems with stty available (a utility used to change command
line options and settings), ssty will be used to hide the user’s input. If stty is not available on
a non-Windows system certain shells will be tried (such as bash, zsh, ksh, or csh) to attempt
to hide the user’s input. If none of the previously mentioned methods work to hide the user’s
input an exception will be thrown stating something similar to “Unable to hide the response”.
1 <?php
2
3 namespace App\Console\Commands;
4
5 use Illuminate\Console\Command;
6
7 class ExampleCommand extends Command
8 {
9
10 // ...
11
12 public function handle()
13 {
14 // Previous command actions, such as getting
15 // the user's email or username.
16
17 $password = $this->secret('Password');
18
19 // Other command actions.
20 }
21
22 // ...
23
24 }
After a command similar to the following has executed the user would see output similar to the
following in the console:
1 Password:
2 >
When the user types their response in the console (assuming the input could be hidden and
the $fallback has been set to true) the input would be hidden and their response would be
assigned to the $password variable. Typically you would gather the user’s username or email
address before requesting their password.
1 /**
2 * Give the user a single choice from an array of answers.
3 *
4 * @param string $question
5 * @param array $choices
6 * @param string $default
7 * @param mixed $attempts
8 * @param bool $multiple
9 * @return string
10 */
11 public function choice(
12 $question,
13 array $choices,
14 $default = null,
15 $attempts = null,
16 $multiple = null) {}
An argument for the $question parameter will become the prompt that is displayed to the
user. The $choices array is also required and will be displayed to the user. The following code
example demonstrates the basic usage of the choice method:
1 <?php
2
3 namespace App\Console\Commands;
4
5 use Illuminate\Console\Command;
6
7 class ExampleCommand extends Command
8 {
9
10 // ...
11
12 function handle()
13 {
14 // Ask a user what their favorite juice is.
15 $favoriteChoice $this->choice('What is your favorite juice?', [
16 'Cranberry Apple',
17 'Orange',
18 'Pomegranate'
19 ]);
20 }
21
22 // ...
23
24 }
Writing Commands 87
When the command is executed, the user would see something similar to the following output
in the terminal:
At this point the user can type their response. A valid response is either the key or value of
the choices (the first valid value that can satisfy the user’s input will be used). An associative
array can also be supplied; the key/value pairs will displayed to the user. Consider the following
example and output:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $favoriteJuice = $this->choice('What is your favorite juice?', [
8 'Cra' => 'Cranberry Apple',
9 'Ora' => 'Orange',
10 'Pom' => 'Pomegranate',
11 'Orange' => 'Prune'
12 ]);
13 }
14
15 // ...
The prompt the user would see would be similar to the following:
If a user supplies an invalid value an error stating something similar to [ERROR] Value
<VALUE> is invalid where <VALUE> is user supplied value. It is important to note that the
error is not a fatal error or an exception that can be caught. The command will continue to ask
for valid input until the user terminates the command (see the section “Limiting the Number of
Attempts” for more information on how to get around this).
Writing Commands 88
The previous example was chosen specifically because of the ambiguity between the Orange
value and the Orange key. If the user types the value Orange at the terminal the $fa-
voriteJuice variable would contain the value Ora. This is because matching values are given
precedence over matching keys. In the following example the value would still be Ora:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $favoriteJuice = $this->choice('What is your favorite juice?', [
8 'Cra' => 'Cranberry Apple',
9 'Pom' => 'Pomegranate',
10 'Orange' => 'Prune',
11 'Ora' => 'Orange'
12 ]);
13 }
14
15 // ...
The third $default parameter allows you to specify a default value. The default value follows
the same precedence rules as when a user supplies their own value. The following example
demonstrates how to supply a default value:
1 <?php
2
3 // ...
4
5
6 function handle()
7 {
8 $favoriteJuice = $this->choice('What is your favorite juice?', [
9 'Cra' => 'Cranberry Apple',
10 'Pom' => 'Pomegranate',
11 'Orange' => 'Prune',
12 'Ora' => 'Orange'
13 ], 'Ora');
14
15 }
16
17 // ...
Writing Commands 89
If a command similar to the above example was executed and the user did not supply a value
the $favoriteJuice variable would contain the value Ora.
If a user enters an invalid value when making a choice an error message will be displayed and
they will be prompted to select a valid choice. This will continue until the user makes a valid
selection or they terminate the execution of the command. This behavior can be avoided by
specifying a maximum number of attempts the user has to make a valid selection. This can be
done by supplying an argument for the $attempts parameter. By default $attempts is set to
null (a value of null allows the user to make as many attempts as they want).
1 <?php
2
3 // ...
4
5
6 function handle()
7 {
8 $favoriteJuice = $this->choice('What is your favorite juice?', [
9 'Cra' => 'Cranberry Apple',
10 'Ora' => 'Orange'
11 ], null, 2);
12
13 }
14
15 // ...
When a user runs a command similar to the previous example and provides an invalid choice two
times in a row an instance of Symfony\Component\Console\Exception\InvalidArgumentException
will be thrown. This exception can be handled within the command to deal with the invalid user
input if desired. If the exception is not handled the command’s execution will be halted and the
exception’s error message will be displayed to the user.
It is also possible to allow users to select multiple values. To allow users to specify multiple values
supply a truth value that evaluates to true for the fifth ($multiple) parameter. A user separates
multiple values by commas.
The following example demonstrates how to allow users to select multiple values (there is also
no default value and users have unlimited attempts):
Writing Commands 90
1 <?php
2
3 // ...
4
5
6 function handle()
7 {
8 // Allow users to specify multiple juice varieties. Notice the fifth
9 // argument is `true`.
10 $favoriteJuice = $this->choice('What are your favorite juices?', [
11 'Cra' => 'Cranberry Apple',
12 'Ora' => 'Orange'
13 ], null, null, true);
14
15 }
16
17 // ...
If the user typed Cra, Ora as their input both of the options would be placed in an array and
assigned to the $favoriteJuice variable. The resulting array would be structured similar to
the following output:
1 array(2) {
2 [0] =>
3 string(3) "Cra"
4 [1] =>
5 string(3) "Ora"
6 }
Since this command disables all of the interactive prompts consider providing alternative ways
to provide the input to your command (think of such situations where users want to automate
the calls to your command). You can check to see the state of user interaction in the following
ways:
Writing Commands 91
1 <?php
2
3 namespace App\Console\Commands;
4
5 use Illuminate\Console\Command;
6
7 class TestCommand extends Command
8 {
9
10 // ...
11
12 public function handle()
13 {
14 // Checking to see if the user has disabled
15 // interactive mode by checking for the
16 // existence of the --no-interaction
17 // user defined option.
18 if ($this->hasOption('no-interaction')) {
19 // The user has disable interactive mode.
20 }
21
22 // Check to see if the current command environment
23 // supports interactive communication with the
24 // user by calling an instance method on the
25 // commands input implementation.
26 if ($this->input->isInteractive()) {
27 // Interactive prompts are available for the
28 // current command session. It is okay to
29 // prompt the user interactively to get
30 // their input.
31 }
32 }
33
34 // ...
35
36 }
9. Command Output
The previous sections have discussed the various ways to defined input expectations and retrieve
the input from users. This section will focus on how to communicate to the users of your
command using various command output methods. Laravel makes it very easy to communicate
with your users, providing useful helper methods to quickly generate tables, progress bars and
other common output elements.
The following table contains all of the output methods that Laravel provides directly. There are
additional methods that are available that are inherited from Symfony’s Symfony\Component\Console\Style\
console output style. These additional methods will be discussed after the Laravel provided
methods. The table contains the name of the method, a general description of the method,
the default font color for the underlying console style and the default background color of the
underlying console style. Any color specified as Inherited indicates that the underlying console
style does not specify an explicit color or styling.
92
Command Output 93
1 /**
2 * Write a string as standard output.
3 *
4 * @param string $string
5 * @param string $style
6 * @param null|int|string $verbosity
7 * @return void
8 */
9 public function line($string, $style = null, $verbosity = null) {}
The line method defines only one required parameter: $string. An argument supplied for the
$string argument will be the text that is written to the console. The $style parameter is used
to control the styling of the written line. By default the $style is null which will cause the
$string to be written without any special styling. The $verbosity parameter can be used to
control when the message will be displayed to the end user. By default $verbosity is set to
null which means the $string will be displayed under all verbosity levels.
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->line('Hello, there!');
8 }
9
10 // ...
After the above code has executed, the user would see something similar to the following in their
console:
1 Hello, there!
The $style parameter (when not null) requires a string argument. The following table lists the
styles that are available by default:
Command Output 94
Style Name
comment
question
error
warning
info
The following examples demonstrate how to use the $style parameter. These styles will be
discussed further in the section “Outputting Lines with Colors”.
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 // Outputting lines with styles using the `line` method.
8 $this->line('Hello, there!', 'question');
9 $this->line('Hello, there!', 'error');
10 // ...
11 }
12
13 // ...
The $verbosity parameter can be used to greatly reduce the amount of code when dealing with
different verbosity levels. The following code example can be simplified by taking advantage of
the $verbosity parameter:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 if ($this->output->isVeryVerbose()) {
8 $this->line(
9 'Only shown for the VERY_VERBOSE verbosity level.'
10 );
11 }
12 }
13
14 // ...
The same functionality can be achieved using the $verbosity parameter and one of the ver-
bosity level constants (defined in Symfony’s Symfony\Component\Console\Output\OutputInterface).
The following table serves as a refresher of these constants, and the code sample that follows
demonstrates how they can be used with the line method.
Command Output 95
1 <?php
2
3 use Symfony\Component\Console\Output\OutputInterface;
4
5 // ...
6
7 function handle()
8 {
9 $this->line(
10 'Only shown for the VERY_VERBOSE verbosity level.',
11 null,
12 OutputInterface::VERBOSITY_VERY_VERBOSE
13 );
14 }
15
16 // ...
If you would prefer not to import the OutputInterface interface the $verbosity parameter
also understands the option versions of the verbosity levels. The following example is function-
ally equivalent to the previous two:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->line(
8 'Only shown for the VERY_VERBOSE verbosity level.',
9 null,
10 'vv'
11 );
12 }
13
14 // ...
The previous three examples would all output the same result when the very verbose (-vv) option
is specified when executing the command.
Command Output 96
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 // Output a warning message.
8 $this->warn('Warning line. Written using `warn`.');
9
10 // Output an error message.
11 $this->error('Error line. Written using `error`.');
12
13 // Output a message styled as a question.
14 $this->question('Question line. Written using `question`.');
15
16 // Output a message styled as a comment.
17 $this->comment('Comment line. Written using `comment`.');
18
19 // Output an informative message.
20 $this->info('Info line. Written using `info`.');
21 }
22
23 // ...
When the messages are printed in a console window that supports colored output the user would
see something similar to the following (note that the blank lines have been added for clarity in
the output):
The warn, error, question, comment and info methods all support the $verbosity parameter
found in the line method. Using the $verbosity parameter in these methods is exactly the
Command Output 97
same as using it with the line method. The following demonstrates how to write a warning
only for a certain verbosity level:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 // Output a warning message.
8 $this->warn('A warning message only for the very verbose.', 'vv');
9 }
10
11 // ...
9.3 Tables
Manually attempting to display tabular output from a command can be a challenging processes.
The table method can be used to easily generate an ASCII table with the correct padding and
headers to display to the console. The signature for the table method is:
1 /**
2 * Format input to textual table.
3 *
4 * @param array $headers
5 * @param \Illuminate\Contracts\Support\Arrayable|array $rows
6 * @param string $style
7 * @return void
8 */
9 public function table(array $headers, $rows, $style = 'default'){}
Arguments $headers and $rows parameters are required, but can be an empty array. If the
$headers array is not empty and the $rows array is empty, the table method will simply
generate the headers. If there are no headers but there are data rows the table method will
print the data without any headers. The $style parameter is used to control the styling of the
table and is set to default by default.
The following example demonstrates a simple usage of the table method:
Command Output 98
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $headers = ['Name', 'Email'];
8
9 $rows = [
10 ['John Doe', 'john@example.org'],
11 ['Jane Doe', 'jane@example.org']
12 ];
13
14 $this->table($headers, $rows);
15 }
16
17 // ...
After the command has executed the user would see something similar in their terminal:
1 +----------+------------------+
2 | Name | Email |
3 +----------+------------------+
4 | John Doe | john@example.org |
5 | Jane Doe | jane@example.org |
6 +----------+------------------+
The table method can also handle mismatched headers and data elements, but it is generally
recommended to have all of the headers and data required before using the table method. This
is especially true when there are more headers than there are data as it can get confusing when
data is placed in the wrong column.
There are a number of default table $styles that can be used to quickly change the way the
generated tables appear. The following default table styles are available for your convenience:
default
The default table style separates the headers and table data as well as provides padding
and borders between columns. Each border intersection is accented with the + character.
The headers are styled using the info text style.
Command Output 99
1 +----------+------------------+
2 | Name | Email |
3 +----------+------------------+
4 | John Doe | john@example.org |
5 | Jane Doe | jane@example.org |
6 +----------+------------------+
borderless
The borderless table style is similar to the default table style, but does not have
any borders between columns. The header dividers are also larger to make it easier to
distinguish between headers and table data.
1 ========== ==================
2 Name Email
3 ========== ==================
4 John Doe john@example.org
5 Jane Doe jane@example.org
6 ========== ==================
compact:
The compact table style displays headers and table data without any borders between the
rows and cells.
1 Name Email
2 John Doe john@example.org
3 Jane Doe jane@example.org
symfony-style-guide
The symfony-style-guide table style is similar to the borderless table style with the
difference being the header dividers are less pronounced.
1 ---------- ------------------
2 Name Email
3 ---------- ------------------
4 John Doe john@example.org
5 Jane Doe jane@example.org
6 ---------- ------------------
1 <?php
2
3
4 // ...
5
6 function handle()
7 {
8 $this->output->progressStart();
9
10 for (i = 0; i <= 50; i++) {
11 $this->output->progressAdvance();
12 }
13
14 $this->output->progressFinish();
15 }
16
17 // ...
When the command is executed in the console the user would see output similar to the following
example:
The progressStart method creates a new progress bar instance for the output. It defines a $max
parameter which can be used to control the maximum amount of steps that the progress bar will
be displayed. If it is omitted, as in the previous example, there is no set end to the progress bar
and will continue to fill until the progressFinish method is called. When an argument for
$max is supplied each step will take up a percentage of the bar relative to the total amount of
steps.
The following example demonstrates how to use the $max parameter:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 // Create a new progress bar with a total of 50 steps.
8 $this->output->progressStart(50);
9
10 for (i= 0; <= 49; i++) {
11 $this->output->progressAdvance();
12 }
13
14 $this->output->progressFinish();
Command Output 101
15 }
16
17 // ...
Progress bars that have a set number of steps are displayed slightly differently in the terminal.
The default style is to display the number of steps completed out of the total number of steps
(for example 31/50).
9.5.1 block
The block method is used to format a message as a block of text. Blocks of text generally have
a different background color and can have optional padding and labels. The signature for the
block method is:
1 /**
2 * Formats a message as a block of text.
3 *
4 * @param string|array $messages The message to write in the block
5 * @param string|null $type The block type (added in [] on first line)
6 * @param string|null $style The style to apply to the whole block
7 * @param string $prefix The prefix for the block
8 * @param bool $padding Whether to add vertical padding
9 */
10 public function block(
11 $messages,
12 $type = null,
13 $style = null,
14 $prefix = ' ',
15 $padding = false
16 ){}
Command Output 102
A string or array are expected arguments for the $messages parameter (if you have a lot
messages to output to the console, consider supplying an array instead of a single string). The
messages $type determines what will be displayed in brackets when the block is rendered. For
example a block with the SUCCESS type might render like the following example:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->output->block('This is an example message.', 'SUCCESS');
8 }
9
10 // ...
Supplying a value of null for the $type will not render any type information for the block. A
$prefix can be set which will placed at the beginning of the block when it is rendered (note
that null has been supplied for the $style parameter in the following example):
1 <?php
2
3 // ...
4
5
6 function handle()
7 {
8 $this->output->block(
9 'This is an example message.',
10 'SUCCESS',
11 null,
12 'Prefix'
13 );
14 }
15
16 // ...
A string argument can be supplied to the $style parameter to change how the block is displayed.
Customizing styles will be discussed in the section “Creating Custom Console Styles”. However,
the following example would create a new block with green background and black text:
Command Output 103
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->output->block(
8 'This is an example message.',
9 'SUCCESS',
10 'fg=black;bg=green'
11 );
12 }
13
14 // ...
9.5.2 title
The title method can be used to format a command’s title. It accepts a string ($message) that
will be printed to the console. This method prints content using the comment text style. The
following example demonstrates the usage of the title method:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->output->title('An example title.');
8 }
9
10 // ...
1 An example title.
2 =================
9.5.3 section
The section method is similar to the title method, but prints a title that is generally used for
subsections within a command (the underlining is less pronounced). Like the title method, the
section method also formats text using the comment text style. The section method is used
in the same way as the title method:
Command Output 104
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->output->section('An example section.');
8 }
9
10 // ...
1 An example section.
2 -------------------
9.5.4 listing
The listing method is useful for displaying an unordered list of elements. It accepts an array
of $elements (the items that should be displayed as a list) as its only argument. The following
example demonstrates its usage:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->output->listing([
8 'Chapter One',
9 'Chapter Two',
10 'Chapter Three'
11 ]);
12 }
13
14 // ...
The user would see something similar to the following in their console window:
1 * Chapter One
2 * Chapter Two
3 * Chapter Three
This method does not handled nested arrays. If nested arrays are supplied as an argument
an instance of ErrorException will be thrown with a message similar to “Array to string
conversion”.
Command Output 105
9.5.5 writeln
The writeln method is used to write line(s) of content to the output while adding a newline at
the end of each line. The writeln method takes either a single string or an array of $messages
as its first argument. It also allows you to specify options that control how the lines are written
via the $options parameter. The $options parameter allow you to control the verbosity of
the message, the output format (raw, colored, etc). This method is generally used internally by
various components.
The following demonstrates how to call the writeln method:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->output->writeln([
8 'Chapter One',
9 'Chapter Two',
10 'Chapter Three'
11 ]);
12 }
13
14 // ...
The user would see something similar to the following in their console window. Note that each
message in the array appears on its own line.
1 Chapter One
2 Chapter Two
3 Chapter Three
9.5.6 write
The write method is similar to the writeln method in that it accepts either a single string or
an array of $messages, as well as a bitmask of $options. However, the write method does
not add a newline character to the end of each message by default. The signature of the write
method is:
Command Output 106
1 /**
2 * Writes a message to the output.
3 *
4 * @param string|array $messages The message as an array of lines or a single
5 string
6 * @param bool $newline Whether to add a newline
7 * @param int $options A bitmask of options (one of the OUTPUT or
8 VERBOSITY constants), 0 is considered the
9 same as self::OUTPUT_NORMAL |
10 self::VERBOSITY_NORMAL
11 */
12 public function write($messages, $newline = false, $options = 0) {}
The following example demonstrates how to call the write method, and how it is similar to the
writeln method (the writeln method internally makes a call to the write method):
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 // Call the `write` method. All items
8 // would appear on the same line.
9 $this->output->write([
10 'Chapter One',
11 'Chapter Two',
12 'Chapter Three'
13 ]);
14
15 // Call the `write` method. All items would appear on their
16 // own line. This is is effectively the same as calling
17 // the `writeln` method with the same exact arguments
18 $this->output-write([
19 'Chapter One',
20 'Chapter Two',
21 'Chapter Three'
22 ], true);
23 }
24
25 // ...
9.5.7 newLine
The newLine method is a simple utility method to write newlines (blank lines) to the console
window. It accepts a $count of the number of blank lines to write; by default it will print one
blank line to the console window.
Command Output 107
The newLine method was used extensively in the writing of this book to provide ample room in
the console window to get clean screen grabs. The newLine method can be used like so:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->line('The first message.');
8
9 // Write one blank line to the console.
10 $this->output->newLine();
11
12 $this->line('The second message.');
13
14 // Write six blank lines to the console.
15 $this->output->newLine(6);
16
17 $this->line('The third message.');
18 $this->line('The fourth message.');
19 }
20
21 // ...
The following sections discuss methods that have similar method names to those that are
available on Laravel’s Command class. However, the following methods are defined in Symfony’s
Symfony\Component\Console\Style\SymfonyStyle class. Each of these methods define
only one parameter $message. A single string or an array of messages can be supplied for
$message. These methods make an internal method call to the block method.
Command Output 108
9.5.8 text
The text method accepts either an single string or an array of messages. It writes each message
to the console without any special formatting. Multiple messages will be written on their own
line.
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->output->text([
8 'Message One',
9 'Message Two'
10 ]);
11 }
12
13 // ...
1 Message One
2 Message Two
9.5.9 comment
The comment method is very similar to the text method. The only difference is that the comment
method will prefix each message with ‘ // ‘. The following examples demonstrate its usage:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->output->comment([
8 'Comment One',
9 'Comment Two'
10 ]);
11 }
12
13 // ...
1 // Comment One
2 // Comment Two
9.5.10 success
The success method will generate a block message with the given message or messages. On
supported systems the block’s background will be green and the foreground color will be black.
The rendered block will have the [OK] block type.
The following code sample:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->output->success([
8 'Success Message Header',
9 'More details about the message.'
10 ]);
11 }
12
13 // ...
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->output->error([
8 'Error Message Header',
9 'More details about the message.'
10 ]);
11 }
12
13 // ...
The warning method is identical to the error method. Each method produces the same block
styling. The only difference is that the warning method produces a block with the [WARNING]
block type. The following example:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->output->warning([
8 'Warning Message Header',
9 'More details about the message.'
10 ]);
11 }
12
13 // ...
9.5.12 note
The note message will generate a block message the given message or messages. On supported
systems the block’s background will inherit the consoles default background color (typically
white). The foreground, or text color, will be yellow. The rendered block will have the [NOTE]
block type as well as the ! prefix.
The following code sample:
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->output->note([
8 'Noteworthy Message Header',
9 'More details about the message.'
10 ]);
11 }
12
13 // ...
9.5.13 caution
The caution method will generate a block message that combines aspects of many of the
previous block methods. On supported systems the block’s background will be red and the
foreground color will be white. The rendered block will have the [CAUTION] block type and
the ! prefix.
The following code sample:
Command Output 112
1 <?php
2
3 // ...
4
5 function handle()
6 {
7 $this->output->caution([
8 'Cautionary Message Header',
9 'More details about the message.'
10 ]);
11 }
12
13 // ...
“Science makes people reach selflessly for truth and objectivity; it teaches people to accept
reality, with wonder and admiration, not to mention the deep awe and joy that the natural order
of things brings to the true scientist.”
– Lise Meitner (1878 - 1968), Physicist
Laravel has a number of helper functions that will make developing applications even easier.
Most of them are utility based, such as determining if an array has an item, or if a string
starts with a particular string or character. All functions will be organized by category and then
grouped by their behavior. Functions that do not have a logical grouping will then appear in the
order they appear in when viewing the helper files.
10. String Helper Functions
String operations in PHP often seem complicated to developers coming to the language from
other language, specifically languages that have a robust object-oriented approach to the
provided data types. Operations such as checking if a particular string contains a substring, or
if a string starts or ends with another string are not impossible, nor are they difficult, they just
appear over-complicated or obscure. Luckily for us, Laravel has an amazing collection of string
helper functions that we can use to perform some of the most common actions. The string helper
functions are kept in the static class Illuminate\Support\Str. The following functions are
not necessarily in the same order that they will appear in the class. They have been grouped
based on their functionality and purpose.
1 use Illuminate\Support\Str;
2
3 $firstString = 'my words';
4
5 // Returns `MyWords`
6 Str::studly($firstString);
7
8 // Displays 'my words'
9 echo $firstString;
10.2 ascii($value)
The ascii helper method accepts only one argument: $value. $value should always be a string,
or something that can be cast into a string. The function converts a string in the UTF-8¹ encoding
into it’s ASCII² equivalent.
This function is useful when communicating with other software platforms that require ASCII,
or when complying with protocols (such as HTTP) about how headers, or some values, need to
be formatted.
Example use:
¹http://en.wikipedia.org/wiki/UTF-8
²http://en.wikipedia.org/wiki/ASCII
114
String Helper Functions 115
1 use Illuminate\Support\Str;
2
3 // The following will output "a test string"
4 // in the ASCII encoding.
5
6 echo Str::ascii('a test string');
As of Laravel 5, the ascii function internally uses the stringy³ library. Previous
versions of Laravel have used the patchwork/utf8⁴ package.
10.3 studly($value)
Studly caps is a way of formatting text with capital letters, according to some pattern. Laravel’s
pattern is to remove the following word separators and capitalize the first letter of each word it
finds (while not affecting the case of any other letters):
Let’s take a look at a few examples to see how this would format a few example strings. The
string returned will appear above the function call as a comment. In fact, all of the function calls
below will return the string MyWords:
1 use Illuminate\Support\Str;
2
3 // MyWords
4 echo Str::studly('my words');
5
6 // MyWords
7 echo Str::studly('my words');
8
9 // MyWords
10 echo Str::studly(' my-words');
11
12 // MyWords
13 echo Str::studly(' my-words_');
³https://github.com/danielstjules/Stringy
⁴https://github.com/tchwork/utf8
String Helper Functions 116
Pascal Case
Laravel’s studly method can also be used to generate Pascal Cased style strings. Both
styles are the same as camel case with the first letter capitalized.
Because the studly method does not affect the case of any letters after the first letter, we can
arrive at output that some users might not expect. Again, the output string will appear above the
method call in a comment.
1 use Illuminate\Support\Str;
2
3 // MyWORDS
4 echo Str::studly('my-WORDS');
5
6 // MYWORDS
7 echo Str::studly('MY_WORDS');
10.3.1 studly_case($value)
The studly_case function is a shortcut to calling Str::studly. This function is declared in
the global namespace.
10.4 camel($value)
Camel casing is similar to studly case such that each word starts with a capitalized letter, with the
difference being the first character is lowercased. Like the studly method, the camel method
will not affect the casing of the rest of the word.
The following examples will all return the string myWords:
1 use Illuminate\Support\Str;
2
3 // myWords
4 echo Str::camel('my words');
5
6 // myWords
7 echo Str::camel('my-words');
8
9 // myWords
10 echo Str::camel('my_words');
11
12 // myWords
13 echo Str::camel(' my-words_');
Again, the camel function does not affect the casing of any characters after the first one.
String Helper Functions 117
1 use Illuminate\Support\Str;
2
3 // mYWORDS
4 echo Str::camel('MY WORDS');
5
6 // mywords
7 echo Str::camel('mywords');
10.4.0.1 camel_case($value)
The camel_case function is a shortcut to calling Str::camel. This function is declared in the
global namespace.
Here are a few examples with the result above the function call in comments:
1 use Illuminate\Support\Str;
2
3 // my_words
4 echo Str::snake('MyWords');
5
6 // my-words
7 echo Str::snake('MyWords', '-');
8
9 // m_y_w_o_r_d_s
10 echo Str::snake('MYWORDS');
11
12 // this is _pretty_cool
13 echo Str::snake('this_is_PrettyCool');
1 use Illuminate\Support\Str;
2
3 // //maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css
4 Str::replaceFirst(
5 'http://', '//',
6 'http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css'
7 );
8
9 // Hello, there!
10 Str::replaceFirst('there', 'Hello', 'there, there!');
1 <?php
2
3 return [
4
5 ...
6
7 'accepted' => 'The :attribute must be accepted.',
8 'array' => 'The :attribute must be an array.',
9
10 ...
11
12 ];
In the above translation lines, :attribute is a placeholder than can be replaced using the
$parameters parameter. The following code examples will demonstrate the results of using
the $parameters parameter. The results will appear above the method call as a comment.
It should be noted that the placeholder name in the $parameters parameter should not contain
the leading : character.
1 <?php
2
3 return [
4 'books' => 'There is one book.|There are :count many books.',
5 ];
String Helper Functions 120
It should be noted that pluralized strings allow for multiple messages to be stored in one
translation line. Messages are separated by the | character, and are ordered such that the message
that corresponds to the lower $number appear first and messages that appear for any higher
$number appear sequentially afterwards.
The following code examples highlight some more ways the trans_choice helper function can
be called, and ways they will mostly appear within applications:
See the section Pluralization section in the Translation chapter for more details specific to just
the pluralization syntax.
10.9 e($value)
The e function is a simple wrapper of PHP’s htmlentities function. The e function utilizes
the UTF-8 character encoding. The e function will sanitize user input when displaying it to the
browser.
Let’s assume that a malicious user was posting on a forum and set the subject of their post to
this:
1 <script>alert("hello everyone");</script>
If the forum software did not sanitize user output, perfectly valid JavaScript code would be
sent to the browser. Since browsers are overly happy to execute any JavaScript included in the
document, any forum visitor would see an alert box with hello everyone every time a page
was loaded that displayed that particular forum post.
To prevent this, use the e function to sanitize user input when sending it to the browser:
String Helper Functions 121
1 <script>alert("hello everyone");</script>gt;
At this point the browser will render a string that literally represents what they had typed.
11. Array Helper Functions
Laravel provides many helper functions for interacting and manipulating array data structures.
Laravel’s array functions offer additional functionality on top of PHP’s built in array functions.
The helper functions in this section are located within the Illuminate\Support\Arr static
class. There are functions defined in the static class that have counterparts defined in the global
namespace. These functions appear below each static function.
1 use Illuminate\Support\Arr;
2
3 $originalArray = [
4 'fruit' => 'orange',
5 'vegetable' => 'carrot'
6 ];
7
8 $anotherArray = array_add($originalArray, 'vehicle', 'car');
1 array(2) {
2 ["fruit"] "orange"
3 ["vegetable"] "carrot"
4 }
This is because Laravel’s functions do not affect the original array (unless stated otherwise).
Running var_dump on $anotherArray, however, would produce the expected results:
122
Array Helper Functions 123
1 array(3) {
2 ["fruit"] "orange"
3 ["vegetable"] "carrot"
4 ["vehicle"] "car"
5 }
1 forms = document.forms;
1 use Illuminate\Support\Arr;
2
3 // Create a multi-dimensional array, to simulate a document and forms.
4 $testDocument = [
5 'document' => [
6 'forms' => [
7
8 ]
9 ]
10 ];
11
12 // Get the forms.
13 $forms = Arr::get($testDocument, 'document.forms');
14
15 // Traditionally, with vanilla PHP:
16 $forms = $testDocument['document']['forms'];
Using dot notation with Laravel’s functions will be explored in more detail in the following
sections.
1 use Illuminate\Support\Arr;
2
3 $myArray = [
4 'animal' => 'Araripe Manakin',
5 'plant' => 'Pineland Wild Petunia'
6 ];
7
8 $myArray = Arr::add($myArray, 'insect', 'Extatosoma Tiaratum');
1 array(3) {
2 ["animal"] "Araripe Manakin"
3 ["plant"] "Pineland Wild Petunia"
4 ["insect"] "Extatosoma Tiaratum"
5 }
1 $anArray = [
2 'nested_array_one' => [
3 'nested_array_two' => [
4 'key' => 'value'
5 ]
6 ]
7 ];
1 use Illuminate\Support\Arr;
2
3 $value = Arr::get($anArray, 'nested_array_one.nested_array_two.key');
1 $value = $anArray['nested_array_one']['nested_array_two']['key'];
While PHP’s array access syntax may be a little shorter, using the dot notation is easier to read.
We can also specify a $default value, which will be returned if there is no matching $key found
in the array.
1 use Illuminate\Support\Arr;
2
3 $value = Arr::get(
4 $anArray,
5 'nested_array_one.nested_array_two.does_not_exist',
6 'default value'
7 );
$value would then have the value of default value. Using this method is shorter than using
PHP’s array access syntax and the isset function, where we would have to check at each level
if the key exists or not.
Mutable Function
This function affects the original $array.
Consider the following array, which is probably familiar to most people these days:
Array Helper Functions 126
1 $weekDays = [
2 1 => 'Sunday',
3 2 => 'Monday',
4 3 => 'Tuesday',
5 4 => 'Wednesday',
6 5 => 'Thursday',
7 6 => 'Friday',
8 7 => 'Saturday'
9 ];
A lot of people do not like Mondays. Let’s demote Monday to the $theWorstDayOfTheWeek
while also removing it from our $weekDays:
1 use Illuminate\Support\Arr;
2
3 // Demote 'Monday'
4 $worstDayOfTheWeek = Arr::pull($weekDays, 2);
1 array(6) {
2 [1] "Sunday"
3 [3] "Tuesday"
4 [4] "Wednesday"
5 [5] "Thursday"
6 [6] "Friday"
7 [7] "Saturday"
8 }
The app function can also be used to resolve registered dependencies from the Container
instance. For example, to return an instance of the Illuminate\Auth\AuthManager class (the
class behind the Auth facade), invoke app with the auth argument:
The following example shows to equivalent ways of retrieving the currently logged in user:
1 use Illuminate\Support\Facades\Auth;
2
3 // Get the current user using the `Auth` facade.
4 $currentUser = Auth::user();
5
6 // Get the current user using the `auth` helper.
7 $currentUser = auth()->user();
You can quickly access any custom authentication guards by supplying an argument for the
$guard parameter. For example if a custom guard was added with the name customGuard:
127
Application and User Flow Helper Functions 128
1 if (auth('customGuard')->attempt([
2 'email' => $email,
3 'password' => $password
4 ])) {
5 // Authentication passed.
6 }
When $guard is set to null, the AuthManager instance will internally set $guard equal to the
value of the auth.defaults.guard configuration key (by default this is web). The following
code samples would produce the same results:
12.3 policy($class)
The policy helper function can be used to retrieve a policy (a policy class can be any valid
PHP class) instance for a given $class. The $class can be either a string or an object instance.
If no policies for the given $class have been registered with the application an instance of
InvalidArgumentException will be thrown.
1 /**
2 * The following code is simply creating a new event class
3 * to signal that a video was watched.
4 */
5
6 namespace App\Events;
7
8 use App\Video;
9 use App\Events\Event;
10 use Illuminate\Queue\SerializesModels;
11
12 class VideoWasWatched extends Event
13 {
14 use SerializesModels;
15
16 public $video;
17
18 /**
19 * Create a new event instance.
20 *
21 * @param Video $video
22 * @return void
23 */
24 public function __construct(Video $video)
25 {
26 $this->video = $video;
27 }
28 }
1 event('\App\Events\VideoWasWatched', $video);
Alternatively, an event can be fired by instantiating a new instance of the event class itself:
1 event(new VideoWasWatched($video));
In the above example, a $payloadwas not supplied. This is because the event instance itself will
become the payload. It is equivalent to the following:
12.5 dispatch($command)
The dispatch helper function can be used to push a new job onto the job queue (or dispatch the
job). The function resolves the configured Illuminate\Contracts\Bus\Dispatcher imple-
mentation from the Service Container and then calls the dispatch method in the Dispatcher
instance.
Assuming a variable $job exists that contains a valid queueable Job the following examples are
all equivalent:
1 use Illuminate\Contracts\Bus\Dispatcher;
2 use Illuminate\Support\Facades\Bus;
3
4 dispatch($job);
5 app(Dispatcher::class)->dispatch($job);
6 Bus::dispatch($job);
12.6 factory()
The factory function is used to create Eloquent models, generally used when testing an
application. The factory method can generally take one of four forms:
12.7 method_field($method)
The method_field helper function is a simple function that returns a new instance of
Illuminate\Support\HtmlString. The contents of the HtmlString instance is a hidden
HTML input field with the name _method and the a value of $method.
The following example highlights the results of the method_field function:
Application and User Flow Helper Functions 131
1 method_field('PUT');
2 method_field('POST');
3 method_field('GET');
4 method_field('PATCH');
5 method_field('DELETE');
The return value of the method_field function is an instance of HtmlString. The correspond-
ing HTML string value for each function call above would be:
The validator helper function is a versatile helper function. If no arguments are supplied
to the validator function (all arguments are optional), the function will return a Illumi-
nate\Contracts\Validation\Factory implementation instance (the default implementa-
tion will be an instance of Illuminate\Validation\Factory).
Using the the validator function without arguments and gaining access to the instance
methods is essentially the same as using the Illuminate\Support\Facades\Validator
facade. The following examples are equivalent; all the examples will make use of the request
helper function.
1 use Illuminate\Support\Facades\Validator;
2
3 // Using the Validator facade.
4 $validator = Validator::make(request()->all(), [
5 'title' => 'required|unique:posts|max:255',
6 'body' => 'required'
7 ]);
8
9 // Using the validator helper function.
10 $anotherValidator = validator()->make(request()->all(), [
11 'title' => 'required|unique:posts|max:255',
12 'body' => 'required'
13 ]);
The second example above can be shortened even further. You can supply the arguments for the
make instance method directly to the validator helper function. When you supply arguments
to the validator helper function it will call and return the value of the make instance method:
Application and User Flow Helper Functions 132
1 $validator = validator(request()->all, [
2 'title' => 'required|unique:posts|max:255',
3 'body' => 'required'
4 ]);
13. Configuration, Environment,
Security and Logging Helper
Functions
13.1 bcrypt($value, $options = [])
The bcrypt function will return a hashed representation of the given $value. The bcrypt
function also accepts an array of $options which can be used to affect how the hash is
computed. Each invocation of the bcrypt function should produce a different result, even if
the input remains the same.
The following example demonstrates how to call the bcrypt function:
1 $2y$10$6b8WZt.Ugwnjjb3JZQH51ecaG.VSjOOO2xCZ3t4s/MGGHU112hhD2
2 $2y$10$o/uJXcnrNDQraGgk1.VG9.LwssnANCyOEO8tCuiL5RlO33CpGo.Lq
3 $2y$10$7qWDkO43obCCN4hpNDt2Hut2xbg8xmKQHzZF/m4EdsGUHApXcKLyi
4 $2y$10$e4srCMoCOaIl9qd2wuk.8e2pBGTxaAu/bDi2CrNlRcNyXxvtYePIy
5 $2y$10$1MhsM.KaYpwoODuoBi7wmO6jUrMJ0xGaigL6/JMKAgb48CgyFz8tK
6 $2y$10$wTdq3XAG7/UKT0aO4u9lO.ZRcDiaF5p4fXMViticodID9oC/CTsJO
7 $2y$10$yHwchZ9HCKZjfnqqulQ7eu61noEwIVZBXKwSZ8.rvYyk9p0SXFNKG
8 $2y$10$5XvPyJE9EQ6DpOdYzM.NYeR4eDjAzntn2ogytDh1tNU4ebWrHaYvS
9 $2y$10$V1yb7D7rqqUL7BZkR2c3HOjYHvVB/lRg5cvrL/Hl/KYzrKrTV/tvC
10 $2y$10$6DAP/IjDTOH3iezOzx/CyuH37ZEDtc6.ADkDEfJUUn/msgUGe5A4S
133
Configuration, Environment, Security and Logging Helper Functions 134
bcrypt Options
Option Description
rounds Determines how many iterations the bcrypt function will internally
use.
13.1.1.1 rounds
The rounds option is used to control how many iterations the underlying Blowfish implemen-
tation will use when generating the final hash. The rounds value can be any positive integer
between 4 and 31 (including both 4 and 31). If an integer outside the stated range is supplied
an ErrorException will be thrown. The rounds option is synonymous with the cost option
when using PHP’s password_hash or crypt functions. Increasing the rounds will also increase
the time required to compute the hash. The default value for this option is 10.
The number of iterations that will be used can be determined with the following equation:
iterations = 2rounds
Calling bcrypt with the rounds option set to 10 will use 21 0 or 1024 iterations.
13.2 encrypt($value)
The encrypt helper function can be used to encrypt a given $value. The function resolves
the configured Illuminate\Contracts\Encryption\Encrypter implementation from the
Service Container and then calls the encrypt method on the Encrypter instance.
The following examples are all equivalent:
Configuration, Environment, Security and Logging Helper Functions 135
1 use Illuminate\Support\Facades\Crypt;
2
3 // Encrypt using the Crypt facade:
4 Crypt::encrypt('Hello, Universe');
5
6 // Encrypt using the encrypt helper:
7 encrypt('Hello, Universe');
For more information on the encrypt instance method, see the “Encryption: Encrypting and
Decrypting Data” chapter.
The above code would produce results similar to the following (some lines have been indented
to prevent wrapping and improve readability):
1 ...
2 [2015-06-15 02:14:43] local.INFO: This is a log message without context
3 [2015-06-15 02:14:43] local.INFO: This is a log message
4 {"name":"John Doe","email":"you@homestead"}
5 [2015-06-15 02:14:43] local.INFO: This is another log message
6 [
7 "[object] (stdClass: {\"name\":\"John Doe\",\"email\":\"you@homestead\"})"
8 ]
9 ...
14. URL Generation Helper
Functions
14.1 action($name, $parameters = [], $absolute =
true)
The action helper function can be used to generate a URL to a controller action, which is
supplied as an argument to the $name parameter. If the controller action requires or accepts
parameters these can be supplied by utilizing the $parameters parameter.
The following examples will use the following example controller (stored in app/Http/Con-
trollers/ExampleController.php):
1 <?php
2
3 namespace App\Http\Controllers;
4
5 class ExampleController extends Controller {
6
7 public function sayHello($name) {
8 return "Hello, {$name}!";
9 }
10
11 }
as well as the following route definition (added to the web middleware group in app/Htp-
p/routes.php):
1 Route::get('sayHello/{name}', 'ExampleController@sayHello');
1 http://laravel.artisan/sayHello/Jim
The exact URL that is generated will depend on the current domain of the site.
Notice that when the action function was called, we did not need to include the root namespace
of the controller (App\Http\Controllers). Laravel will automatically add the namespace for
you. Any namespaces that are not part of the root namespace must be included (such as Auth),
however.
136
URL Generation Helper Functions 137
1 /sayHello/Jim
15. Miscellaneous Helper Functions
15.1 dd()
The dd function is a debug utility that will dump a set of values and then die. This means it will
create a human-readable representation of the values and then stop execution of the script.
The dd function will take into account if the application is currently running in the console, or if
it is returning a response to a client (such as a browser), and then update it’s output accordingly.
15.3 windows_os
The windows_os helper function can be used to determine if the host server is running a
Microsoft Windows® operating system. The function returns either true—if the server is
running Windows®—or false—if the server is not running Windows®.
Using this function you can write code like so:
1 <?php
2
3 if (windows_os()) {
4 // Windows® specific commands or instructions.
5 } else {
6 // Anything that is not Windows®.
7 }
138
Miscellaneous Helper Functions 139
1 <?php
2
3 if (strtolower(substr(PHP_OS, 0, 3)) === 'win') {
4 // Windows® specific commands or instructions.
5 } else {
6 // Anything that is not Windows®.
7 }
The tap helper function was added in Laravel version 5.3 and defined in the
src/Illuminate/Support/helpers.php file. This function can easily be integrated
into older Laravel code bases as it does not depend on any new fundamental framework
components.
The following example PHP classes will be used to demonstrate a trivial usage of the tap helper
function. The classes represent a crude “talker” system where one can add messages and retrieve
the final message back:
Stored in the app/Message.php file:
1 <?php
2
3 namespace App;
4
5 class Message
6 {
7
8 /**
9 * The actual message.
10 *
11 * @var string
12 */
13 protected $message = '';
14
15 /**
16 * Gets the original message.
Miscellaneous Helper Functions 140
17 *
18 * @return string
19 */
20 public function getOriginal()
21 {
22 return $this->message;
23 }
24
25 /**
26 * Changes the message.
27 *
28 * @param $message
29 * @return Message
30 */
31 public function change($message)
32 {
33 $this->message = $message;
34
35 return $this;
36 }
37
38 public function __toString()
39 {
40 return strtolower($this->message);
41 }
42
43 }
The Message class if fairly simple. It is simply a value object that wraps PHP’s native string data
type. It provides a few methods that can be used to retrieve the original value and change (mutate)
the internal value of the message. When the message is cast back to a string it is converted to its
lowercased variant. The important thing to notice is that the change method returns a reference
back to itself.
Stored in the app/Talker.php file:
1 <?php
2
3 namespace App;
4
5 class Talker
6 {
7
8 /**
9 * The actual parts of the message.
10 *
Miscellaneous Helper Functions 141
11 * @var array
12 */
13 protected $messageParts = [];
14
15 /**
16 * Adds a message part to the end of the message.
17 *
18 * @param $message
19 * @return Message
20 */
21 public function atEnd(Message $message)
22 {
23 array_push($this->messageParts, $message);
24 return $message;
25 }
26
27 /**
28 * Adds a message part to the start of the message.
29 *
30 * @param $message
31 * @return Message
32 */
33 public function atBeginning(Message $message)
34 {
35 array_unshift($this->messageParts, $message);
36 return $message;
37 }
38
39 /**
40 * Returns the string representation of the message.
41 *
42 * @return string
43 */
44 public function talk()
45 {
46 return ucfirst(implode(' ', $this->messageParts));
47 }
48
49 }
The Talker class is also very simple. It maintains an array of Message instances and allows you
to add them to either the beginning or ending of the array of messages. In addition, it allows you
to retrieve a string made up of all the individual messages with the first character upper cased.
Annoyingly the atEnd and atBeginning methods return the Message instance instead of the
Talker instance, which makes chaining rather difficult.
The following example will create a simple helper function to remove some of the steps of using
Miscellaneous Helper Functions 142
1 <?php
2
3 use App\Talker;
4 use App\Message;
5
6 /**
7 * Say something.
8 *
9 * string $message
10 * @return string
11 */
12 function saySomething($message) {
13 $talker = new Talker;
14 $talker->atBeginning(new Message)->change($message);
15 return $talker->talk();
16 }
1 <?php
2
3 echo saySomething('Hello World');
1 Hello world
It would be nice if we could return the value of the method chain from our function like so:
1 <?php
2
3 // ...
4
5 function saySomething($message) {
6 $talker = new Talker;
7 return $talker->atBeginning(new Message)->change($message)->talk();
8 }
9
10 // ...
However, that code would not work. This is because the atBeginning method on the Talker
class returns an instance of Message. The talk method does not exist on the Message class, and
if it did would probably not have the same behavior as the Talker instance method. We can use
the tap function to get around this quite easily:
Miscellaneous Helper Functions 143
1 <?php
2
3 // ...
4
5 function saySomething($message) {
6 $talker = new Talker;
7 return tap($talker, function($t) use ($message) {
8 $t->atBeginning(new Message)->change($message);
9 })->talk();
10 }
11
12 // ...
In the above example we are using the tap function to keep our method chain going. In addition
we are passing the $message parameter into the inner callback function so that we can use it.
The above example could actually be simplified further by using the with helper function to
return a new instance of Talker:
1 <?php
2
3 // ...
4
5 function saySomething($message) {
6 return tap(with(new Talker), function($t) use ($message) {
7 $t->atBeginning(new Message)->change($message);
8 })->talk();
9 }
Miscellaneous Helper Functions 144
10
11 // ...
The previous example is very contrived but does demonstrate a fairly basic use of the tap
helper function. More common use cases might be when passing around Eloquent models with
extensive method chaining.
The following example will make use of the Eloquent model factory builder to create a new
instance, modify an attribute, save the model and then return the created model instance:
1 <?php
2
3 use App\User;
4
5 $user = tap(factory(User::class)->make(), function($user) {
6 $user->setAttribute('name', 'No such a random name')
7 ->save();
8 });
After the above example has executed, the attributes of the $user model instance might look
similar to the following output:
1 array [
2 "name" => "No such a random name"
3 "email" => "Batz.Bridget@example.com"
4 "password" => "$2y$10$aXsXCEx3pkgmNcWpJFkAE.AMHoyk3o8XC6Kth3..."
5 "remember_token" => "nayR2BKwaQ"
6 "updated_at" => "2016-06-03 22:29:01"
7 "created_at" => "2016-06-03 22:29:01"
8 "id" => 7
9 ]
The actual attribute values will differ as they are randomly assigned a value from the model
factory. Because of the way we used the tap helper function we were able to modify the name
attribute elegantly, save the model and get the exact return value we wanted.
Collections
“I was told I’d never make it to VP rank because I was too outspoken. Maybe so, but I think men
will always find an excuse for keeping women in their ‘place.’ So, let’s make that place the
executive suite and start more of our own companies.”
– Jean Bartik (1924 - 2011), Computer Programmer
After the above code executes, the variable $someValue would hold the value Some value.
It should be noted that even though array syntax works with collections, PHP’s array specific
functions will not work on an instance of a collection directly. Instead we have to retrieve the
underlying array from the collection.
The following code will throw an instance of ErrorException stating that array_values
expects the first parameter to be an object:
¹http://php.net/manual/en/class.arrayaccess.php
146
Basic Usage - Collections as Arrays 147
1 use Illuminate\Support\Collection;
2
3 $collection = new Collection;
4 $collection[] = 'First';
5 $collection[] = 'Second';
6 $collection[] = 'Third';
7
8 $values = array_values($collection);
Instead, the toArray method can be used to retrieve a representation of the underlying array:
1 use Illuminate\Support\Collection;
2
3 $collection = new Collection;
4 $collection[] = 'First';
5 $collection[] = 'Second';
6 $collection[] = 'Third';
7
8 $values = array_values($collection->toArray());
After the above code executes, $values would contain a value similar to the following:
1 array (size=3)
2 0 => string 'First' (length=5)
3 1 => string 'Second' (length=6)
4 2 => string 'Third' (length=5)
1 use Illuminate\Support\Collection;
2
3 $collection = new Collection;
4
5 $value = $collection['does_not_exist'];
Interacting with collections in this manner should be relatively uncommon in practice. The
Collection class provides many methods that aid developers in such situations. As an example,
the get method allows retrieval of data from the collection, with the option of returning a default
value:
Basic Usage - Collections as Arrays 148
1 use Illuminate\Support\Collection;
2
3 $collection = new Collection;
4
5 $value = $collection->get('does_not_exist', 'But I do');
After the above code is executed the $value variable would have the value But I do, and
the code will not throw an exception. The chapter Collections: The Public API contains more
information about the public methods available.
1 use Illuminate\Support\Collection;
2
3 // An array of test data.
4 $testData = [
5 'first' => 'This is the first',
6 'second' => 'This is the second',
7 'third' => 'This is third'
8 ];
9
10 // Create a new collection instance.
11 $collection = new Collection($testData);
Another way to create a Collection instance is to call the static make method on the
Collection class itself:
1 use Illuminate\Support\Collection;
2
3 // An array of test data.
4 $testData = [
5 'first' => 'This is the first',
6 'second' => 'This is the second',
7 'third' => 'This is third'
8 ];
9
10 // Create a new collection instance static 'make' method.
11 $collection = Collection::make($testData);
A convenient way to create a new Collection instance is to use the collect helper function.
The collect helper function internally returns a new instance of Collection passing in any
arguments to the class’s constructor. It’s most basic usage is:
Basic Usage - Collections as Arrays 149
17.1 all
The all method can be used to retrieve the underlying array that the collection is using to hold
its data. The following code demonstrates the usage of the all method:
1 use Illuminate\Support\Collection;
2
3 $items = [
4 'first' => 'I am first',
5 'second' => 'I am second'
6 ];
7
8 $collection = Collection::make($items);
9
10 $returnedItems = $collection->all();
After the above code has been executed, the $returnedItems variable would hold the following
value:
1 array (size=2)
2 'first' => string 'I am first' (length=10)
3 'second' => string 'I am second' (length=11)
We can also verify that the two arrays are indeed equal:
1 // true
2 $areEqual = $items === $returnedItems;
It should also be noted that the all method will preserve any nested collections:
¹http://php.net/manual/en/class.arrayaccess.php
²http://php.net/manual/en/class.iteratoraggregate.php
150
Collections: The Public API 151
1 use Illuminate\Support\Collection;
2
3 $items = [
4 'first' => 'I am first',
5 'second' => 'I am second',
6 'third' => new Collection([
7 'first' => 'I am nested'
8 ])
9 ];
10
11 $collection = Collection::make($items);
12
13 $returnedItems = $collection->all();
At this point, the $returnedItems variable would a value similar to the following:
1 array (size=3)
2 'first' => string 'I am first' (length=10)
3 'second' => string 'I am second' (length=11)
4 'third' =>
5 object(Illuminate\Support\Collection)[132]
6 protected 'items' =>
7 array (size=1)
8 'first' => string 'I am nested' (length=11)
To return an array, and have any nested collections converted to arrays, see the toArray method.
17.2 toArray
The toArray method is similar to the all method in that it will return the underlying array
that the collection instance is using. The difference, however, is that the toArray method
will convert any object instance it can into arrays (namely any object that implements the
Illuminate\Contracts\Support\Arrayable interface). Consider the following code:
1 use Illuminate\Support\Collection;
2
3 $items = [
4 'first' => 'I am first',
5 'second' => 'I am second',
6 'third' => new Collection([
7 'first' => 'I am nested'
8 ])
9 ];
10
Collections: The Public API 152
11 $collection = Collection::make($items);
12
13 $returnedItems = $collection->toArray();
After the above code has executed, the $returnedItems variable would contain a value similar
to the following output:
1 array (size = 3)
2 'first' => string 'I am first' (length=10)
3 'second' => string 'I am second' (length=11)
4 'third' =>
5 array (size=1)
6 'first' => string 'I am nested' (length=11)
1 $testArray = [
2 'one' => '1',
3 'two' => '2',
4 'three' => '3',
5 'four' => '4',
6 'five' => '5',
7 'six' => '6'
8 ];
9
10 $collection = new Collection($testArray);
11
12 $chunks = $collection->chunk(3);
1 object(Illuminate\Support\Collection)[135]
2 protected 'items' =>
3 array (size=2)
4 0 =>
5 object(Illuminate\Support\Collection)[133]
6 protected 'items' =>
7 array (size=3)
8 0 => string '1' (length=1)
9 1 => string '2' (length=1)
10 2 => string '3' (length=1)
11 1 =>
12 object(Illuminate\Support\Collection)[134]
13 protected 'items' =>
14 array (size=3)
15 0 => string '4' (length=1)
16 1 => string '5' (length=1)
17 2 => string '6' (length=1)
As you can see, the chunk method returned a new collection that contains two new collections,
each containing three elements. It should also be noted that the original array keys are missing
(there are no numerical word names). This can be changed by passing true as the second
argument:
Now the $chunks variable would have a value similar to the following:
1 object(Illuminate\Support\Collection)[135]
2 protected 'items' =>
3 array (size=2)
4 0 =>
5 object(Illuminate\Support\Collection)[133]
6 protected 'items' =>
7 array (size=3)
8 'one' => string '1' (length=1)
9 'two' => string '2' (length=1)
10 'three' => string '3' (length=1)
11 1 =>
12 object(Illuminate\Support\Collection)[134]
13 protected 'items' =>
14 array (size=3)
15 'four' => string '4' (length=1)
16 'five' => string '5' (length=1)
17 'six' => string '6' (length=1)
17.4 only($keys)
The only method is the logical opposite of the except method. The only method is used to
return all the key/value pairs in the collection where the keys in the collection are in the supplied
$keys array. Internally, this method makes a call to the Illuminate\Support\Arr::only($array,
$keys) helper function.
Using the same example from the except method section, we can get only the first_name and
last_name of the users in a collection:
After the above code has executed, the $data variable would contain a value similar to the
following output:
1 Collection {
2 #items: array:2 [
3 "first_name" => "John"
4 "last_name" => "Doe"
5 ]
6 }
17.5 keyBy($keyBy)
The keyBy method is used to create a new Collection instance where the keys of the new
key/value pairs are determined by a $keyBy callback function (a string value can also be
supplied instead of a function). The signature of the callback function is keyBy($item), where
the $item is the actual item in the collection. This method does not change the original
Collection instance will will return a new, modified, Collection instance.
In the following example, we will create a new collection instance where the key of each item is
the persons id. We will not supply a callback function in this example, but rather pass the name
of the value we want to use as the key as as string:
1 $results = $people->keyBy('id');
After the above code has executed, the $results variable will contain a value similar to the
following output:
1 Collection {
2 #items: array:3 [
3 12 => array:3 [
4 "id" => 12
5 "name" => "Alice"
6 "age" => 26
7 ]
8 52 => array:3 [
9 "id" => 52
10 "name" => "Bob"
11 "age" => 34
12 ]
13 14 => array:3 [
14 "id" => 14
15 "name" => "Chris"
16 "age" => 26
17 ]
18 ]
19 }
We can also achieve the exact same results by using a callback function like so:
1 $results = $people->keyBy(function($item) {
2 return $item['id'];
3 });
However, the above example is overly complicated if all we were interested in was just the id
of the person. We could do something a little more interesting, such as returning a simple hash
of each persons id to use as the new key:
Collections: The Public API 156
1 $results = $people->keyBy(function($item) {
2 return md5($item['id']);
3 });
After the above code has executed, the new $results variable would contain a value similar to
the following output:
1 Collection {
2 #items: array:3 [
3 "c20ad4d76fe97759aa27a0c99bff6710" => array:3 [
4 "id" => 12
5 "name" => "Alice"
6 "age" => 26
7 ]
8 "9a1158154dfa42caddbd0694a4e9bdc8" => array:3 [
9 "id" => 52
10 "name" => "Bob"
11 "age" => 34
12 ]
13 "aab3238922bcc25a6f606eb525ffdc56" => array:3 [
14 "id" => 14
15 "name" => "Chris"
16 "age" => 26
17 ]
18 ]
19 }
The same method could just as easily be applied to other hashing libraries, such as the
hashids.php³ library.
³https://github.com/ivanakimov/hashids.php
18. Message Bags
The Illuminate\Suport\MessageBag class is an elaborate key/value storage system for
storing different types of messages. It it also allows developers to specify a format which is
used when returning the messages. The format makes it incredibly simple to format mes-
sages on HTML forms, emails, etc. The MessageBag class implements both the Illumi-
nate\Contracts\Support\MessageProvider and Illuminate\Contracts\Support\MessageBag
interfaces.
18.1 Illuminate\Contracts\Support\MessageProvider
Interface
The MessageProvider interface defines only one method, getMessageBag. The expected
behavior of the getMessageBag method is to return an instance of an implementation of
the Illuminate\Contracts\Support\MessageBag interface. Any class that implements the
MessageProvider interface can be expected to be capable of returning MessageBag implemen-
tations.
The following classes extend, implement, or make use of the MessageProvider interface by
default:
Class Description
Illuminate\Contracts\Validation\ The ValidationException is often
ValidationException thrown when a validation error occurs
by some process within an
applications request life-cycle.
Illuminate\Contracts\Validation\ The Validator interface defines the
Validation methods and behaviors of the
frameworks validator component. The
Validator component actually
extends the MessageProvider
interface.
Illuminate\Http\RedirectResponse The RedirectReponse class is
responsible for setting the correct
headers required to redirect a user’s
browser to another URL.
IlluminateSupportMessageBag The MessageBag class is the default
implementation of the
Illuminate\Contracts\Support\MessageBag
interface. It also implements the
MessageProvider interface to return
a reference to itself.
157
Message Bags 158
Class Description
Illuminate\View\View The View class uses instances of
MessageProvider implementations
to facilitate the communication of
errors between the application logic
and the front-end code of an
application.
An instance of ViewErrorBag is shared with views if the current request contains any errors.
This functionality is facilitated by the Illuminate\View\Middleware\ShareErrorsFromSession
middleware. The ViewErrorBag instance that is shared with views is given the name errors.
Interacting with the ViewErrorBag instance should look familiar to most developers:
1 @if($errors->count())
2 <div class="alert alert-danger">
3 <p>There were some errors that need to be fixed!</p>
4 <ul>
5 {!! implode($errors->all('<li>:message</li>')) !!}
6 </ul>
7 </div>
8 @endif
The following examples will assume that a form exists that asks a user for their username and
a secret. The form will be validated from a controller using the following code sample (in this
case there is no response when validation was successful):
1 $this->validate($request, [
2 'username' => 'required|max:200',
3 'secret' => 'required'
4 ]);
If a user supplied only the username, the above Blade template code would generate the
following HTML:
Message Bags 159
If the user did not supply either a username or a secret, the following HTML code would have
been generated:
1 use Illuminate\Support\ViewErrorBag;
2
3 // Create a new ViewErrorBag instance.
4 $viewErrorBag = new ViewErrorBag;
5
6 // Determine if the default MessageBag
7 // instance is empty, which in this case
8 // is true.
9 $viewErrorBag->isEmpty();
18.2.1.1 count
The count method returns the number of messages stored within the default MessageBag
instance. It is also the only MessageBag method that specifically handled by the ViewErrorBag
instance itself because it needs to be declared within the ViewErrorBag class itself to satisfy the
requirements of PHP’s Countable¹ interface.
The following code example demonstrates the behavior of the count method:
¹http://php.net/manual/en/class.countable.php
Message Bags 160
1 use Illuminate\Support\ViewErrorBag;
2 use Illuminate\Support\MessageBag;
3
4 // Create a new ViewErrorBag instance.
5 $viewErrorBag = new ViewErrorBag;
6
7 // Create a new MessageBag instance.
8 $messageBag = new MessageBag([
9 'username' => [
10 'The username is required.'
11 ]
12 ]);
13
14 // Add the new MessageBag instance to
15 // the ViewErrorBag
16 $viewErrorBag->put('formErrors', $messageBag);
17
18 // Get the count from $viewErrorBag
19 //
20 // 0
21 $messageCount = $viewErrorBag->count();
22
23 // Change the 'default' MessageBag to the one
24 // created earlier.
25 $viewErrorBag->put('default', $messageBag);
26
27 // Get the count from $viewErrorBag
28 //
29 // 1
30 $messageCount = count($viewErrorBag);
As can be seen in the comments in the above example, the count method only operates on the
default MessageBag instance. Because of this adding the MessageBag formErrors did not
affect the count, but setting the same MessageBag instance as the value for the default key did
change the results of the count method.
The getBag method can be used to retrieve a MessageBag instance associated with the provided
$key. If a MessageBag instance does not exist with the provided $key, a new instance of
Illuminate\Support\MessageBag will returned instead.
The following code sample will demonstrate the usage of the getBag method. It also shows that
because of the way PHP internally handles objects and references, that the $messageBag is the
same as the value returned from the getBag method.
Message Bags 161
1 use Illuminate\Support\ViewErrorBag;
2 use Illuminate\Support\MessageBag;
3
4 // Create a new ViewErrorBag instance.
5 $viewErrorBag = new ViewErrorBag;
6
7 // Create a new MessageBag instance.
8 $messageBag = new MessageBag([
9 'username' => [
10 'The username is required.'
11 ]
12 ]);
13
14 $viewErrorBag->put('formErrors', $messageBag);
15
16 // Demonstrate that the object returned by the getBag
17 // method is the same as $messageBag.
18 //
19 // true
20 $areTheSame = $messageBag === $viewErrorBag->getBag('formErrors');
Additionally, you can request a MessageBag instance with any $key, even if they have not been
set:
It should be noted that the getBag method does not set the MessageBag instance that is
returning. This behavior can lead to some confusion, and can be observed in the following code
sample:
1 $messageBagInstance = $viewErrorBag->getBag('paymentErrors');
2
3 // Add a message to the $messageBagInstance
4 $messageBagInstance->add('ccn', 'The credit card number is invalid');
5
6 // Get the number of messages.
7 //
8 // 1
9 $messageCount = $messageBagInstance->count();
10
11 // Get the number of messages.
12 //
13 // 0
14 $messageCount = $viewErrorBag->getBag('paymentErrors')->count();
Message Bags 162
If the ViewErrorBag instance had set the MessageBag instance before returning it from the
getBag method, both $messageCount variables would have contained the value 1.
Another way to retrieve MessageBag instances from the ViewErrorBag instance is dynamically
access a property, where the property name is the intended key. This technique exhibits the same
behavior as using the getBag method.
18.2.1.3 getBags
The getBags method is used to return an associative array containing all the MessageBag
instances that are currently stored within the ViewErrorBag instance.
1 use Illuminate\Support\ViewErrorBag;
2 use Illuminate\Support\MessageBag;
3
4 // Create a new ViewErrorBag instance.
5 $viewErrorBag = new ViewErrorBag;
6
7 // Create a new MessageBag instance.
8 $messageBag = new MessageBag([
9 'username' => [
10 'The username is required.'
11 ]
12 ]);
13
14 // Add some message bags to $viewErrorBag
15 $viewErrorBag->put('formErrors', $messageBag);
16 $viewErrorBag->put('paymentErrors', new MessageBag);
17
18 // Get the message bags as an array.
19 $messageBags = $viewErrorBag->getBags();
After the above code has executed, the $messageBags variable would be an array and contain
a value similar to the following output:
Message Bags 163
1 array (size=2)
2 'formErrors' =>
3 object(Illuminate\Support\MessageBag)[142]
4 protected 'messages' =>
5 array (size=1)
6 'username' =>
7 array (size=1)
8 ...
9 protected 'format' => string ':message' (length=8)
10 'paymentErrors' =>
11 object(Illuminate\Support\MessageBag)[143]
12 protected 'messages' =>
13 array (size=0)
14 empty
15 protected 'format' => string ':message' (length=8)
The hasBag method is used to determine if a MessageBag instance exists within the ViewEr-
rorBag instance with the given $key. The $key is set to default unless it is changed. The
following example will highlight the usage of the hasBag method.
1 use Illuminate\Support\ViewErrorBag;
2 use Illuminate\Support\MessageBag;
3
4 // Create a new ViewErrorBag instance.
5 $viewErrorBag = new ViewErrorBag;
6
7 // Check if the 'default' MessageBag instance
8 // exists.
9 //
10 // false
11 $doesExist = $viewErrorBag->hasBag();
12 $doesExist = $viewErrorBag->hasBag('default');
13
14 // Check if a 'payments' MessageBag instance
15 // exists.
16 //
17 // false
18 $doesExist = $viewErrorBag->hasBag('payments');
19
20 // Add a new 'payments' MessageBag instance.
21 $viewErrorBag->put('payments', new MessageBag);
22
23 // Check again if the 'payments' MessageBag instance
24 // exists.
Message Bags 164
25 //
26 // true
27 $doesExist = $viewErrorBag->hasBag('payments');
The put method is used to add a new MessageBag implementation instance to the ViewEr-
rorBag instance, supplied as the argument to the $bag parameter with some name determined
by the $key argument. The following code demonstrates how to add a new MessageBag instance
to a ViewErrorBag:
1 use Illuminate\Support\ViewErrorBag;
2 use Illuminate\Support\MessageBag;
3
4 // Create a new ViewErrorBag instance.
5 $viewErrorBag = new ViewErrorBag;
6
7 // Create a new MessageBag instance.
8 $messageBag = new MessageBag;
9
10 // Add the $messageBag to the $viewErrorBag
11 // with some key.
12 $viewErrorBag->put('somekey', $messageBag);
13
14 // Get the number of MessageBag instances.
15 $messageBagCount = count($viewErrorBag->getBags());
After the above code has executed, the $messageBagCount variable would contain the value 1.
Another way to add MessageBag instances to the ViewErrorBag is by dynamically setting an
instance property:
At this point, the $viewErrorBag instance would now contain two MessageBag instances with
the keys somekey and anotherKey.
Because neither ViewErrorBag or MessageBag provide a method to quickly remove all the
messages from a MessageBag instance, the put method can be used to remove all MessageBag
messages, or supply new ones, by changing the MessageBag instance for a given key:
Message Bags 165
After the above code has executed, the $beforeChange variable will contain the old Message-
Bag instance and the $afterChange variable will contain the new MessageBag instance.
1 object(Illuminate\Support\MessageBag)[142]
2 protected 'messages' =>
3 array (size=0)
4 empty
5 protected 'format' => string ':message' (length=8)
1 object(Illuminate\Support\MessageBag)[143]
2 protected 'messages' =>
3 array (size=1)
4 'username' =>
5 array (size=1)
6 0 => string 'The username is required.' (length=25)
7 protected 'format' => string ':message' (length=8)
19. Fluent
The Illuminate\Support\Fluent class is a useful data type. It allows for the construction of a
data “container” similar to an array or instance of stdClass. However, the Fluent class makes
it easier to make assumptions about the data the class instance contains. The following array and
stdClass instance will be used for the next couple of examples:
The $value variable would now contain the value The first value. Similarly, data can be
retrieved from the stdClass instance using object operator (often called the “arrow”):
Like in the previous example, the $value variable would now contain the value The first
value. There is nothing surprising going on here. However, what happens when a developer
needs to make assumptions about the data their code is working with? Uncertain developers
often litter code with unwieldy if statements and similar constructs. Failure to do so generally
results in fatal errors.
For example, attempting to retrieve data from an array that does not exist results in an instance
of ErrorException being thrown:
166
Fluent 167
The exact error message will differ between single or multi-dimensional arrays, but the principal
is the same. PHP does not like it when code attempts to access array elements that do not exist.
The same can be said for accessing an object’s properties:
The above code example will again throw an instance of ErrorException, with the error
message being something similar to “Undefined property: stdClass::$doesNotExit”. To work
around this, the following code can be written:
The above code example can be simplified using Laravel’s array and object helper
functions. Specifically see the sections on array_get, object_get and data_get.
In the above code example, we checked to see if an object instance has a value by using the
property_exists function instead of the isset function. This is because the property_-
exist function will return true if the property exists and has a value of null. The isset
function will return false if the property exists but has a value of null.
http://php.net/manual/en/function.property-exists.php
Fluent 168
http://php.net/manual/en/function.isset.php
Developers need to assume things about code quite often. In a perfect world, developers would
know exactly what data an array or object their code interacts with contains. However, when
dealing with remote data, such as data from external APIs, or when interfacing with code from
multiple development teams, this is not always possible. The Fluent class can be used to simplify
things for developers.
The following example will create a new Fluent instance with some data:
Now that we have a Fluent instance, data can be retrieved just like an object or an array:
Both $value and $secondValue would contain the value The first value. Accessing data
that does not exist now simply returns null, without raising an error:
1 $value = $fluent['does_not_exist'];
2
3 $secondValue = $fluent->doesNotExist;
Both $value and $secondValue would contain the value null. The Fluent class does expose
public methods in its API to custom the default value returned.
The $default value is evaluated using the value helper function, meaning that it can be the
result of a function:
If we look at the following code example, one might be tempted to say that the value of $message
would be Hello, world!, but that would be incorrect:
Fluent 170
However, that would be incorrect. It is important to remember that the Fluent object is an
elaborate key/value storage container that can behave like an array or an object. When the fluent
container is created for an object containing a closure, such as the above example, the closure
instance is stored as the value. The following code will quickly prove this:
1 // true
2 $isClosure = ($fluent->method instanceof Closure):
To evaluate the closure and get the results, the value helper function can be used:
1 // Hello, world!
2 $message = value($fluent->method);
3
4 // Hello, world!
5 $message = value($fluent->get('method'));
19.1.2 getAttributes()
The getAttributes method simply returns an array containing all key/value pairs, representing
the underlying data contained within the Fluent instance.
After the following code is executed:
The $attributes variable would look have a value similar to the following:
Fluent 171
1 array (size=4)
2 'first' => string 'The first value' (length=15)
3 'second' => string 'The second value' (length=16)
4 'third' => string 'The third value' (length=15)
19.1.3 toArray()
The toArray method returns the exact same values as the getAttributes method.
19.1.4 jsonSerialize()
The jsonSerialize method internally returns a call to toArray. Because of this, toArray,
jsonSerialize and getAttributes are all functionally equivalent. The jsonSerialize
method exists to satisfy PHP’s JsonSerializable² interface, which allows developers to
customize how a class is represented when using the json_encode function.
19.1.5 toJson($options = 0)
The toJson method will return a JSON encoded version of the data stored within the fluent
instance. It internally does this by returning a call to PHP’s json_encode³ function, passing in
any $options that were supplied. Like the json_encode function, the $options parameter is
a bitmask of the predefined JSON constants⁴.
The following code:
would be converted into the following JSON, stored in the $jsonValue variable:
1 {
2 "first": "The first value",
3 "second": "The second value",
4 "third": "The third value",
5 "method": {}
6 }
The toJson method internally makes a call to PHP’s json_encode function. Unlike json_-
encode, toJson does not provide a way to specify the depth (essentially how many arrays are
nested inside of each other) to which data will be encoded, which is by default set to 512. To
convert a fluent object into its JSON equivalent with a depth greater than 512, the following
method will be sufficient:
173
Facades 174
The alternative² is to inject the cache repository directly into the controller:
²Dependency injection is not the only alternative to using facades, it is, however, arguably the most common in Laravel projects.
Facades 175
Both code examples would accomplish the same thing: retrieve some_cache_item from the
cache storage. The facade example allows for shorter code, and code that is definitely easier to
follow along with. The second example has its own advantages too, which will not be covered
in this section.
1 <?php
2
3 class Calculator {
4
5 /**
6 * Adds two numbers.
7
8 * @param mixed $firstNumber
9 * @param mixed $secondNumber
10 * @return mixed
11 */
12 public function add($firstNumber, $secondNumber)
13 {
14 return $firstNumber + $secondNumber;
15 }
16
17 // Possibly many more methods.
18
19 }
The next thing that needs to happen is the class needs to be registered with the service container:
1 App::singleton('math', function()
2 {
3 return new Calculator;
4 });
Components are typically registered with the service container through the use of
Service Providers.
The Calculator class instance was bound as a singleton because there does not need to possibly
hundreds of instances of Calculator created: many consumers of the class can share a single
instance (note that not all classes should be bound as a singleton). The important part is that we
have an service container binding: math which will resolve to an instance of Calculator.
It is at this point a facade can be created. A facade is created by creating a new class and extending
Laravel’s abstract Facade class:
Facades 177
1 <?php
2
3 use Illuminate\Support\Facades\Facade;
4
5 class Math extends Facade {
6
7 /**
8 * Get the registered name of the component.
9 *
10 * @return string
11 */
12 protected static function getFacadeAccessor() { return 'math'; }
13
14 }
It is important to note that the value returned by the getFacadeAccessor() function matches
the name of the service container binding: math. The facade will use that value to request a class
instance from the service container and redirect method calls to that instance.
We will now examine how we would have used the Calculator class without the facade:
Examining the above code sample, it can be deduced that to add a new facade alias we simply
need to add a new entry to the aliases array. The key of the entry will become the name of the
alias and the value of the entry will become the class being aliased. To make this clearer, in the
above list Response is aliasing Illuminate\Support\Facades\Response, and both classes
can be used interchangeably.
We will use our Math facade from earlier, and we will assume it was defined in the Our\Applications
\Namespace. We could create an alias like so:
Developers can manually create an instance of the BladeCompiler themselves like so (this
Facades 182
1 <?php
2
3 use Illuminate\Support\Facades\App;
4
5 $bladeCompiler = App::make('view')->getEngineResolver()
6 ->resolve('blade')->getCompiler();
20.4.3.1 has($key)
The has function will check if a cookie with the given $key exists for the current request.
The get function will retrieve a cookie from the current request with the given $key. A
$default value can be supplied and will be returned if a cookie with the given $key does
not exist.
The get method will get an item from the input data, such as when a user posts a form or an API
request is being processed. The get method can be used for requests with the following HTTP
verbs:
• GET
• POST
• PUT
Facades 183
• DELETE
The get method will invoke the input method on an instance of the
Illuminate\Http\Request class.
The get method looks up the data based on the given $key. A $default value can be supplied
and will be returned if the given $key is not found in the request data.
20.4.5.1 connection($name)
In the above code example, the $className variable would contain the value Illumi-
nate\Auth \AuthManager.
This method of determining a facade’s underlying class can be expanded on to create a function
that will list every facade’s underlying class for the current Laravel installation:
³http://php.net/manual/en/function.get-class.php
Facades 184
1 /**
2 * Generates an HTML table containing all registered
3 * facades and the underlying class instances.
4 *
5 * @return string
6 */
7 function getFacadeReferenceTable()
8 {
9 $html = '';
10
11 // An array of all the facades that should be printed in the table.
12 $facades = [
13 'App', 'Artisan', 'Auth', 'Blade', 'Bus',
14 'Cache', 'Config', 'Cookie', 'Crypt', 'DB',
15 'Event', 'File', 'Hash', 'Input', 'Lang', 'Log',
16 'Mail', 'Password', 'Queue', 'Redis', 'Redirect',
17 'Request', 'Response', 'Route', 'Schema', 'Session',
18 'Storage', 'URL', 'Validator', 'View'
19 ];
20
21 // Boilerplate HTML to open an HTML table.
22 $html = '<table><thead><tr><th>Facade</th>';
23 $html .= '<th>Underlying Class</th></tr><tbody>';
24
25 foreach ($facades as $facade)
26 {
27 $html .= '<tr><td>',$facade,'</td><td>';
28 $html .= get_class(call_user_func($facade.'::getFacadeRoot'));
29 $html .= '</td></tr>';
30 }
31
32 // Boilerplate HTML to close an HTML table.
33 $html .= '</tbody></table>';
34
35 return $html;
36 }
Appendix A: Available Hash
Functions
The chapter on hashing discussed creating implementations of Illuminate\Contracts\Hashing\Hashser
for the various hash functions available for PHP’s crypt⁴ function. However, there are many
more hash functions available through the use of PHP’s hash⁵ function. The following table lists
the hash functions that are available on a default Homestead environment. These functions were
discussed using PHP’s hash_algos⁶ function.
⁴http://php.net/manual/en/function.crypt.php
⁵http://php.net/manual/en/function.hash.php
⁶http://php.net/manual/en/function.hash-algos.php
185
Appendix B: HTTP Status Codes
RFC 2295⁷, RFC 4918⁸, RFC 5842⁹, RFC 6585¹⁰, RFC 7231¹¹, RFC 7232¹², RFC 7233¹³, RFC 7235¹⁴,
RFC 7538¹⁵, RFC 7540¹⁶ define the HTTP status codes listed below. The status codes are listed
below for convenience.
Code Full Name
100 100 Continue
101 101 Switching Protocols
200 200 OK
201 201 Created
202 202 Accepted
203 203 Non-Authoritative Information
204 204 No Content
205 205 Reset Content
206 206 Partial Content
300 300 Multiple Choices
301 301 Moved Permanently
302 302 Found
303 303 See Other
304 304 Not Modified
305 305 Use Proxy
306 306 (Unused)
307 307 Temporary Redirect
308 308 Permanent Redirect
400 400 Bad Request
401 401 Unauthorized
403 403 Forbidden
404 404 Not Found
405 405 Method Not Allowed
406 406 Not Acceptable
407 407 Proxy Authentication Required
408 408 Request Timeout
409 409 Conflict
410 410 Gone
411 411 Length Required
⁷https://www.ietf.org/rfc/rfc2295.txt
⁸https://tools.ietf.org/html/rfc4918
⁹https://www.ietf.org/rfc/rfc2774.txt
¹⁰https://tools.ietf.org/html/rfc6585
¹¹https://tools.ietf.org/html/rfc7231
¹²https://tools.ietf.org/html/rfc7232
¹³https://tools.ietf.org/html/rfc7233
¹⁴https://tools.ietf.org/html/rfc7235
¹⁵https://tools.ietf.org/html/rfc7538
¹⁶https://tools.ietf.org/html/rfc7540
186
Appendix B: HTTP Status Codes 187