Sie sind auf Seite 1von 73

Getting Started

Laravel is a PHP 5.3 web application framework written by Taylor Otwell. It was written with PHP 5.3 features in mind. The combination of these features and its very e pressive synta has led to the framework !ainin! in popularity. In this book we will be e plorin! Laravel from the !round up startin! with its installation" which I am sure you will a!ree is a bree#e. In order to use any PHP $ramework %not &ust Laravel' you will need to have a PHP 5.3 enabled web server" I would recommend installin! a webserver on your local development machine" to allow you to test your work without needin! to upload your files each time you make a chan!e. This chapter makes the followin! assumptions( )ou have a workin! *pache+based web server. )ou are familiar with the server,s file system" and how to move - copy files. )ou have access to modify *pache confi! files. If you are usin! a different web server" you will be able to find many articles online on how to accomplish the tasks found below for your server. $irst we will need a copy of the framework,s source code" simply head over to Laravel.com and hit the bi! oran!e download button. $or added security" I would recommend e tractin! the contents of the packa!e to somewhere other than your web root. .ake a mental note of where you e tracted the source to %or find a sticky note/'. 0e now have two options to allow the framework to e ecute as e pected" I would advise tryin! the first method as it is the 1real1 way of installin! the framework and will allow us to specify a more thorou!h confi!. However I find the second method much 2uicker when workin! with many pro&ects on a development server.

Method 1 Create a new VirtualHost


0e will need to create a new *pache confi! file. On most standard installations creatin! a myproject.conf file in the *pache conf.d folder will include it by default" please see the documentation for your current setup for more information. Inside our new confi! file" paste-type the followin! 3irtualHost declaration(
<VirtualHost 127.0.0.2> DocumentRoot "/pat /to/lara!el/project/pu"lic" #er!er$ame myproject <Directory "/pat /to/lara!el/project/pu"lic"> &nde'es (ollo)#ym*in+s ,ultiVie)s -llo)%!erride all </Directory></VirtualHost> %ptions

0e must update the IP address to one which is not currently in use. %4est not to use 127.0.0.1" this is your loopback address" and you may have somethin! else usin! it.' 5han!e the two paths to point to your Laravel source packa!e,s pu"lic folder. 6ow restart your webserver. 6e t we will create a new local 768 entry to point a pro&ect name to your 3irtualHost. $irst open the hosts file normally found at c./)indo)s/system02/dri!ers/etc/ osts on 0indows or /etc/ osts on uni +based operatin! systems. *dd the followin! line usin! the IP address you used in your 3irtualHost declaration" and a pet name for your pro&ect(
127.0.0.2 myproject

)ou should now be able to navi!ate to ( ttp.//myproject with your web browser to see the Laravel welcome pa!e.

Method 2 Symbolic link the public folder.


If you are familiar with usin! symbolic links on a uni +based system" this method will prove rather simple. Inside the e tracted Laravel source code %you remember where you put it" ri!ht9' you will find a sub folder called ,public,. This folder contains the Laravel bootstrap file and all public assets. 0e will be symbolic linkin! this folder to your public web root %possibly -var-www-html-'. To create the symbolic link simply e ecute the followin! command in your terminal of choice" replacin! the paths where necessary.
ln 1s /pat /to/lara!el/pu"lic/folder /pat /to/)e"/root/su"directory

$or e ample (
ln 1s / ome/dayle/lara!el/myapp/pu"lic /!ar/)))/ tml/myapp

ote! "ou could also symbolic link the public folder directly to your web root# but $ prefer using a subdirectory so $ can work on se%eral pro&ects. )ou should now be able to navi!ate to ( ttp.//local ost/myapp with your web browser to see the Laravel welcome pa!e.

Getting back on track..


*t this point you should now be able to see your Laravel welcome pa!e" if so.. Congratulations! )ou have a brand new Laravel pro&ect" you are now ready to !et codin!/ In the ne t chapter we will be coverin! the Laravel pro&ect structure" and providin! an e planation of each of the important files and folders. If you happen to find any of the topics covered in this book confusin!" the followin! links can be used to find the help and support you need" or simply post a new comment on 7ayle:ees.com. Laravel 0ebsite Laravel 7ocs Laravel *PI Laravel $orums

0hy not come and &oin our ever e pandin! community by usin! an I:5 client to connect to irc.freenode.net.2227 and &oinin! the 3lara!el channel/

'ro&ect Structure
Laravel,s source packa!e contains a number of different directories. Let,s take a look at the pro&ect structure to !ain a !reater understandin! of how thin!s work. I may use some terms to describe various features of Laravel that could be confusin! if you are &ust startin! out" if so" bear with me as we will cover each feature in more detail in a later chapter.

(oot )irectory Structure


Lets take a 2uick look at the top+level file and directory structure (
/application/"undles/lara!el/pu"lic/stora4e/!endor/artisan 5file6/pat s.p p 5file6

6ow lets take a closer look at each item ( /application This is where the ma&ority of the code for your application will live. It contains your routin!" data models and views. )ou will be spendin! most of your time here/ /bundles 4undles are Laravel applications. They can be used to separate aspects of your application" or can be released - downloaded to share common code. 4y installin! new bundles with artisan" you can e tend the functionality of Laravel to suit your needs. $nterestingly# the /application directory is also a bundle known as the D7(-8*9:;8$D*7# this means that anything you use in /application you can also use in your bundles* /laravel This is where the framework,s core files live" these are the files it needs to e ecute a re2uest. )ou will rarely have to interact with this directory" but it can sometimes be useful to browse the source to see how a 5lass or .ethod works. *lternatively you could check the Laravel *PI. /public This is the directory that you must point your web server to. Tt contains the bootstrap file inde'.p p which starts the Laravel framework" and the routin! process. The public directory can also be used to hold any publicly accessible assets such as 588" ;avascript files and ima!es. The lara!el subfolder contains the files needed to render the offline documentation correctly. /storage The stora!e directory is used as file store for services that use the file system as a driver" for e ample 8essions" or the 5ache class. This directory must be writable by the web+server. )ou will not need to interact with this directory to build a Laravel application. /vendor The vendor directory contains code used by Laravel" but wasn,t written by the framework,s author or contributors. The folder contains open source software" or parts of software that contribute to Laravel,s features. /artisan [file] *rtisan is Laravel,s 5ommand Line Interface. It allows you to perform numerous tasks on the command line. )ou can even create your own tasks/ To run *rtisan simply type(
p p artisan

/paths.php [file]

This file is used by the $ramework to determine paths to the important directories mentioned above" and to provide a shortcut for retrievin! them % usin! pat <='. )ou should not need to edit this file.

+pplication )irectory Structure


*s mentioned above" /application is where all the fun happens" so let,s have a look at the structure of the /application directory.
/ confi4/controllers/lan4ua4e/li"raries/mi4rations/models/tas+s/tests/!ie)s/"undles.p p 5file6/routes.p p 5file6/start.p p 5file6

*nd now a closer look at each one. /config The confi! folder contains a number of confi! files for chan!in! various aspects of the framework. 6o confi! needs to be set at install for the framework to work ,out of the bo ,. .ost of the confi! files return key+value PHP arrays of options" sometimes key+closure pairs that allow a !reat deal of freedom to modify the inner workin! of some of Laravel,s core classes. /controllers Laravel provides two methods for routin!" usin! controllers and usin! routes. This folder contains the 5ontroller classes that are used to provide basic lo!ic" interact with data models" and load view files for your application. 5ontrollers were added to the framework at a later date to provide familiar !round for users mi!ratin! from other frameworks. *lthou!h they were added as an afterthou!ht" due to Laravel,s powerful routin! system" they allow you to perform any action which can be performed usin! routes to closures. /language In this directory" PHP files containin! arrays of strin!s e ist to enable easy locali#ation of applications built usin! Laravel. 4y default the directory contains strin! files for pa!ination and form validation in the <n!lish lan!ua!e. /libraries The libraries directory can be used to ,drop in, sin!le class PHP Libraries to provide e tra functionality for your application. $or lar!er Libraries it is recommended that you create a 4undle instead. The libraries folder is added to the *utoloader at startup from the start.php file. /migrations The mi!rations folder contains PHP classes which allow Laravel to update the 8chema of your current database" or populate it with values while keepin! all versions of the application in sync. .i!ration files must not be created manually" as their file name contains a timestamp. Instead use the *rtisan 5LI interface command p p artisan mi4rate.ma+e <mi4ration:name> to create a new .i!ration. /models .odels are classes that represent your pro&ect,s data. 6ormally this would mean inte!ratin! with a form of database" or other data source. Laravel provides three methods for interactin! with common database platforms" includin! a 2uery builder named ,$luent," which allows you to create 8=L 2ueries by chainin! PHP methods" usin! <lo2uent O:. to represent your tables as PHP Ob&ects" or the plain old raw 8=L 2ueries that you,re used to. $luent and <lo2uent both use a similar synta " makin! their adoption a smooth transition. The models directory has been auto+loaded automatically from start.php. /tasks

4y creatin! classes in the tasks directory" you are able to add your own custom tasks to the Laravel *rtisan command line interface. Tasks are represented by 5lasses and methods. /tests The tests folder provides a location for you to keep your application >nit tests. If you are usin! PHP>nit" you can e ecute all tests at once usin! the Laravel *rtisan PHP command line interface. /views The views directory contains your HT.L template files to be used by controllers or routes" althou!h please use a .php e tension for files in this folder. )ou can alternatively use a .blade.php e tension to enable parsin! with the 4lade templatin! library which will be e plained in a later chapter. /bundles.php [file] To enable a bundle" simply add it to the array in bundles.php" you can also use a key+value name+array pair to define e tra options for the bundle. /routes.php [file] The routes file contains the methods which enable routes to be mapped to their appropriate outcome with Laravel. This topic will be e plained more thorou!hly in upcomin! chapters. This file also contains declarations for several events includin! error pa!es" and can be used to define view composers or route filters. /start.php [file] The start.php contains startup routines for the /application bundle" such as auto+loadin! directories" loadin! confi!s" and other wonderful useful stuff/ $eel free to append to this file. In the ne t chapter we will be cover routin! usin! controllers by creatin! a small dynamic website with several pa!es.

,sing Controllers
In this chapter we will be creatin! a simple multi pa!e website to demonstrate the workin!s of Laravel,s routin! system" without delvin! into anythin! too complicated. *s I mentioned in the previous chapter" there are two options available to route web re2uests to your code" 5ontrollers and :outes. In this chapter we will be usin! 5ontrollers since anyone &oinin! us from other frameworks will be more familiar with them.

(outing Controllers
8o let us start by takin! a look at a 5ontroller (
<>p p// application/controllers/account.p pclass -ccount:?ontroller e'tends ;ase:?ontroller@ pu"lic function action:inde'<= @ ec o "9 is is t e profile pa4e."A B pu"lic function action:lo4in<= @ ec o "9 is is t e lo4in form."A B pu"lic function action:lo4out<= @ ec o "9 is is t e lo4out action."A BB

* 5ontroller is a PHP 5lass that represents a section of your website" or web application. Its .ethods or ,*ctions, represent an individual pa!e" or an end+point of a HTTP re2uest. In the above e ample our *ccount 5ontroller represents our users section of the web site" a profile pa!e" a lo!in pa!e" and a lo!out pa!e. 6ote that the 5ontroller name is appended with :?ontroller and that action names are prefi ed with action:. 5ontrollers must e tend the ;ase:?ontroller" ?ontroller or another 5ontroller class. Our controller is created in the application/controllers folder as a lower+case file matchin! the controller name" the 5ontroller above would be saved at (
/application/controllers/account.p p

4efore we can use our 5ontroller we will need to re!ister it in /application/routes.p p. Let,s add the followin! line (
<>p p// application/routes.p pRoute..controller<CaccountC=A

If our controller is in a sub+folder of the controllers directory simply use periods %.' to separate the director%y ? ies' like so (
<>p p// application/routes.p pRoute..controller<Cin.a.su".folder.accountC=A

If our controller e ists in a bundle" simply prefi with the bundle name and a double colon (
<>p p// application/routes.p pRoute..controller<Cmy"undle..accountC=A

6ow if we visit(
ttp.//myproject/account/lo4in

we see 9 is is t e lo4in form.. This is because now that our 5ontroller has been mapped in the :oute class" the first se!ment %between the slashes' of the >:L specifies the controller" and the second se!ment %yes" a!ain between the slashes' specifies the action. In simple terms /account/lo4in is mapped to -ccount:?ontroller1>action:lo4in<= and the result of our method is displayed. 6ow let,s try visitin! /account instead (
9 is is t e profile pa4e.

0hy does this happen9 The inde' action is a special action which is called when no action is specified in the >:L" therefore the above pa!e could also be 1called1 with the followin! >:L (
/account/inde'

'assing 'arameters
This simple routin! is interestin!" but it doesn,t offer us anythin! that a simple PHP website could not. Let,s try somethin! a little more dynamic. 4y addin! parameters to our controller actions we can pass e tra data as se!ments to the >:L. Let,s add a welcome action to our controller (
<>p p// application/controllers/accountpu"lic function action:)elcome<DnameE Dplace= @ ec o "Felcome to @DplaceBE @DnameBG"AB

Here our action parameters are method parameters" so the above code should seem familiar. Let,s try visitin! the route /account/)elcome/Dayle/Fales..
Felcome to FalesE DayleG

Parameters can be used to pass resource identifiers to enable 5:>7 actions on data" or anythin! you can think of/ *s you can see" they offer a !reat deal of fle ibility to our actions. ote ! "ou can assign %alues to your action parameters to make them optional in the ,(-.

,sing Views
<choin! out source from our 5ontrollers yields a result" but it,s not an ele!ant solution. If you are interested in learnin! Laravel then ele!ant solutions may well have been what brou!ht you here. The nature of .35 su!!ests that we separate our visual layer" from the applications lo!ic. This is where the ,3iews, portion of the pattern comes into play. 0ith Laravel views could not not be simpler" simply add HT.L templates to your /application/!ie)s/ directory with a lower+case file name" and a .p p e tension. $or e ample (
/application/!ie)s/)elcome.p p

0ith the contents (


< 1>HollaG</ 1><p>9 is is t e )elcome action of t e account controller.</p>

6ow we need to return the 3iew from our welcome action. Laravel has a beautiful e pressive way of doin! this" let,s take a look (
<>p p// application/controllers/account.p ppu"lic function action:)elcome<DnameE Dplace=@ return Vie)..ma+e<C)elcomeC=AB

The more nerdy types amon! my readers will have reali#ed that the statement is tellin! Laravel to create %make' a 3iew ob&ect from the file application/!ie)s/)elcome.p p %e tension not needed here' and return it as the result of the welcome action. )ou will also notice that the ma+e<= method looks in the application/!ie)s folder for its views. If you would like to specify an absolute path to a view file simply use the pat . prefi " for e ample pat . /pat /to/my/!ie).p p. 6ow if we visit /account/)elcome/Dayle/Fales we will be !reeted with the web pa!e which we defined in our 3iew file. 6ote that you can also use the same sub+folder and bundle prefi es that we previously used with controllers" to refer to 3iews. I know what you,re thinkin!" now our welcome messa!e isn,t very dynamic at all9 Let,s see if we can fi

this. Let,s pass our action parameters to the 3iew" we can do this usin! the )it <= method and we can see Laravel,s ele!ant method chainin! in action" here we !o/
<>p p// application/controllers/account.p ppu"lic function action:)elcome<DnameE Dplace=@ return Vie)..ma+e<C)elcomeC= 1>)it <CnameCE Dname= 1>)it <CplaceCE Dplace=AB

>sin! the )it <= method we can pass any value %or ob&ect' to the 3iew" and !ive it a ,nickname, for accessin! it from the view. 0e have used the same nicknames as our parameter names in this e ample" but you can call them anythin! you want/ 6ow let,s use this data in our view (
< 1>HollaG</ 1><p>Felcome to <>p p ec o DplaceA >>E <>p p ec o DnameA >>G</p>

6ow our action works as it did before" only better formatted with neater source code separatin! all lo!ic from our visual layer. Instead of usin! several )it <= methods" you can pass an array as a second parameter to ma+e<= with key+value pairs. This can save space but has the same result" here is an e ample.
<>p p// application/controllers/account.p ppu"lic function action:)elcome<DnameE Dplace=@ Ddata H array< CnameC H> DnameE CplaceC H> Dplace =A return Vie)..ma+e<C)elcomeCE Ddata=AB

ote ! $ like to call my %iew array Ddata# but you can call it whate%er you want* In a later chapter we will cover 3iews in more detail" includin! 4lade templatin!" nested views and other advanced templatin! options.

(.S/ful Controllers
:<8Tful web applications respond to meanin!ful HTTP verbs with appropriate data. They are very useful when buildin! public *PI,s for your applications. 0ith Laravel you can have your controller actions respond to individual HTTP verbs usin! :<8Tful controller actions" let,s see this in action.
<>p p// application/controllers/ ome.p pclass Home:?ontroller e'tends ;ase:?ontroller@ pu"lic Drestful H trueA pu"lic function 4et:inde'<= // B pu"lic function post:inde'<= @ // BB @

8imply add a boolean public class attribute named @restful and set it to true" then prefi your actions with the HTTP verb to respond to" rather than actionA. 5ommon HTTP verbs are B<T" PO8T" P>T and 7<L<T<.

/he 0ase1Controller
)ou can edit the ;ase:?ontroller" and e tend it with your other 5ontrollers to provide !lobal functionality across all of your controllers. *dd a default action inde " or class values" anythin! you want/ The 4aseA5ontroller can be found in /application/controllers/"ase.p p. If you do not wish to use a 4aseA5ontroller" simply have your controllers e tend the ,5ontroller, class instead.

+d%anced (outing
6ow we are able to map our controllers and actions to >:I,s in the format /controller/action/param/param/... which is !reat" but we shouldn,t be restricted to usin!

only this format. Let,s see if we can break out of the mold. <arlier we placed a controller declaration in routes.p p but now let,s replace it with the followin! code.
<>p p//application/routes.p pRoute..4et<Csuper)elcome/<.any=/<.any=CE CaccountI)elcomeC=A

Here we are sayin!" let,s send all web re2uests with the J79 HTTP verb" and the address /super)elcome/<.any=/<.any= to the welcome action of the account controller. The %(any' se!ments are place+holders for our parameters" and will be passed in the order that they are provided. >sin! <.num= will match only numbers" and usin! <.any>= will create an optional se!ment. 8o now a visit to /super)elcome/Dayle/Fales will show our lovely view pa!e/ The advanta!e of definin! routes" is that we can have our >:Ls in whatever order we like" in whatever format we like. $or e ample we could also have..
<>p p//application/routes.p pRoute..4et<Csuper)elcome/<.any=/<.any=CE CaccountI)elcomeC=ARoute..4et<C)elcome/<.any=/to/<.any=CE CaccountI)elcomeC=A

6ow we have two different routes" with the same result pa!e. It is worth notin! that :outes that are defined 1hi!her up1 in the routes.p p file are !iven a hi!her priority. 0ith the followin! e ample..
<>p p// application/routes.p pRoute..4et<C<.any=/<.any=CE CaccountI)elcomeC=ARoute..4et<C)elcome/<.any=/to/<.any=CE CaccountI)elcomeC=A

..the second route would never be tri!!ered because the <.any= in the first route would respond to the )elcome in the second route. This is a common mistake when startin! out with Laravel. 4e sure to keep an eye on the priority of your routes/ 0e will be coverin! routin! in more depth in the ne t chapter which will also cover routin! with closures instead of controllers.

(outes 2ith Closures


In this chapter we will be usin! Routes with Closures instead of Controllers with Actions. If you have not already read the previous chapter on the topic of usin! controllers then I would su!!est startin! there since we will be buildin! on what we have already learned in this chapter. :outes allow us to map our framework >:L,s to closures" which is a very clean way of containin! our lo!ic without all of the ,class fluff,. 5losures are anonymous functions %function<= @B'" they can be assi!ned to and treated like any other variable. $or more information on 5losures" check out the PHP *PI article.

Closures
Lets have a look at a route that routes to a closure.
<>p p// application/routes.p pRoute..4et<C/CE function<=@ Vie)..ma+e<C ome.inde'C=AB=A return

In this e ample we are respondin! to re2uests to the root of the web application that use the HTTP verb J79 with a closure that simply returns a view ob&ect. The output is the default welcome pa!e. Please note that you only need the root slash for the root pa!e" all other routes omit it" for e ample..
<>p p// application/routes.p pRoute..4et<Caccount/profileCE function<=@ Vie)..ma+e<Caccount.profileC=AB=A return

:outes are :<8Tful by nature" but you can use Route..any<= to respond to any HTTP verb. Here are your options(
<>p p// application/routes.p pRoute..4et<=ARoute..post<=ARoute..put<=ARoute..delete<=ARoute. .any<=A

To pass parameters to your closures simply add the usual view placeholders to the >:I" and define parameters in your closure. They will be matched in the order from left to ri!ht" for e ample..
<>p p// application/routes.p pRoute..4et<Cuser/<.any=/tas+/<.num=CE function<DusernameE Dtas+:num"er=@ // Dusername )ill "e replaced "y t e !alue of <.any= // Dtas+:num"er )ill "e replaced "y t e inte4er in place of <.num= Ddata H array< CusernameC H> DusernameE Ctas+C H> Dtas+:num"er =A return Vie)..ma+e<Ctas+s.for:userCE Ddata=AB=A

*vailable placeholders are( 'laceholder .3planation %(any' .atch any alpha+numeric strin! %(num' .atch any whole number. %(any9' Optional parameter.

(edirects and amed (outes


It would be kinda silly to look at named routes before seein! a method that uses them wouldn,t it9 Let,s have a look at the :edirect class" it can be used to :edirect to another route. It can be used in a similar fashion to returnin! a view.
<>p p// application/routes.p pRoute..4et<C/CE function<=@ Redirect..to<Caccount/profileC=AB=A return

Lovely/ 5ouldn,t be simpler" wait no" it could" and is/ Lets take a look at a named route (

<>p pRoute..4et<Caccount/profileCE array<CasC H> CprofileCE CdoC H> function<= @ return Vie)..ma+e<Caccount/profileC=AB==A

Instead of passin! a 5losure as the second parameter" we now pass an array with the key ,do, pointin! to the closure This allows us to add all kind of e tra information to the route. The ,as, key" assi!ns a nickname to our route" this is what named routin! is all about. Let,s see how it can be used to improve the :edirect(( from before.
<>p pRoute..4et<C/CE function<=@ return Redirect..to:route<CprofileC=AB=A

There" now we have that nasty >:I out of our code" very pretty. *ll of the classes or helpers which refer to routes have a similar method to route to a named route" this can really clean up your code" and makes it read like a book. *lso" if you later decide to chan!e the >:I for a certain pa!e" you will not have to !o back and chan!e all of your links and redirects/

4ilters
Ok ok... I said I was !oin! to be e plainin! :outes in this one" but I honestly can,t think of a better place to cover $ilters" and they are related" so here we !o. $ilters are e actly as they sound" they are code" or tests that can be performed ,before, or ,after, a route" and other key events within the framework. Laravel has four special route filters that are defined by default in application/routes.p p" let,s take a look at them.
<>p pRoute..filter<C"eforeCE function<=@ // Do stuff "efore e!ery reKuest to your application...B=ARoute..filter<CafterCE function<Dresponse=@ // Do stuff after e!ery reKuest to your application...B=ARoute..filter<CcsrfCE function<=@ if <ReKuest..for4ed<== return Response..error<CL00C=AB=ARoute..filter<Caut CE function<=@ if <-ut ..4uest<== return Redirect..to<Clo4inC=AB=A

The first two routes" e ecute the encapsulated closure before and after every re2uest %or route - action' to your application. 0hat you do within the enclosure is entirely up to you. 8tart libraries" provide data to ,somethin!," your own creativity is your only limitation. They are special filters in that they do not need to be assi!ned to individual routes. The ,csrf, filter is used to prevent ,cross+site+re2uest+for!ery, and can be applied to routes which are the result of an *;*C call for e tra security. The ,auth, filter can be applied to any route" to prevent access unless a user is currently ,lo!!ed in, usin! Laravels authentication system. To apply ,csrf, or ,auth, filters to your :outes" simply add a new array entry to the second parameter like so(
<>p pRoute..4et<C/CE array<CasC H> CprofileCE C"eforeC H> Caut CE CdoC H> function<= @ return Vie)..ma+e<Caccount/profileC=AB==A

The key for the array can be either ,before, to run the filter before your route" or ,after, to run it after. .ultiple filters can be applied by separatin! their names with a ? %pipe' for e ample aut Mcsrf. *s of Laravel 3.D" if you would like to add a filter to a number of re2uests whose >:I,s match a specific pattern" use the followin! line (
<>p pRoute..filter<Cpattern. admin/NCE Caut C=A

This will apply the ,auth, filter to all route >:I,s that start with admin/.

(oute Groups
)ou may want to apply a number of settin!s across a ran!e of routes. )ou can do this easily usin! the route !roupin! option" take a look..
<>p pRoute..4roup<array<C"eforeC H> Caut C=E function<=@ Route..4et<CpanelCE function<= @ // do stuff B=A Route..4et<Cdas "oardCE function<= // do stuff B=AB=A @

now both the panel and dashboard routes are protected by the auth filter. *lthou!h routin! can be very simple" routes can also be as comple as you need them to be. >se route !roups to avoid duplicatin! common rules across many routes and keep your code 7:). %7on,t repeat yourself/' The ne t chapter will cover the creation of links" so that we can move from one routes pa!e to the ne t.

-inks and ,(-s


Our application mi!ht !et a little borin! if we only have one pa!e" and I,m sure the user would !et peeved 2uite 2uickly if they had to type out the full >:I each time to switch pa!es. $ortunately hyper+links are here to save the day. If you haven,t been livin! under a rock for the past couple of decades you will already know what hyper+ links are" and I won,t bore you with the technical e planation. 4efore we have a look at links let,s take a look at how Laravel handles its >:Ls.

(etrie%ing ,(-s
$irst let,s take a look at a problem. )ou see frameworks have very uni2ue >:L structures" some may have an inde .php in them" some installations won,t. Others will have comple routes. In most cases usin! a relative >:L like you would on another website would lead to trouble in the lon! run. If you chose to provide full >:L,s to everythin!" and decided to move the application at a later date" you mi!ht find yourself abusin! the find and replace function of your favourite editor. 0hy not let Laravel do all the hard work9 Laravel knows the full >:L to your application" it knows whether or not you are usin! >:L rewritin!. It even knows about your routes. Let,s take advanta!e of this information by usin! the >:L class to !enerate some site >:Ls. Let,s start by findin! the >:L to the root of our website. 0e can use the "ase<= method for this.
<>p pec o 8R*.."ase<=A// ttp.//myproject

Breat/ 6ow we have the full >:L to our site" with or without the inde'.p p on the end. It all depends on your current setup. 0hat about the current >:L" the one that is bein! routed at the moment" can we !et that9 )ou betcha/ 8imply use the current<= method.
<>p pec o 8R*..current<=A// ttp.//myproject/t is/pa4e

4y default Laravel will strip off the 2uery strin! if one is appended to the >:L. If we want to retrieve the current >:L alon! with the 2uery strin!" we can use the full<= method instead.
<>p pec o 8R*..full<=A// ttp.//myproject/t is/pa4e>t in4Hstuff

Enowin! our base >:L and current >:L can be handy" but it would be more useful if we could !et the >:L to other routes or pa!es" then we could create links. To !enerate a >:L to a route" we use the to<= method" and hand it the route we are tryin! to retrieve" this is much easier than specifyin! the full path" for e ample..
<>p pec o 8R*..to<Cmy/routeC=A// ttp.//myproject/my/route

If we want to link to this pa!e securely" via the HTTP8 protocol we can use the method to:secure<= instead.
<>p pec o 8R*..to:secure<Cmy/routeC=A// ttps.//myproject/my/route

7o you remember bein! tau!ht about named routes in the routin! chapter9 Of course you do/ Here,s an e ample of one a!ain..
<>p pRoute..4et<Clo4inCE array<CasC H> Clo4inCE CdoC H> function<= @ codeB==A // some

Here we have a route that we have named ,lo!in, usin! the ,as, array key. 0ell I told you that it would be useful later" and now is the time for named routes to shine. Let,s make a link to our named ,lo!in, route..
<>p pec o 8R*..to:route<Clo4inC=A// ttp.//myproject/lo4in

0oah/ 3ery clean and e pressive I think you will a!ree. 0hat if we need to supply parameters to our route9 8imple" &ust pass an array of parameters as a second parameter to the to:route<= method. Let,s ima!ine for a second that our lo!in route looks more like this...
<>p pRoute..4et<Cmy/<.any=/lo4in/<.any=/pa4eC=..

It,s a terrible route" please don,t use u!ly >:L,s like this one" but it will help to illustrate a point. )ou see if you pass parameters to the to:route<= method" Laravel will automatically work out which order they should appear in the >:L" and return the full >:L with the parameters in the ri!ht place" neat/
<>p pec o 8R*..to:route<Clo4inCE array<LE 7==A

The above method would !ive us..


ttp.//myproject/my/L/lo4in/7/pa4e

Breat/ 6ow our routes will look s2ueaky clean.. as lon! as we don,t create routes as complicated as that one. 8o that,s routes cleared up" but we shouldn,t for!et controllers. 6o one likes to be left out. $ortunately there,s a nice and clean way to create a link to a controller action. 8imply use the to:action<= method" for e ample..
<>p pec o 8R*..to:action<Cdas "oardI omeC=A// ttp.//myproject/das "oard/ ome

8imply pass the controller name and action" separated by an I %at' symbol. Once a!ain you can pass an array of e tra parameters as a second parameter to the to:action<= method if you need to. If we are dealin! with assets" a 588 style+sheet for e ample" rather than routes pa!es we will need a very different >:L. 0e can,t use 8R*..to<= because that mi!ht put an inde'.p p in the >:L" or resolve it to one of our routes. Instead we can use the to:asset<= method to !enerate a correct link. 8imply pass the application relative path to our style+sheet and Laravel will take care of the rest.
<>p pec o 8R*..to:asset<Ccss/style.cssC=A

This line will !ive us..


ttp.//myproject/css/style.css

These methods are already very handy" but Laravel takes this a step further by providin! shorter elper methods which look !reat when used in our views. Here is a list of these helpers" and their lon!er alternatives. Helper url%' asset%' route%' action%' Method >:L((to%' >:L((toAasset%' >:L((toAroute%' >:L((toAaction%'

Generating -inks
6ow that we can retrieve our site links" the ne t lo!ical step would be to use them to create hyper+links. 6ow I know what you,re thinkin!" we can do it like this..
<a refH"<>p p ec o 8R*..to<Cmy/pa4eC=A >>">,y Oa4e</a>

8ure that would work" but it,s a little u!ly. In Laravel if somethin! is a little u!ly" there is always a better way of handlin! it. Links are no e ception.

0hy don,t we use the HT.L class to !enerate a link9 *fter all" that,s what the HT.L class is for. It is used to !enerate all kinds of HT.L ta!s.
<>p p ec o H9,*..lin+<Cmy/pa4eCE C,y Oa4eC=A >>

That looks a lot better/ Let,s see the result.


<a refH" ttp.//myproject/my/pa4e">,y Oa4e</a>

If you are an 8<O nin&a" and cannot stand to see a link without a title attribute" simply pass an e tra array.
<>p p ec o H9,*..lin+<Cmy/pa4eCE C,y Oa4eCE array<CtitleC H> C,y pa4eGC==A >>

0hich !ives..
<a refH" ttp.//myproject/my/pa4e" titleH",y pa4eG">,y Oa4e</a>

One of the !reat features of Laravel is how consistent its method namin! is. .any of the H9,*..lin+ methods follow a similar namin! pattern as the 8R*..to methods" which makes them easy to remember. Let,s take a look at how we can link to a secure pa!e %via HTTP8'.
<>p pH9,*..lin+:to:secure<Cmy/pa4eCE C,y Oa4eC=A// <a refH" ttps.//myproject/my/pa4e">,y Oa4e</a>

0e can also use lin+:to:route" to create a link to a named route &ust like we did with the >:L library.
<>p pH9,*..lin+:to:route<Clo4inCE C*o4inGC=A// <a refH" ttp.//myproject/lo4in/pa4e">*o4inG</a>

Once a!ain we can use the lin+:to:action<= method to link to a controller+action pair" for e ample..
<>p pH9,*..lin+:to:action<CaccountIlo4inCE C*o4inGC=A// <a refH" ttp.//myproject/account/lo4in">*o4inG</a>

Laravel even !ives us a method of easily creatin! ,mailto, links from an email address. Let,s take a look.
<>p pH9,*..mailto<CmeIdaylerees.comCE C,ail meGC=A// <a refH"mailto.meIdaylerees.com">,ail meG</a>

6ice and clean/ 6ow that you know how to create >:L,s and links" your applications will start to !row in si#e" coverin! many routes until they consume our planet and take over the unive... )our applications will be a lot more interestin!/

4orms
$orms are an important part of any web+based application. They help control the flow of the application" allow us to receive input from our users and make decisions that affect the functionality of our applications. They are also my least favorite thin! in the world to write. $ortunately for me" Laravel,s form class takes care of a lot of the hard work for us by providin! useful methods for !eneratin! common form elements. Let,s use the form class to create a simple web form in one of our views.

Creating 4orms
// form.p p<>p p ec o (orm..open<Cmy/routeC=A >> <G11 username field 11> <>p p ec o (orm..la"el<CusernameCE C8sernameC=A >> <>p p ec o (orm..te't<CusernameC=A > > <G11 pass)ord field 11> <>p p ec o (orm..la"el<Cpass)ordCE COass)ordC=A >> <>p p ec o (orm..pass)ord<Cpass)ordC=A >> <G11 lo4in "utton 11> <>p p ec o (orm..su"mit<C*o4inC=A<>p p ec o (orm..close<=A >>

Take a moment" stare at the form source" you have never seen a form so clean. 8ay it out loud to yourself" !o on.. I will wait. I have never seen a form so clean. )ou are ri!ht" its beautiful. Let,s have a look at the !enerated source to make sure I,m not &ust teachin! you wron!" you know" for fun9
<form met odH"O%#9" actionH" ttp.//mysite/my/route" accept1c arsetH"89(1P"> <G11 username field 11> <la"el forH"username">8sername</la"el> <input typeH"te't" nameH"username" idH"username"> <G11 pass)ord field 11> <la"el forH"pass)ord">Oass)ord</la"el> <input typeH"pass)ord" nameH"pass)ord" idH"pass)ord"> <G11 lo4in "utton 11> <input typeH"su"mit" !alueH"*o4in"></form>

Breat" it worked/ I mean of course it did/ Let,s !o over the form line by line to see how it works. On our first line we have the (orm..open<= method" which creates a form open ta! for us.
<>p p ec o (orm..open<Cmy/routeC=A >>

The first parameter to the method is the >:I we wish to submit the form to. The second parameter is the ,79H%D used to submit the form" if you don,t provide a method as a strin! Laravel will assume that you want a O%#9 form" which is the most common usa!e. The third parameter is also optional" you can pass an array of attri"ute H> !alue pairs to add e tra attributes to the <form> ta!. $or e ample" if you wished to tar!et the form with ;avascript you may want to pass array<CidC H> CmyformC= as the third parameter to !ive the element an id. To submit a form to a secure >:I %https' you will need to use the open:secure<= method instead of open<=. It accepts the same parameters. If you wish to be able to have files uploaded from your form" it will need to use multipart/data" use open:for:files<= instead of the open<= method. This method also accepts the same parameters. $inally if you wish to submit to a secure >:I" and have files uploaded you will need to use the open:secure:for:files<= method" which once a!ain accepts the same parameters" and is a combination of both open:secure<= and open:for:files<=.

+dding -abels
The ne t line contains the (orm..la"el<= method which is used to create a <la"el> element. The

first parameter is the name of the input element that it describes to be used in the forH"" attribute. The second parameter is what will be used as the content of the la"el element. )ou can pass an array as an optional third parameter to apply e tra HT.L element attributes.

Generating $nputs
6e t we have the input !enerators" these methods help to !enerate all of the HT.L elements that are common to forms. In the e ample above we use the te't<= and pass)ord<= method to !enerate <input typeH"te't".. and <input typeH"pass)ord".. elements. The first parameter to the method" is the value of the elements name attribute. The optional second parameter is the default value of the element. Once more we can pass an array of HT.L attributes as an optional third parameter" are you startin! to see a pattern yet9 The te'tarea<= and idden<= fields also accept the same parameters. 5heckbo es can be created usin! the c ec+"o'<= method" with the first parameter bein! the name of the element" the second bein! the value. The third option is an optional boolean switch to set whether the element is initially checked or not. The fourth optional parameter a!ain sets attributes. In fact" !o ahead and assume that all future inputs accept an attributes array as their optional final parameter. Let,s have a look at a checkbo !enerator..
<>p p ec o (orm..c ec+"o'<CadminCE CyesCE trueE array<CidC H> Cadmin1c ec+erC==A >>

The radio<= method creates radio buttons" and shares the same parameters as the c ec+"o'<= method. 6e t we have drop downs" the most awkward of all form elements. $ortunately all we need to do is pass a name" an array of !alue H> la"el options" and an optional parameter to state which option should be selected by default to the select<= method. Our dropdown will then be !enerated for us" for e ample..
<>p p(orm..select<CrolesCE array< 0 H> C8serCE C7ditorCE 0 H> C-dministratorC=E 2=A 1 H> C,em"erCE 2 H>

and we !et..
<select nameH"roles"> <option !alueH"0">8ser</option> <option !alueH"1">,em"er</option> <option !alueH"2" selectedH"selected">7ditor</option> <option !alueH"0">-dministrator</option></select>

Breat/ 6ow it,s time to submit our form.

Generating 0uttons
The su"mit<= and "utton<= !enerator methods both accept the same parameters. The first bein! the !alue of the HT.L element" and the second bein! the usual array of attributes.
<>p p(orm..su"mit<C*o4inC=A

Secret $nputs
There are also a number of e tra !eneration methods for less common form inputs that aren,t covered by the documentation. Here is a listin! of them" with their parameters.
<>p p(orm..searc <DnameE D!alue H nullE Dattri"utes H array<==A(orm..email<DnameE D!alue H nullE Dattri"utes H array<==A(orm..telep one<DnameE D!alue H nullE Dattri"utes H array<==A(orm..url<DnameE D!alue H nullE Dattri"utes H array<==A(orm..num"er<DnameE D!alue H nullE Dattri"utes H array<==A(orm..date<DnameE D!alue H nullE Dattri"utes H array<==A(orm..file<DnameE Dattri"utes H array<==A

CS(4 /oken
If you intend to use the ?#R( filter %which will be covered in a later chapter' you can add the 58:$ token to your form by usin! the method to+en<=" for e ample..
<>p p(orm..to+en<=A

4orm Macros
Laravel has provided many different input methods" but what if we need somethin! a little more custom9 $ortunately Laravel has provided the macro<= method to allow us to create our own input !enerators. 4y passin! an input name and a closure to the macro<= method we can define our own input !enerator" let,s take a look.
<>p p(orm..macro<Cs oe:siQeCE function<= @ />CAB=A return C<input typeH"s oe:siQe"

6ow we can use the $orm class to !enerate our shoe si#e field in the same way as any other input" for e ample..
<>p p ec o (orm..s oe:siQe<=A >>

If you need to use parameters" simply add them as parameters to the closure. <n&oy creatin! your own uni2ue input !enerators/

Handling $nput
6ow that we know how to create forms" we need to learn how to handle the input that has been sent by them. *s always" Laravel has provided an ultra clean way of dealin! with your input data. 6o need to interact with PHP arrays such as D:O%#9" D:J79 and D:(&*7#. Let,s be honest" those look u!ly.

(e5uest data
Let,s use the Input class to handle this instead.
<>p pDpanda H &nput..4et<CpandaC=A

6ow we have a Panda/ Breat.. we have too many already. One thin! that you need to remember about the 4et<= method on the &nput class is that it doesn,t refer to D:J79 data. )ou will see that 4et<= is simply a nice and e pressive short method name for retrievin! all kinds of data. The &nput class also responds to 4et<= with all kinds of re2uest data" includin! D:O%#9. If a piece of re2uest data isn,t set" the Input class will return null. If you pass a second parameter to the 4et<= method and the inde doesn,t e ist" then the method will return the second parameter instead. 3ery useful/
<>p pDpanda H &nput..4et<CpandaCE C,uffinC=A

If you would like to retrieve the entire re2uest array" simply skip the inde . <asy as that.
<>p pDmorepandas H &nput..4et<=A

4y default the 4et<= array won,t includes values from the D:(&*7# array" however if you use all<= instead of 4et<= it will contain files too.
<>p pDpandas:and:files H &nput..all<=A

If you would like to check if a piece of post data e ists without actually returnin! it" simply use the ele!ant and hi!hly e pressive as<= method which will return a boolean result.
<>p pDdo:)e: a!e:a:panda H &nput.. as<CpandaC=A

4iles
To access an element from the D:(&*7# array" simple make a call to the &nput..file<= method" for e ample..
<>p pDfile H &nput..file<CspoonC=A

If you simply want to retrieve a file attribute then add a period and an attribute key to the first parameter" for e ample to retrieve the file si#e..
DsiQe H &nput..file<Cspoon.siQeC=A

Once a!ain" callin! the method without a parameter will retrieve the full array of files. FFF 6ote( )ou can use this synta to access all multi dimensional arrays. 8imply use a period to denote a nested array inde . FFF
Dfiles H &nput..file<=A

4lash )ata
$lash data is a useful method of storin! data for use in the ne t re2uest. It can be a useful method of repopulatin! forms. To flas all of the current re2uest data to the session" for it to be accessible in the ne t re2uest" simply use the flas <= method.
<>p p&nput..flas <=A

If you only want to flash a portion of the current re2uest data" simply pass ,only, as the first parameter to the method and an array of field names that you wish flas ed as the second parameter.
<>p p&nput..flas <ConlyCE array<C"ettyCE CsimonC==A

6ow we will take 4etty and 8imon with us to the ne t re2uest. *lternatively we could specify a list of fields that we don,t want to take with us usin! the e'cept option" for e ample..
<>p p&nput..flas <Ce'ceptCE array<Cuncle:"o"C==A

There" now we can leave >ncle 4ob behind" he,s an arro!ant soul" and dislikes our national animal the red panda. 6ow we can use the usual Redirect..to<= method to move to a new re2uest. $rom here we can use the e pressive &nput..old<= method to retrieve a value that has been flas ed from a previous re2uest.
<>p pD"etty H &nput..old<C"ettyC=A

*s you can see" 4etty has survived the transition. )ou can think of flash data as those fu##y transporter pads from 8tar Trek" movin! Eirk and his buddies from one re2uest to the ne t. Once a!ain you can skip the parameter to return a full array of flash data.
<>p pDpeople H &nput..old<=A

)ou can use the ad<= method to see if an inde of flash data e ists.
<>p p&nput.. ad<Cuncle:"o"C=A

Of course not" we hate >ncle 4ob. Laravel wouldn,t be the framework it is" without its wonderful shortcuts and e pressive methods. Let,s have a look at a prime e ample of this in action.
<>p preturn Redirect..to<CpartyC=1>)it :input<=A

The )it :input<= method will flash all of our re2uest data for us" it also accepts the same only and e'cept methods as our flas <= method.
<>p preturn Redirect..to<CpartyC=1>)it :input<ConlyCE array<C"ettyCE CsimonC==Areturn Redirect..to<CpartyC=1>)it :input<Ce'ceptCE array<Cuncle:"o"C==A

Validation
3alidation is an important part of many web applications. )ou can never trust your users" they have been plottin! to destroy you for weeks" by abusin! your forms with evil &avascripts. 0e can,t let them win" they must not destroy our beautiful applications. Let,s validate all input provided by the user" that way they won,t be able to harm us at all. 6aturally Laravel has a library" aptly named ,3alidation, that will do all the hard work for us.

Set up %alidation
Let,s start by creatin! an ima!inary form" close your eyes and ima!ine a nice lon! form with many fields... uh oh... how can I !et you to open your eyes a!ain..9 :i!ht" I will assume you !ot fed up of waitin!" have opened your eyes" and are back with me a!ain" alon! with our ima!inary form. Let,s !et the input data from that form.
<>p pDinput H &nput..4et<=A

6ow normally you don,t want to use the 4et<= method" as its an easy way to populate your input array with e tra data you don,t need. In fact the open source collaboration site !ithub was a victim to mass assi!nment. I have used 4et<= to simplify the tutorial" in your applications please build the input array only with the fields you need. Our input array now contains somethin! that looks a little like this..
<>p parray< CnameC H> CRo nCE Ca4eC H> 1L=

Let,s validate these fields to make sure they make sense to our application" before we can start the validation process we need to create a set of rules that will be used to validate each field. 0ith the validator class" rules are defined in an array format" let,s &ump ri!ht in and take a look.
<>p pDrules H array< CnameC CreKuiredMinte4erMmin.12C=A H> CreKuiredMmin.0Mma'.02Malp aCE Ca4eC H>

Breat" now we have some rules. The array key is the field that is bein! validated upon" and the array value contains a number of validation rules separate by a pipe ? symbol. In our case we are validatin! that both fields contain a value" by usin! the ,re2uired, rule. The len!th of the user,s name must be a minimum of 3 characters %min(3' and a ma imum len!th of 3G characters %ma (3G'. The ,alpha, rule will check to make sure that the name field only contains letters. Our a!e field must contain an inte4er and the value must be at least 12" you see that the min rule has adapted to fit the content that its validatin!" very clever/ 7on,t worry" we will cover all the validation rules later" for now let,s see the validation in action" here we !o.
<>p pD! H Validator..ma+e<DinputE Drules=A

0e have made our validator ob&ect with the ma+e<= method" passin! it our input array" and our rules array. Let,s see if it validates/
<>p pif< D!1>fails<= =@ !alidation successGB // code for !alidation failure .<Belse@ // code for

*s you can see" we use the fails<= method to check the result of the validation attempt" it will return true if the validation has failed" and false if it was successful. If you prefer a more positive outlook on your validations" you could use the passes<= method" which

returns the opposite values..


<>p pif< D!1>passes<= =@ !alidation failure .<B // code for !alidation successGBelse@ // code for

There" now we are positive and can dance over rainbows with sparkleponies.

.rrors
If your validation fails" which it will because our user is under DH %sorry for slayin! your sparklepony'" you will want to find out what went wron!. The validator provides an errors .essa!es ob&ect which allows us to easily find the information we need. The errors ob&ect has similar methods to the &nput class" so I will not need to !o over them all" let,s retrieve an array of errors for a specific field.
<>p pDa4e:errors H D!1>errors1>4et<Ca4eC=A

6ow we have an array containin! all of the errors associated with the a!e field..
<>p parray< C9 e a4e must "e at least 12.C=

.ost of the time I find myself usin! the first<= method in my views" which returns the first array item if it e ists" or null if it doesn,t. $or e ample..
<>p p ec o (orm..la"el<CusernameCE C8sernameC= >><>p p ec o Derrors1 >first<CusernameC= >><>p p ec o (orm..te't<CusernameC= >>

6ow our validation errors will appear for this field if any are present. )ou can also pass a second parameter to the first<= method to format the output..
<>p p ec o Derrors1>first<CusernameCE C<span classH"error">.messa4e</span>C= >>

6eat/ )ou can also use as<= to check to see if an error e ists" and all<= to retrieve all errors as an array.

Validation (ules
Here is a list of validation rules" and their purpose. required <nsure that a value for a field is present" and is not an empty strin!. alpha The strin! must only consist of letters %alphabetical characters'. alpha num The strin! must only contain letters and numbers. >seful for usernames. alpha dash The strin! must contain only letters" numbers" dashes or underscore characters. >seful for storin! >:L slu!s. si!e"# %strin!' The strin! must be e actly five characters lon!. %numeric' The value must be five. between"#$%& %strin!' The len!th of the strin! must be between five and ten characters. %numeric' The value must be

between five and ten. min"# %strin!' The len!th of the strin! must be between five characters or more %numeric' The value must be e2ual to or !reater than five. %file' The file si#e must be 5 kilobytes or more. ma'"# %strin!' The len!th of the strin! must be less than or e2ual to five. %numeric' The value must be less than or e2ual to five. %file' The file si#e must be 5 kilobytes or less. numeric The value must be numeric. integer The value must be an inte!er or whole number. in"red$green$blue <nsure that the value is contained within the list of values provided. not in"pink$purple <nsure that none of the values provided match the value. confirmed The value of the field must match a confirmation field" named in the format , accepted The field value must be e2ual to ,yes, or D. >seful for validatin! checkbo es. same"age The field value must match the field specified by the same rule. different"age The field value must not match the field specified by the same rule. match"/[a(!])/ The field value must match the provided re!ular e pression. unique"users This is one of my favorites" the validator will look at the users database table" and make sure that the value is uni2ue within the column that has the same name as the field name. >seful for makin! sure that duplicate usernames or email addresses don,t occur. If you would like to specify an alternate column name" simply pass it as a second parameter..
uniKue.usersEnic+name

)ou can also force the rule to i!nore a provided id by passin! it as a third parameter.
uniKue.usersEnic+nameEL

e'ists"colors *cts as the opposite of uniKue" the value must already e ist in the database table. Once more you can pass a second parameter to refer to another column. before"%*+,(%-(%The date provided by the field" must have occurred before the date template provided to the "efore rule. The before and after filters use strtotime%' to calculate a timestamp for comparison" this means you can do

some neat tricks like..


"efore.ne't 9 ursday

>nfortunately I was on the one that added this functionality" so if it breaks you can !o ahead and shout at me... sorry/ after"%*+,(%-(%8imilar to before" only the date must occur after the date provided to the after rule. email The value must be a valid email address. url The value must match the format of an >:L. active url The value must match a valid active >:L. c ec+dnsr is used to verify that the >:L is active. mimes"png$mp. The value must be a @A$IL< which whose .I.< type matches the file e tensions provided. )ou can add additional .I.< types to the array in confi4/mimes.p p. image The uploaded file must be an ima!e.

Custom .rror Messages


I find the default error messa!es 2uite descriptive" but your clients mi!ht have their own ideas. Let,s see how we can customi#e our error messa!es to suit our needs. )ou can edit the validation error messa!es directly by modifyin! the file application/lan4ua4e/en/!alidation.p p...
..."after" H> "9 e .attri"ute must "e a date after .date."E"alp a" H> "9 e .attri"ute may only contain letters."E"alp a:das " H> "9 e .attri"ute may only contain lettersE num"ersE and das es."E...

Laravel replaces the .attri"ute marker with the name of the field. Other markers also e ist within the rules" and their purpose is 2uite self e planatory. If you would rather chan!e the messa!es for a sin!le form" rather than edit them !lobally" you can pass a third array of messa!es to the Validator..ma+e<= method.
<>p pDmessa4es H array< CsameC H> C9 e .attri"ute and .ot er must matc E foolGCE CsiQeC H> C9 e .attri"ute must "e e'actly .siQe E li+e du GC=AD! H Validator..ma+e<DinputE DrulesE Dmessa4es=A

Breat now we have custom messa!es/ 0e can even specify error messa!es for individual fields" by settin! the messa!e key to field:rule" for e ample..
<>p pDmessa4es H array< "irt dayGC=A Ca4e:reKuiredC H> CSou need to a!e ad at least one

Custom Validation (ules


The validator allows you add e tra rules to suit the needs of your application" let,s &ump ri!ht in and take a look at how we re!ister a new validation rule.

<>p pValidator..re4ister<CsuperdooperCE function<Dattri"uteE D!alueE Dparameters=@ return D!alue HH CsuperdooperCAB=A

Our newly created validation rule superdooper will ensure that our value matches the strin! ,superdooper,. )our custom validations should return true on success" or false on failure. The Dattri"ute value will be the name of the field bein! validated" and D!alue will of course contain the value. The Dparameters attribute contains an array of parameters that have been passed to the rule after the colon" and separated by commas. *s you have created a new validator" there will be no error messa!es associated with it yet" we will need to add one so that Laravel knows what to say when it fails. 0e can add an error messa!e in the same way as we have previously..
<>p pCsuperdooperC H> C9 e .attri"ute must "e superdooperE o+ trooper>GCE

Once a!ain you can pass the e tra error messa!e array as a third parameter to the Validator..ma+e<= method" or simply add it to your application/lan4ua4e/en/!alidation.p p file for safe keepin!.

Validation Classes
If we want to provide many new validation methods" or reuse them across a number if pro&ects" it would be best to create a validation class. 3alidation classes e tend Laravel,s data" and overload it with additional validation methods. The class is created in the application/li"raries directory for easy loadin!" but you could place it elsewhere as lon! as it is re!istered with the -utoloader %later chapter'. Let,s take a look at the class.
<>p p// application/li"raries/!alidator.p pclass Validator e'tends *ara!el/Validator @ pu"lic function !alidate:a)esome<Dattri"uteE D!alueE Dparameters= @ return D!alue HH Ca)esomeCA BB

*s you can see our 3alidator class e tends the *ara!el/Validator namespaced core class and provides additional validations in the form of !alidate:<rulename> methods. The validation methods accept the same parameters as the Validator..re4ister<= closure" and work in the same way. In order to use our new validation class" we will need to remove the e istin! alias for Validator from our application/confi4/application.p p file. This way Laravel will use our created class instead of the one in the Laravel source folder. )ou could use this method to replace the ori!inal validation methods with your own" for e ample you could create a !alidate:siQe method and calculate the si#e in an alternate format. I would su!!est addin! custom error messa!es to the validation lan!ua!e file when usin! 3alidation classes" this will allow for a much easier mi!ration to another pro&ect" and will not re2uire any ,source+ di!!in!, to find all the messa!es used. In the ne t chapter" we will cover some typical form validation scenarios that are common to web applications" this includes input forms" edit forms" form re+population and more.

Migrations
Ori!inally I had attempted to include a !uide to the $luent =uery 4uilder with this chapter" but I now feel that the chapter has become too lon!" so I have decided to cover database setup and mi!rations only in this chapter. Bet ready for a nice lon! e planation of $luent in the ne t chapter. .i!rations are one of my favorite Laravel features" I hate writin! 8=L" and the 8chema class allows me to create my tables easily" without writin! a sin!le line of that foul 1lan!ua!e1/ 6ot only that" the 8chema code looks absolutely beautiful and reads like a book. If you have not encountered mi!rations before" they are a way of describin! chan!es to your database in files" so that different installations - development copies of your application are aware of the current schema. 5han!es to the schema can also be reverted or ,rolled back,. .i!rations can also be used to populate tables with e ample data %also known as seedin!'.

)atabase Setup
Head over to your application/confi4/data"ase.p p confi! file" if you have ever installed a PHP application you will be familiar with this kind of file" you have your database access credentials to hand don,t you9 If not !o di! them out ri!ht now/ *re you back yet9 Breat" let,s take a closer look. 8croll down to the ,connections, array key" here you will see a number of options for a few different type of databases" fill in the connection parameters for your database of choice" I am !oin! to stick to !ood ole, fashioned my8=L.
<>p pCmysKlC H> array< Cdri!erC H> CmysKlCE C ostC H> Clocal ostCE Cdata"aseC H> CcodefunCE CusernameC H> CrootCE Cpass)ordC H> Cpandaseat"am"ooCE Cc arsetC H> CutfPCE Cprefi'C H> CCE=E

There we !o" now you will want to scroll up a little bit" and chan!e the ,default, array key to reflect the database you are usin!. $or me it,s already on my8=L.
<>p pCdefaultC H> CmysKlCE

6ow we have our database confi!ured" we need some tables to play with. Onwards to mi!rations/

Migrations
Let,s !et started by creatin! a mi!ration file. 0e are !oin! to use Laravel,s command line interface artisan to create our new mi!ration. To run *rtisan you will need to have PHP 5LI installed %normally this will be installed alon! side your web+ server'. )ou will also need to open a terminal to the root of your Laravel packa!e where the ,artisan, file e ists. :i!ht" let,s type our first artisan command (
p p artisan mi4rate.ma+e create:users

0e are tellin! artisan" to run the ma+e method on the mi4rate task" we pass a name for our mi!ration to identify it by" I like to name it after the action bein! performed" in this case we are creatin! the users table. Lets have a look at the result.
JreatG $e) mi4ration createdG

<nthusiastic/ If we take a look in our application/mi4rations folder" we see a new file named 2012:00:00:220TLU:create:users.p p" well yours mi!ht not be called that/ )ou see artisan

takes the current date" and adds the time in His format to create the file name. The reason for this is that dates are very important to mi!rations %and sin!le people'" the system needs to be able to know in which order to apply the chan!es. Let,s open up the file and take a look at the mi!ration class.
<>p pclass ?reate:8sers @ /NN N ,a+e c an4es to t e data"ase. N N Ireturn !oid N/ pu"lic function up<= @ // B /NN N Re!ert t e c an4es to t e data"ase. N N Ireturn !oid N/ pu"lic function do)n<= @ // BB

*s you can see" our mi!ration class consists of two methods" up<= is responsible for makin! all of your database chan!es" where do)n<= accomplishes the e act reverse" this way a mi!ration can be performed" and rolled back when necessary. If you were to create a table within the up<= method" we would DR%O the same table in the do)n<= method. 8o how do we perform chan!es on our database" no doubt with some comple u!ly 8=L 2uery ri!ht9 Haha" no. 0e are usin! Laravel" if it,s u!ly" it,s not in the framework. Lets have a look at creatin! a table with the Laravel 8chema class.
<>p p#c ema..create<CusersCE function<Dta"le= @ // auto incremental id <OV= Dta"le1>increments<CidC=A // !arc ar 02 Dta"le1>strin4<CusernameCE 02=A Dta"le1>strin4<CemailCE 020=A Dta"le1>strin4<Cpass)ordCE 2T=A // int Dta"le1>inte4er<CroleC=A // "oolean Dta"le1>"oolean<Cacti!eC=A // created:at M updated:at D-979&,7 Dta"le1>timestamps<=A B=A

0e call the create<= method on the 8chema class to create a new table" as parameters we pass the name of the table to be created" and a closure as the second parameter. 0e also need to pass a parameter to the closure" you can call it whatever you like" but I like usin! Dta"le because I think it makes the code read better. Inside the closure" we can use the Dta"le parameter to create our fields with a number of handy" well+ named methods" lets take a 2uick look at them. increments/0 *dd an auto+incrementin! I7 to the table" most of your tables will have this/ string/0 5reate a 3*:5H*: field" strin! sounds a lot better doesn,t it9 integer/0 *dd an inte!er field to the table. float/0 *dd a float field to the table. boolean/0 *dd a boolean field to the table. date/0 *dd a date field to the table. timestamp/0 *dd a timestamp field to the table. timestamps/0 *dd createdAat updatedAat timestamp fields. te't/0 *dd a te t field to the table.

blob/0 *dd a blob data field to the table. )ou can also use the chainable method 1>nulla"le<= to allow the field to receive 6>LL values. $ull details on the parameters available to the above methods can be found in the official documentation. Breat" so now we have created our table/ 8ince we created the table in the up<= method" we now need to DR%O the table in the do)n<= method" so that the schema would return to its ori!inal form after a rollback. $ortunately the 8chema class has another method that is perfect for this task.
<>p p#c ema..drop<CusersC=A

)ep" it doesn,t !et easier than that. The 8chema class also has functions for performin! other schema tasks" such as droppin! columns drop:column<=" addin! inde es uniKue<= and a number of forei!n key methods. I think that coverin! all of them here would turn the book into an *PI" somethin! I don,t wish to do" besides they are e plained well in the official documentation" and if you take a look there we can move on to new thin!s" how about findin! out how we run these mi!rations9 Let,s do it/ 4efore we can run our mi!rations" we need to install the lara!el:mi4rations table" so that Laravel can keep track of which mi!rations have been run. $ortunately artisan has a command which will perform the necessary database chan!es for you" let,s have a !o.
p p artisan mi4rate.install

*nd the result..


,i4ration ta"le created successfully.

Breat/ 6ow the lara!el:mi4rations table has been created" we can finally run our new mi!ration. 8imply use the task name this time" here we !o.
p p artisan mi4rate,i4rated. application/2012:00:00:220TLU:create:users

0oop" if we take a look at our database the users table has been created successfully. 0ait" we made a mistake/ %we didn,t" but I like drama and I need an e cuse to use rollback' Let,s rollback our schema to redo the chan!es.
p p artisan mi4rate.roll"ac+Rolled "ac+. application/2012:00:00:220TLU:create:users

Please note that if you would like to provide e ample data to populate your database with" simply create it with the $luent =uery 4uilder" however a !uide on this topic will not appear until the ne t chapter" so you mi!ht want to wait a day or so/ <asy as pie/ 6ow you know how to use mi!rations" you can build your schema and populate your database whenever you please/ 6e t chapter we will be lookin! at the $luent =uery 4uilder. *nd now" as promised" a list of names - messa!es from those who have purchased the book for more than @I.II. Please don,t for!et to talk about the Io5 container and how this can be useful with unit tests. )ou made a !reat choice with Laravel. + ;or!e .artine# Thanks for buyin! the book ;or!e" we will be coverin! the Io5 container in a later section" once we have covered all the basics of app buildin!. 0e at JHelp8pot really support what you,re doin! to e pand the Laravel community" keep up the !reat work/ + Ian Landsman Thanks Ian/ 0e the Laravel community really support what you,re doin! to e pand the $ramework" so

now we are even/ $or those of you who do not know" Ian Landsman is the head of >ser8cape" a company which provided the framework,s author with a &ob that lets him e pand the framework. >ser8cape also sponsor the bundle site for Laravel" and many other thin!s/ Please check out their product Helpspot" a wonderfully fle ible and affordable piece of help desk software/ There were some other purchases over @I.II that I have not received an email from yet" remember if you pay more than @I.II and you would like your name to appear in the book" please send an email to meJdaylerees.com " unfortunately I can,t see the names of those who purchased on the sales tab.

4luent 6uery 0uilder


$luent is another wonderful library that Laravel provides to help me dod!e the 8=L bullet" althou!h you can still write raw 8=L statements if you happen to en&oy pain. The best part about usin! $luent9 *part from the lack of 8=L" is that it uses prepared statements" which are fully protected a!ainst 8=L in&ection. $luent is also... well fluent" in a number of different 8=L dialects" so your methods will work across a variety of databases. 4efore we !et started you will need to understand the concept of method chainin!" take a look at this e ample.
<>p p?lass..ma+e<=1>c ain<=1>c ain<=1>c ain<=1>tri44er<=A

This is a very useful way of strin!in! options to!ether" and is a lovely way of e pressin! 8=L %as you will see later'. The class is instantiated with the ma+e<= method" sometimes you will also pass ,startup parameters, to the class this way. The c ain<= methods are used to modify the re2uest with different options" and the tri44er<= method is used to brin! back the final result. This mi!ht sound a bit confusin!" but let,s take a look at an e ample from fluent.
<>p pDusers H D;..ta"le<CusersC=1>) ere<CusernameCE CHCE CdayleC=1>4et<=A

The above e ample will e ecute a simple..


#7*7?9 N (R%, users FH7R7 username H CdayleCA

and brin! back an array of ob&ects" representin! database rows that are the result of the 2uery. The ta"le<= method is instantiatin! the ob&ect" and settin! the table that we intend to work with. The ) ere<= is a chain method that applies a 0H<:< clause to our 2uery" and 4et<= is the final tri!!er method that retrieves all ob&ects that are the result of the 2uery. The 4et<= tri!!er will brin! back an array of results" so lets start by loopin! the result set with a foreach.
<>p pforeac <Dusers as Duser=@ ec o Duser1>emailAB

*s you can see in the above e ample" fields for the row are accessed usin! the attributes of the result ob&ect" the loop above would output the email addresses for all of our users.

(etrie%ing (esults
Lets have a look at some of the other tri!!er methods for retrievin! results. get/0 0e have &ust used this" it will brin! back all ob&ects which are the result of the 2uery in an array. first/0 This tri!!er will brin! back a sin!le result ob&ect" the first ob&ect to match the re2uirements of the 2uery. find/1id0 This tri!!er will find the item by its database id" this is a handy shortcut to ) ere<CidCE CHCE Did= it will brin! back a sin!le result ob&ect. onl2/1fieldname0 This will brin! back the result for a sin!le field matchin! the 2uery. get/arra2/00 Pass an array of fields to 4et<= to retrieve only those fields.

2here Clauses
8o now we have the methods that we need to retrieve our database results" how can we apply conditions to these 8=L 2ueries9 0ell in the e ample above you saw me usin! the ) ere<= method" let,s take a closer look at this.
<>p pDusers H D;..ta"le<CusersC=1>) ere<CusernameCE CHCE CdayleC=1>4et<=A

Here we have the same snippet a!ain" but we are concentratin! on the ) ere<= part of the chain (
<>p p) ere<CusernameCE CHCE CdayleC=

The !reat thin! about how Laravel handles the where clause" is that the chain looks a little bit like the 8=L bein! !enerated. In the chain method above we are sayin! FH7R7 username H CdayleC" the first parameter to the method states the field which we are comparin!" the second parameter states the operator to use for the comparison" and the third parameter is the value which we are comparin! with. 0e could also use (
<>p p) ere<Ca4eCE C>CE C1PC=// FH7R7 a4e > C1PC// drin+ upG not if you are -merican t ou4 E sorry.

0hat if we want more conditions9 0ell first we need to decide" if we need ,*67 0H<:<," or ,O: 0H<:<," to include an ,*67, where clause" simply use the ) ere<= method a!ain in the chain" for e ample (
<>p pDusers H D;..ta"le<CusersC= 1>) ere<Cse'ynessCE C>CE L000= 1>) ere<CusernameCE CHCE CdayleC= 1>4et<=A

*s you can see in the above e ample" I have put each chain method on a new line" I find this is easier to read" and avoids havin! terribly lon! lines of code. This chain will perform the followin! 8=L (
#7*7?9 N (R%, users FH7R7 username H CdayleC -$D se'yness > L000A

If we would prefer to use an O: where condition we simply use the or:) ere<= method" which accepts the same parameters" for e ample (
<>p pDusers H D;..ta"le<CusersC= 1>or:) ere<CfaceCE C*&V7CE CWmalemodelWC= 1>) ere<CusernameCE CHCE CdayleC= 1>4et<=A

which !ives us (
#7*7?9 N (R%, users FH7R7 username H CdayleC %R face *&V7 CWmalemodelWCA

6ow I don,t need to e plain how every feature of 8=L works" there are plenty of other books for that" but I will name the methods used to accomplish common tasks instead. >se the ) ere:in<=" ) ere:not:in<=" or:) ere:in<= and or:) ere:not:in<= methods to match a field to one of an array of items. The ) ere:null<=" ) ere:not:null<=" or:) ere:null<=" and or:) ere:not:null<= methods to match a field to a 6>LL value. 8ometimes you will want to nest where clauses to!ether" Laravel provides functionality for this in the form of ,6ested 0here 5lauses," lets take a look at a code e ample from the official docs.
<>p pDusers H D;..ta"le<CusersC= 1>or:) ere<function<DKuery= @ DKuery1>) ere<C!otesC C>CE 100=A 1>) ere<CidCE CHCE 1= DKuery1>) ere<Ca4eCE C>CE 2L=A B= 1>4et<=A

4y passin! a closure containin! e tra where clauses to another where method" we can create nested where clauses" the result can be seen in the 8=L(
#7*7?9 N (R%, "users" FH7R7 "id" H > %R <"a4e" > > -$D "!otes" > >=

neat huh9 *nd now for a more interestin! feature/ %I told you about how I loathe 8=L ri!ht9' 7ynamic where clauses !ive you a really funky way of definin! simple where clauses. 5heck this out..
<>p p) ere:siQe<L=1>4et<=A

Here we are specifyin! the field to compare in the method name" $luent is so clever that it will deal with it" no problem/ It will even understand -$D and %R" check this out/
<>p p) ere:siQe:and: ei4 t<700E T00=1>4et<=A

< pressive" clean" Laravel at its finest.

/able 7oins
Let,s have a look at a &oin usin! $luent.
<>p pD;..ta"le<Ctas+sC= 1>join<CprojectCE Ctas+s.idCE CHCE Cproject.tas+:idC= 1>4et<array<Ctas+.nameCE Cproject.nameC==A

0e pass the name of the &oin table as the first parameter" and use the remainin! three parameters to perform an ,O6, clause" similar to how we perform ,0H<:<,s. 0e then pass the fields we want to return to the 4et<= method as an array. 0e can do a left:join<= e actly the same way" in fact it takes the same parameters" easy huh9 7o you remember the nested where clauses9 0ell you can use a similar techni2ue to add more conditions to the %$ clause of a &oin" let,s take a looksy.
<>p pD;..ta"le<Ctas+sC= 1>join<CprojectCE function<Djoin= @ Djoin1 >on<Ctas+s.idCE CHCE Cproject.tas+:idC=A Djoin1>or:on<Ctas+s.aut or:idCE CHCE Cproject.aut or:idC=A B= 1>4et<array<Ctas+.nameCE Cproject.nameC==A

In this case" we pass a closure as the second parameter to the join<= method" then use the on<=" or:on<= and and:on<= methods to set the conditions.

8rdering
Orderin! is pretty important" you don,t wanna waste resources doin! that with PHP" you could... sure... lots of nasty array:sort<=in!" tons of loops" that wouldn,t be any fun. Let,s pass this responsibility to fluent.
<>p pD;..ta"le<Cs oesC=1>order:"y<CsiQeCE CascC=1>4et<=A

Hmm shoes9 0omen are meant to think about shoes but thats all that came to mind.. 8carey. *nyway its as easy as passin! a field name" and either asc for acendin!" or desc for descendin!. To sort on more columns" simply repeat the order:"y<= chain.

-imiting.. no /aking
0hat if we only want to !et a certain number of results back" in 8=L we would use *&,&9 bah that sounds stupid" Laravel provides ta+e<=.
<>p pD;..ta"le<Cs oesC=1>ta+e<10=1>4et<=A

6ow I want DK shoes9 I should be more worried.. 4ut it,s clear" limitin! is very simple/

Skipping (esults
0e don,t need the first 5 pairs of shoes do we9 They are leather shoes" I like to wear skate shoes" very wide feet you see.. Let,s &ust skip them.
<>p pD;..ta"le<Cs oesC=1>s+ip<L=1>4et<=A

The we !o" now we can s+ip<= the first 5 results" easy as pie/

+ggregates
8ometimes its handy to run basic maths on 2ueries" *3B" .I6" .*C" 8>." and 5O>6T are used all the time to 2uickly !et the result we want with 8=L" and they are all available with the $luent =uery 4uilder" lets take a look.
<>p pD!al H D;..ta"le<Cs oesC=1>a!4<CsiQeC=AD!al H D;..ta"le<Cs oesC=1>min<CsiQeC=A D!al H D;..ta"le<Cs oesC=1>ma'<CsiQeC=AD!al H D;..ta"le<Cs oesC=1>sum<CsiQeC=AD!al H D;..ta"le<Cs oesC=1>count<=A

8imple/ 7on,t for!et that these are tri!!er methods" we don,t need to add 4et<= here. )ou are also welcome to add conditions with ) ere<= or whatever you like/

.3pressions
The methods we have been usin! so far escape and 2uote the parameters you provide automatically" but what if we need somethin! really custom" what if we don,t want anythin! else added9 $or this we can use the D;..ra)<= method" heres an e ample (
<>p pD;..ta"le<Cs oesC=1>update<array<C)ornC H> D;..ra)<C$%F<=C===A

In this 2uery the $%F<= will not be escaped or 2uotes" lots of freedom there" but don,t for!et that spiderman 2uote" be responsible with this power.

99 :or decrementing;
0hat if we want to simply increment or decrement a value9 <asy as pie/
<>p pD;..ta"le<Cs oesC=1>increment<CsiQeC=AD;..ta"le<Cs oesC=1>decrement<CsiQeC=A

8imply pass a field name" and voila/

$nsert
$inally" lets store some data. *ll this time we have been lookin! at readin! data" this will be more fun/ 0ell its 2uite simple really" to insert a new row all we have to do is provide a key+value array to the insert<= method" which is a tri!!er method by the way/
<>p pD;..ta"le<Cs oesC=1>insert<array< C eelsCE CsiQeC H> C12C==A CcolorC H> C ot pin+CE CtypeC H>

0ait" lets !rab the id thats created with this new row" it mi!ht be handy later9 0e can use insert:4et:id<= with the same params for this.
<>p pDid H D;..ta"le<Cs oesC=1>insert:4et:id<array< CtypeC H> C eelsCE CsiQeC H> C12C==A CcolorC H> C ot pin+CE

That,s my weekend pair" lets keep this between us... we now have a nice hot pink pair of heels" in si#e DG in the s oes table of our database.

,pdate
0ait" did I say heels in that last section9 They were hot pink skate shoes" if only we could !o back and fi our mistake" I could update the table and no one would see my shame. Oh we could probably use the update<= method" you see it takes an array with the same synta as insert<=.
<>p pD;..ta"le<Cs oesC=1>update<array< CtypeC H> Cs+ate s oesC==A

Hold on" we aren,t specifyin! a record here" I don,t want to chan!e all my records to skate shoes" it would ruin my wonderful Laravel flip flops. Let,s use a ) ere<= method and that @id we !ot to narrow it down to the record we want. 5hain time/
<>p pD;..ta"le<Cs oesC= H> Cs+ate s oesC ==A 1>) ere<CidCE CHCE Did= 1>update<array< CtypeC

There" we fi ed the problem before anyone noticed.

)elete
To delete a row %please" not the shoes" they are innocent/' we can use the delete<= method with a ) ere<= clause" or simply pass it an id directly to delete a sin!le row" let,s see these methods in action.
<>p pD;..ta"le<Cnot:s oesC=1>) ere<Cte'tureCE CHCE CfuQQyC=1>delete<=A

8imple" fu##y thin!s !one/


<>p pD;..ta"le<Cs oesC=1>delete<Did=A

6O/ 6ot the hot pink skate shoes" you have obviously learned too much" please keep the responsibility and power thin! in mind.. we don,t want any more shoe massacres. In the ne t chapter" we will be movin! on from sho... $luent" and takin! a look at <lo2uent. <lo2uent allows us to treat our database rows as ob&ects" and provides an ele!ant.. or elo2uent solution to handlin! relationships. I would like to thank .a 8chwanekamp for purchasin! the book" and also 7ou!las Brubba who had the followin! to say( Eeep up the !reat work 7ayle/ * wonderful resource. Thank you to the Jlaravel team. Jtaylorotwell you are really chan!in! the php world. Thanks 7ou!/ I,m sure Taylor will also be pleased to hear that he is chan!in! the PHP world" one method at a time/

.lo5uent 8(M
*n O:. is a really useful packa!e" it stands for Ob&ect :elational .apper" sounds pretty complicated ri!ht9 Let,s break it down a little" %add bass beat' the mapper part" is because we are mappin! our PHP ob&ects" or classes to database tables and rows. The :elational part will become clear in the relationships section. There are many O:. solutions out there" but none as <lo2uent as... well <lo2uent. <lo2uent ships with Laravel" and can be used out of the bo . $or this portion I am !oin! to assume you set up your database" as described in the ,i4rations chapter" and that you are familiar with the methods and chainin! from the (luent Xuery ;uilder chapter" we are !oin! to build on these. )ou see <lo2uent is an alternative to usin! $luent" but it shares many of the same methods" the only difference is we are !oin! to be interactin! with <lo2uent models are results" rather than the std%"ject we !et back from $luent" it,s !oin! to make our code look even clearer. Let,s dive ri!ht in and checkout the <lo2uent model.

Creating and using .lo5uent Models


<>p pclass 8ser e'tends 7loKuent@B

*ctually thats it.. no really" I am serious. )ou see" <lo2uent trusts you" it knows that you have already created a nice mi!ration for the users table. It doesn,t need you to tell it about the fields that e ist" its !oin! to trust that you know them" you should" you wrote the mi!ration and made the table. Oh by the way" you did put an increments<CidC= in your table ri!ht9 This is a common practice" and <lo2uent needs this to work. *nother thin! you mi!ht have noticed about the model is that the class is called 8ser and the table is called users" this isn,t a typo. <lo2uent is so clever" that it can detect the plurals for the <n!lish lan!ua!e. Our ob&ect is sin!ular" so we define it as a 8ser" but our database table users will contain any number of users" so Laravel knows to look for a table with a plural of the ob&ect name. )ou may have picked up on the fact that it only detects plurals for the <n!lish lan!ua!e" what if you use another lan!ua!e" or a certain plural doesn,t work for you9 8imply add the word" and its plural version to the array in the application/confi4/strin4s.p p file" now it will work as e pected/ .aybe you don,t like havin! the table name as plural form9 6ot a problem" simply use the static Dta"le class attribute to specify another table name" for e ample..
<>p pclass 8ser e'tends 7loKuent@ pu"lic static Dta"le H Capp:usersCAB

:i!ht" typin! that hu!e model definition must have worn you out %please note the sarcasm'" let,s have a !o at usin! our new model.
<>p pDuser H 8ser..find<1=A

0ait hold on... we have seen this before" do you remember find<= from our $luent chapter" it brin!s back a sin!le result by its primary key. )ou see <lo2uent uses many of the methods used by $luent" this is really convenient because you can use a combination of both 7atabase libraries without for!ettin! which method is for what. 8weet/ $or elo2uent" simply use the ob&ect,s name" and supply a static method" we don,t need to use D;..ta"le<= for this one. )ou can use the result ob&ect in a similar way" the truth is you are now interactin! with an <lo2uent ob&ect" but you couldn,t really tell the difference at this point" lets !et that users name.
<>p pec o Duser1>nameA

)ep thats the same as last time" nice and easy. 0hat if we would rather have our 8ser ob&ect returned as an array9 8imply call the to:array<= method on any <lo2uent model to receive an array instead of an ob&ect.
<>p pDuser H Duser1>to:array<=A

If you want to e clude certain fields from this array" you can add a D idden static attribute to your <lo2uent model" containin! an array of all the fields to e clude" for e ample (
<>p pclass 8ser e'tends 7loKuent@ pu"lic static D idden H array<Cnic+nameC=AB

8ay we want multiple results back9 0e can use the fancy all<= method to brin! back every user" then we can have a se y user party.
<>p pDusers H 8ser..all<=A

0hat we have now" is an array of user ob&ects" we can loop throu!h them to access each one individually" simple as that.
<>p pforeac <Dusers as Duser=@ add:to:se'y:party<Duser=AB

6ice" its really swin!in! in here" 2uite a few !uys thou!h.. well let,s increase our chances" and !et rid of the other !uys. Then it really will be a se y party/
<>p pDse'y:users H 8ser..) ere<Cse'CE CHCE CfemaleC=1>4et<=A

0ahey" lots better/ The eye+candy threshold went up si!nificantly. )ou see we &ust used a ) ere<= chain method" and 4et<= &ust like we did with fluent" nothin! new there" &ust increased clarity. I could cover all the 2uery methods a!ain for returnin! results" but I don,t really need to" simply flick back a chapter" and mentally replace the word $luent with <lo2uent" you will !et the idea. Instead" let,s see what has chan!ed. 5reatin! and updatin! ob&ects %rows' &ust !ot a whole lot better/
<>p pDuser H ne) 8ser<=ADuser1>name H C?aptain #e'ypantsCADuser1>mojo H C100WCA Duser1>sa!e<=A

4est not to invite 5aptain 8e ypants to our party" we won,t !et any action with him around" even his parrot has swa!!er. )ou see we simply create a new 8ser ob&ect" set class attributes for the fields that e ist %we don,t need to set the I7" <lo2uent handles that' and sa!e<= the ob&ect" to write our chan!es to the database. This is commonly known as the -cti!e Record desi!n pattern" its a really nice way of interactin! with our rows" by treatin! them the same as any other ob&ect in our application. It,s like the database and all that nasty 8=L doesn,t even e ist/ If we already have a key+value array describin! our friend ,5aptain 8e ypants, then we can either pass it as a constructor parameter to the new ob&ect" or use the mass+assi!nment method fill<= to add him to the database" check this out..
<>p pDuser H ne) 8ser<array< ==ADuser1>sa!e<=A CnameC H> C?aptain #e'ypantsCE CmojoC H> C100WC

or
<>p pDarr H array< CnameC H> C?aptain #e'ypantsCE H ne) 8ser<=ADuser1>fill<Darr=ADuser1>sa!e<=A CmojoC H> C100WC =ADuser

Please be careful not to let any e tra information slip throu!h when usin! mass+assi!nment" as it could result in a potential security risk. 8o what about updatin! a row9 It,s very similar" e cept we need to 2uery for the user we want to chan!e first" lets see..

<>p pDuser H 8ser..) ere<CnameCE CHCE C?aptain #e'ypantsC=1>first<=A

Here we use first<= because we want to make sure we only !et one ob&ect back" we can,t chan!e the values on an array" we would have to loop throu!h each one" and that would make a lon!er e ample than we need/
<>p pDuser1>mojo H CLWCADuser1>sa!e<=A

0ell I couldn,t take all his mo&o" that wouldn,t be fair. *t least he can come to the party now. 8o you see updatin! is performed e actly the same way as insertin!" e cept we need to find the ob&ect that we want to update first. 7o you remember usin! Dta"le1>timestamps<= with in the mi!rations chapter to make updated:at and created:at fields9 <lo2uent will update these automatically for you" insertin! a timestamp when an ob&ect is created" and updatin! the updated:at field every time you save" if you would like to disable this feature simply add the Dtimestamps class attribute to your model and set it to false.
<>p pclass 8ser e'tends 7loKuent@ pu"lic static Dtimestamps H falseAB

(elationships
:elationships are beautiful. 6o I haven,t !one all soppy. I mean relationships between tables" in <lo2uent they are beautiful. 6one of that ,;OI6, rubbish" we can define ,one+to+one," ,one+to+many, and ,many+to+ many, &ust by addin! some simple methods to our <lo2uent .odels" let,s &ump ri!ht in" you will learn more with a code snippet in front of you.

8n /o 8ne
;umpin! ri!ht in..
<>p pclass 8ser e'tends 7loKuent@ Dt is1> as:one<C&n!iteC=A BB pu"lic function in!ite<= @ return

Let,s !o ahead and assume that we have made an in!ites table and an &n!ite model to contain our se y party invites. 6ow we can retrieve a user,s %or party !uest' invite with a clear e pressive synta " lets take a peek(
<>p pDin!ite H 8ser..find<1=1>in!ite<=1>first<=A

*!ain we are usin! first<= because we only want one result. )ou see by addin! 1>in!ite<=1> to the chain" which is of course our relationship method name" we retrieve the &n!ite ob&ect that is related to our user. This relationship will e ecute two 2ueries (
#7*7?9 N (R%, "users" FH7R7 "id" H 1A#7*7?9 N (R%, "in!ites" FH7R7 "user:id" H 1A

$rom the 2uery" you will see that <lo2uent is lookin! for user:id automatically as the forei!n key" so if we want to use this relationship" we will need to create a user:id inte!er field with our mi!ration" in the &n!ites table. 0hat if we want to call our forei!n key somethin! else9 6o problem" we simply pass a second parameter to the as:one<= method %or other relationship methods' to specify the new field name" for e ample.
<>p pclass 8ser e'tends 7loKuent@ pu"lic function in!ite<= Dt is1> as:one<C&n!iteCE Ct e:in!ite:idC=A BB @ return

but what about the inverse of this relationship" what if we have an Invite" but we want to know who it "elon4s to" this is where the "elon4s:to<= method comes in handy. Let,s take a look at the model.

<>p pclass &n!ite e'tends 7loKuent@ Dt is1>"elon4s:to<C8serC=A BB

pu"lic function user<=

return

* similar synta " but usin! "elon4s:to<= instead" to point out that the forei!n key" e ists in this table. 6ow we can use..
<>p pDuser H &n!ite..find<1=1>user<=1>first<=A

<asy/

8ne /o Many
0hat if we want to return many related items9 0ell as you may have !uessed from the header" there,s a method for that. Let,s take a look. % I say that a lot don,t I9 .aybe it can be my catchphrase. '
<>p p?lass 8ser e'tends 7loKuent@ Dt is1> as:many<CHatC=A BB pu"lic function ats<= @ return

*!ain" you see that we are passin! the ob&ect name in strin! format" with capitali#ation to the as:many<= method. In this e ample" the ats table will need a user:id forei!n key" and then we can use..
<>p pD ats H 8ser..find<1=1> ats<=1>4et<=A

6ote that we could also use a dynamic property with the same name" to retrieve the same results with a shorter synta " for e ample (
<>p pD ats H 8ser..find<1=1> atsA

6icer still/ *s before" you can pass another forei!n key as a second parameter to use that instead" lets move on/

Many /o Many
Here thin!s !et a little more complicated" but don,t worry.. I am here to !et you throu!h this" take my hand 0endy" lets ima!ine that we have two <lo2uent models" 8ser and 9as+" a user may have many tasks" and a task may have many users" for this type of relation ship we will need a third table. This table is known by many names" a Pivot Table" a Lookup Table" an Intermediate table" or <l Pivote Brande. It,s simply a table with two inte!er fields user:id and tas+:id that links the two tables to!ether" formin! a many+to+many relationships. The table is named after both related tables in a plural form" in an alphabetical order" sounds complicated but it looks simple" check it out( tas+s:users Breat" now we have our table" lets form the relationship(
<>p pclass 8ser e'tends 7loKuent@ pu"lic function tas+s<= Dt is1> as:many:and:"elon4s:to<C9as+C=A BB @ return

a!ain" similar synta " with a sli!htly lon!er method name. This time" we can pass an optional second parameter" to specify a different pivot table name. 8imple.

$nserting (elated Models


0hen we are insertin! related models" we can set the user:id or at:id forei!n key ourselves" but thats not very pretty" why not pass the ob&ect instead(
<>p pD at H Hat..find<1=ADuser H 8ser..find<1=ADuser1> ats<=1>insert<D at=A

That looks a lot better" its like handin! ob&ects to each other" much cleaner than dealin! with those inte!er forei!n keys directly. 0ith as:many<= relationships" you can pass an array of field+value pairs to the sa!e<= method to insert or updated related models. $or e ample(
<>p pD at H array< CnameC H> CDennisCE 8ser..find<1=ADuser1> ats<=1>sa!e<D at=A CstyleC H> C(edoraC=ADuser H

5lean (' 0hen we are creatin! a new related item with a many+to+many relationship" if we use the insert<= method" <lo2uent will not only create the new ob&ect" but also update the pivot table with the new entry" for e ample (
<>p pD at H array< CnameC H> CDennisCE 8ser..find<1=ADuser1> ats<=1>insert<D at=A CstyleC H> C(edoraC=ADuser H

4ut what if the ob&ects already e ist" and we &ust want to create the relationship between them9 0e can do this easily with the attac <= by passin! the @id %or the ob&ect' of the ob&ect to be related" let,s see the code.
<>p pDuser1> ats<=1>attac <D at:id=A

The pivot will have been updated for you/ 6e t is a method that I myself have only recently become aware of" I will assume it arrived with <lo2uent in 3.D. 0e can use the sync<= method with an array of ids and once the method has e ecuted" only the id,s in the array will be in the pivot table. 3ery handy/ Here,s a code snippet.
<>p pDuser1> ats<=1>sync<array<TE 7E P==A

'i%ot /ables
0hat if we want access to our pivot table directly" rather than &ust the tables that are related9 <lo2uent provides the pi!ot<= method to accomplish this task.
<>p pDpi!ot H Duser1> ats<=1>pi!ot<=A

6ow we have an array of result ob&ects" &ust like any other 2uery" but for those which relate the users hats. 0hat if we want to retrieve the e act row that has been used to relate an ob&ect9 <asy with the pi!ot dynamic attribute" the official docs has a !reat e ample of this" and I am !oin! to steal it because I am a nasty person. 7on,t worry" I will make it look a bit different" kinda like with your hi!h school assi!nments9
<>p pDuser H 8ser..find<1=Aforeac >created:atAB <Duser1> ats as D at=@ ec o D at1>pi!ot1

6ow we can access the created:at field on the pivot table row" to see when our hat was made. Ok" I,m !ettin! pretty sick of hats" in fact I want to delete my hats" every last one of them. $ortunately I know my user id" its number L" lucky number L. Let,s do it ri!ht now" let,s delete<= all of my hats.
<>p p8ser..find<7=1> ats<=1>delete<=A

There done" cold head from now on" but its worth it now you know how to use the delete<= method.

.ager -oading
<lo2uent !ives the option of 7a4er *oadin4 to help solve the hi!hly debated 6MD issue" if you don,t know what this is" let me break it down for you usin! what we have already learned. Take a look at the followin! snippet of code.
<>p pDusers H 8ser..all<=Aforeac <Dusers as Duser=@ ec o Duser1> at1>siQe<=AB

$or every loop iteration" <lo2uent has to perform another 8=L 2uery" to retrieve that users Hat ob&ect" and find its si#e. 6ow this isn,t !oin! to be a hu!e problem on small data sets" but with hundreds of rows it could drastically affect performance. 0ith ea!er loadin! we can tell <lo2uent to run a #7*7?9 N (R%, atsA when retrievin! the 8ser ob&ect" so that we already have all the data we need. That reduces the amount of strain to only two 8=L 2ueries. .uch better/ Let,s see how we can tell <lo2uent to ea!er load a relation(
<>p pDusers H 8ser..)it <C atC=1>4et<=A

There" now the hat relationship is ea!er loaded. If you want to ea!er load several relationships" simply pass an array to the )it <= method. It,s worth notin! that the )it <= method is static" and as such must always be at the start of the chain. )ou can even ea!er load nested relationships" lets assume our Hat ob&ect has a atstand<= relationship to let us know which stand it,s on" we can ea!er load both of the relationships like this.
<>p pDusers H 8ser..)it <array<C atCE C at. atstandC==1>4et<=A

8imply prefi the relationship name" with the nested ob&ect. 0hat if we want to add some conditions to our ea!er loadin!" maybe we are only !oin! to be usin! blue hats9 Of course we can do this with <lo2uent/ simply pass the relationship name as a key to the array" and a closure containin! conditions as a parameter" this is better e plained throu!h code.
<>p pDusers H 8ser..)it <array<C atC H> function<DKuery= @ CHCE C"lueC=AB==1>4et<=A DKuery1>) ere<CcolorCE

8imple" you can add as many 2ueries as you need to/

Setters and Getters


8etters are handy little methods that allow us to format our new model data in a certain way when it is assi!ned" lets take a look at a code snippet.
<>p ppu"lic function set:pass)ord<Dpass)ord=@ Dt is1 >set:attri"ute<C as ed:pass)ordCE Has ..ma+e<Dpass)ord==AB

0e create a method with the name of the setter" prefi ed with set:" pass it a variable which will receive the field value. 6ow we can use set:attri"ute<= to set a field to its new value" this lets us modify the passed value anyway we like. The snippet above will cause the as ed:pass)ord field to be updated with a hashed version of the supplied value when we call (
<>p pDuser1>pass)ord H "secret:panda:ninja"A

3ery useful/ Betters are the e act opposite" they can be used to ad&ust a value when it is bein! read" for e ample (
<>p ppu"lic function 4et:panda:name<=@ >4et:attri"ute<CnameC=AB return COandaC.Dt is1

6ow if our name is Dayle we can use..


<>p pec o Duser1>panda:nameA

which would !ive ,Panda7ayle,. I haven,t yet decided what we are !oin! to cover in the ne t chapter" but rest assured" it will be an ama#in! feature of Laravel %because they all are" !et it9'.

.%ents
<vents are a way of lettin! other pieces of code" e tend your applications in a neat way. 8ome other applications refer to this type of e tension as a ,Hook,. If you are a ,PHP Buru, you mi!ht see some resemblances to the ,Observer - Observable, desi!n pattern. <vents may have any number of listeners" and firin! them can return a varied number of responses. I think the best way to learn will be to see this in action" let,s take a closer look at <vents in Laravel.

4ire +n .%ent
<>p pDresponses H 7!ent..fire<Cdinner.timeC=A

In this e ample" we ,tri!!er, or ,fire, the event dinner.time which alerts all of the listeners of the event" that it is time to !et your !rub on. The Dresponses variable will contain an array of responses that the listeners of the event will provide" more on that later. 0e can also retrieve the first response from an event" rather than all of them. 0e simply call the first<= method instead of fire<=" now we receive a sin!le result like this.
<>p pDresponse H 7!ent..first<Cdinner.timeC=A

It,s worth notin!" that althou!h we are only receivin! one response" all of the events listeners will be informed" so the event will be fired &ust as it was usin! the fire<= method" but all responses apart from the first" will be i!nored. The third option for firin! an event is the until<= method" this method will fire the event" notifyin! each listener until the first response that is a ,6O6+6>LL, value is returned. The ,6O6+6>LL, value is then passed to the Dresponse variable.
<>p pDresponse H 7!ent..until<Cdinner.timeC=A

0ell now that we know how to fire an event" lets have a look at the other end of the spectrum" we need to know how to re!ister ourselves as a listener. 0e don,t want to miss our dinner/

-isten for an .%ent


To listen for an event" we use the... yeah you probably !uessed it. The listen<= method. 0e hand it the name of the event that we are lookin! for as a strin!" and a closure to be performed when the event has been fired. The result of the closure will be passed back as a response. Let,s take a look.
<>p p7!ent..listen<Cdinner.timeCE function<= @ return Ct an+s for t e 4ru"GCAB=A

If we now call D!al H 7!ent..first<Cdinner.timeC=A the value of D!al will be t an+s for t e 4ru"G. 8imple as that.

.%ents 2ith 'arameters


< tra information can be passed to a listener from a fired event" by passin! an array of values to the event closure. Like this..
<>p pDresponses H 7!ent..fire<Cdinner.timeCE array<1E 2E 0==A

0e can then add parameters to the closure in our listener to ,catch, these values" like so (
<>p p7!ent..listen<Cdinner.timeCE function<DoneE Dt)oE Dt ree= @ for t e 4ru"GCAB=A return Ct an+s

<asy as pie/ 0hich coincidentally is what is for dinner.

-ara%el .%ents
Here are the events that can be found inside the Laravel core. 6ormally you won,t have to interact with these" but once you have become a *ara!el Juru you may feel the need to bend the framework to your will" and usin! these events is one such e ample of doin! so.
<>p p7!ent..listen<Clara!el.lo4CE function<DtypeE Dmessa4e=@B=A

* new laravel lo! entry has been created.


<>p p7!ent..listen<Clara!el.KueryCE function<DsKlE D"indin4sE Dtime=@B=A

*n 8=L 2uery has been performed.


<>p p7!ent..listen<Clara!el.doneCE function<Dresponse=@B=A

Laravels work is done" and the response is ready to be sent.


<>p p7!ent..listen<CT0TCE function<=@B=A

* pa!e could not be found. and many more. 3ote" It is best to prefi your event with the application name to avoid conflicts with other events. This is why all Laravel events start with lara!el..

.3ample ,sage
8o where will usin! <vents come in handy9 0ell ima!ine we have a simple task mana!ement application" these types of applications will obviously have a 8ser type ob&ect to allow our users to lo!in and use the application. 8ser ob&ects can also be created to add more users to the system" lets attach a Laravel <vent to the user creation process..
<>p pDne):user H array<.. user details ere ..=ADu H ne) 8ser<Dne):user=ADu1 >sa!e<=A7!ent..fire<Cmyapp.ne):userCE array<Du1>id==A

*s you can see" we pass the new user,s id value to the ,myapp.newAuser, event" so that all event listeners are aware of which user has been created. 6ow lets create an e tension to our application" the e tension should not interfere with the e istin! code of the application" it could be an e tra library" or a bundle %comin! soon'" anythin! outside of the main application. In our e tension" we are !oin! to add a prefi to the users name %this is somehow useful to our e tension'. Let,s do this by listenin! to the user event.
<>p p7!ent..listen<Cmyapp.ne):userCE function <Duid= @ Duser1>name H C,yapp:C.Duser1>nameA Duser1>sa!e<=AB=A Duser H 8ser..find<Duid=A

0e create a listener" that receives the user id. >sin! this we can retrieve the new user from the database" and apply the chan!es. 6ow we have added some e tra functionality to the application" without editin! its core files. It is the responsibility of the applications author" to insert <vent tri!!ers or fire<= methods" within area,s of the application that are likely to be e tended. 0ithout these events" the application,s source would have to be

modified.

0lade /emplates
Laravel,s 4lade templatin! en!ine" allows you to use very neat lookin! synta to embed PHP code within your views. It also includes a number of shortcuts that allow a cleaner use of e istin! Laravel features. 4lade,s templates are also cached by default" which makes them e tremely fast/ *s always" let,s &ump ri!ht in.

/he 0asics
To enable 4lade templatin!" simply name your views with the e tension ."lade.p p instead of .p p" its as simple as that/ 0hen usin! !ie) files with PHP frameworks" you will often find yourself doin! this..
<>p p ec o D!alA >>

<nablin! PHP short ta!s tidies this up a little..


<>HD!al>>

.. however there is still room for improvement. Lets have a look at how 4lade would handle the same echo statement.
@@ D!al BB

6eat/ The spacin! between the brackets is optional" but I think it looks better with it there. )ou see the contents of the double curly brackets is evaluated" and echoed out. )ou can use any PHP you want in there" for e ample..
@@ L N time<= BB

This snippet will work &ust as well. )ou see all 4lade is doin!" is convertin! @@ D!al BB to <>p p ec o D!alA >>. 4e sure to consider this if you run into any problems with blade/

-ogic
0hat about foreac <= loops" I use loads of them/ I use a lot of if and else too" blade simplifies all of these conditional statements throu!h the use of the ma!ical I si!n" lets take a look.
<>p pIforeac <Dusers as Duser= >name BB</di!>Iendforeac <di! classH"user">@@ Duser1

There" not only cleaner lookin! than all of those u!ly PHP ta!s" but a lot 2uicker to write/ 0hat about ifs and elseifs9 0ell if you are used to PHP alternate synta " you will be able to !uess the result. 8imply replace the <>p p with I and skip the . >> all to!ether/ 0hat we have left is..
Iif <Duser1>name HH CDa!eC= </p>Iendif <p>Felcome Da!eG</p>Ielse <p>Felcome JuestG

3ery simple" here are the other operators you can use with 4lade" they should look familiar (
<>p pIfor <Di H0A Di < 100 1 1A DiYY= $um"er @@ Di BB<"r />Iendfor

and
<>p pIforelse <Dusers as Duser= users.</p>Iendforelse @@ Duser1>name BBIempty <p>9 ere are no

That last one is a little special" its a foreac <= loop" but with an e tra Iempty which will output the

result below if the supplied array is empty. 3ery handy" as this avoids addin! an e tra if statement.

0lade -ayouts
4lade offers another method of writin! comple " or nested layouts. >sin! its clean synta " this could well be the best layout implementation available within the framework. )ou simply have to use it" to understand its beauty. Let,s have a look at our primary template" which is a blade view %in this case named template."lade.p p' like any other.
<GD%?9SO7 H9,*>< tml lan4H"en1J;">< ead> <meta c arsetH"89(1P"> <title>Iyield<CtitleC=</title></ ead><"ody> <di! classH" eader"> Isection<Cna!i4ationC= <li><a refH"3">Home</a></li> refH"3">;lo4</a></li> Iyield:section </ul> </di!> Iyield<CcontentC=</"ody></ tml> <ul> <li><a

Our main template uses the Iyield<= method to define a content re!ion" that can be filled by a view that uses this layout. 8imply pass a strin! to the method to provide a nickname for that content re!ion" that will be used to identify it later. The Isection<= and Iyield:section define a content re!ion" that contains some default data" but can be replaced at a later date. Let,s have a look at a view %pa4e."lade.p p' that makes use of the template we have &ust created.
Ilayout<CtemplateC=Isection<CtitleC=DayleCs Fe"pa4eG IendsectionIsection<Cna!i4ationC= Iparent <li><a refH"3">-"out</a></li>IendsectionIsection<CcontentC= <p>Felcome to DayleCs )e" pa4eG</p>Iendsection < 1>FelcomeG</ 1>

In this view we use the Ilayout<= method to specify that we want to use a view named template as our layout. 6ow we can use Isection<= and Iendsection to replace yielded content re!ions" with the code found between these two methods. In the case of the na!i4ation section" you will notice that we have a Iparent stub inside the content area" 4lade will replace this" with the content from the base template. If we return..
return Vie)..ma+e<Cpa4eC=A

$rom our route-action we can now see our pa!e" wrapped within the layout template" like so..
<GD%?9SO7 H9,*>< tml lan4H"en1J;">< ead> <meta c arsetH"89(1P"> Fe"pa4eG</title></ ead><"ody> <di! classH" eader"> <ul> refH"3">Home</a></li> <li><a refH"3">;lo4</a></li> refH"3">-"out</a></li> </ul> </di!> < 1>FelcomeG</ 1> DayleCs )e" pa4eG</p></"ody></ tml> <title>DayleCs <li><a <li><a <p>Felcome to

Breat/ 0e can also use as many templates as we want to" they are simply normal 4lade views/ 0hat if we want to provide the Isection contents from our *ction-:oute9 8imply call the #ection..inject<= method with the section name" and a strin! representin! the sections contents" for it to be in&ected into the view.
Route..4et<C/CE array<CdoC H> function<=@ return Vie)..ma+e<Cpa4eC=AB==A #ection..inject<CtitleCE C,y #iteC=A

and that,s all/ 6ow you can use 4lade to make your views look clean and efficient" your desi!ner will love you for it.

+uthentication
.any applications will want a layer of *uthentication. If you are writin! a blo!" you don,t want your readers to be able to post new topics" or if you,re workin! with some sensitive data" you don,t want unauthori#ed users accessin! it. $ortunately Laravel has a simple" secure" and hi!hly customi#able *uthentication class" let,s take a look at how we can interact with it.

Setup
4efore we be!in you are !oin! to need to create a new table to store our user details" we can name this table whatever we like" but if we name it users we won,t have to chan!e the *uthentication,s confi!uration file. Here,s how to create a suitable table with the 8chema 4uilder.
<>p p#c ema..create<CusersCE function<Dta"le= @ Dta"le1>increments<CidC=A Dta"le1>strin4<CusernameCE 12P=A Dta"le1>strin4<Cpass)ordCE 2T=AB=A

)ou can add as many additional fields as you like" but this will !et us !oin!. Let,s also create a sample user that we can use to test the authentication process. $irst I should e plain how the Hash class works. )ou can use the Hash class to hash a password usin! the hi!hly secure bcrypt al!orithm" its very simple to use" here is an e ample.
<>p pDpass H Has ..ma+e<Cmy:pass)ord:strin4C=A

In the above snippet we create a bcrypt hash out of our password. 4y storin! the hash in the database instead of the plain te t password" it offers our users some e tra security. )ou will find this is common practice with web applications. If you would like to compare a hashed password with a value" simply use the c ec+<= method" for e ample..
<>p pHas ..c ec+<Cmy:passCE Dpass=A

This will return a boolean result" true on successful match" and false on failure. 6ow that we know how to hash a password" we can create our sample user" I am !oin! to call him 7e ter" you see I am watchin! the T3 show 7e ter while writin! this chapter" it,s !reat to write with back!round noise" try it with codin!" it really works/ Onwards to 7e ter..
<>p pD;..ta"le<CusersC=1>insert<array< Has ..ma+e<C+nifeC===A CusernameC H> CDe'terCE Cpass)ordC H>

6ow we must choose which of the default authentication drivers we wish to use" we have the choice of ,elo2uent, or ,fluent,. The ,fluent, driver will use $luent to interact with the database" and return an ob&ect representin! the the user tables row when we call -ut ..user<=. The eloKuent driver will return an <lo2uent model representin! the user instead. 5onfi!uration for authentication driver" table or ob&ect name" and field names can all be found within Napplication-confi!-auth.php,.
<>p preturn array< Cdri!erC H> CeloKuentCE H> C8serCE Cta"leC H> CusersCE=A CusernameC H> CemailCE CmodelC

Let,s chan!e ,driver, to fluent to use the fluent 2uery builder as the authentication driver" and chan!e the ,username, confi! item to ,username, so that we can lo! our users into our application usin! their username rather than an email address.

<>p preturn array< Cdri!erC H> CfluentCE H> C8serCE Cta"leC H> CusersCE=A

CusernameC H> CusernameCE

CmodelC

Setting up the form


:i!hto/ 0e are !oin! to need a lo!in form" let,s make a pretty one with blade/ 0e love 4lade now ri!ht9 Let,s do it. 5reatin! lo4in."lade.p p.
@@ (orm..open<Clo4inC= BB <G11 c ec+ for lo4in errors flas !ar 11> Iif <#ession.. as<Clo4in:errorsC== <span classH"error">8sername or pass)ord incorrect.</span> Iendif <G11 username field 11> <p>@@ (orm..la"el<CusernameCE C8sernameC= BB</p> <p>@@ (orm..te't<CusernameC= BB</p> <G11 pass)ord field 11> <p>@@ (orm..la"el<Cpass)ordCE COass)ordC= BB</p> <p>@@ (orm..pass)ord<Cpass)ordC= BB</p> <G11 su"mit "utton 11> <p>@@ (orm..su"mit<C*o4inC= BB</p>@@ (orm..close<= BB

That is a beautif.. 8sssh" that was a few chapters a!o now" I,m not into brain washin!" you can let it !o. 8ure is a beautiful form thou!h/ Let,s create a nice route to show the form.
<>p pRoute..4et<Clo4inCE function<= @ return Vie)..ma+e<Clo4inC=AB=A

Let,s make a O%#9 variant of this route" we can use that to handle when the lo!in form is submitted" that way we can use a sin!le >:L for both.
<>p pRoute..post<Clo4inCE function<= @ return Clo4in form sentCAB=A

:i!ht let,s make sure our routes work fine" actually I am pretty sure they will" but this is &ust a habit of mine. If we visit ,http(--localhost-lo!in, and enter some phony data" submit the form" we should !et lo4in form sent.

Handling -ogin
6ote that before we can lo!in" we will need to setup a session driver. This is because Laravel lo!ins are stored in the session" if you head over to application/confi4/session.p p it will list all your options" choose a suitable one. /8)8 .ore information on choosin! a session driver. Breat/ Let,s handle that lo!in attempt" and !o to work on that post route. $irst lets !et the input data that has been posted from the form.
<>p pRoute..post<Clo4inCE function<= @ // 4et O%#9 data CusernameC H> &nput..4et<CusernameC=E Cpass)ordC &nput..4et<Cpass)ordC= =AB=A Duserdata H array< H>

8weet/ 0e have post data" lets put it to use. 0e will use the -ut ..attempt<= method to check if the username and password can be used to lo!in. The !reat thin! about this method" is on success it will automatically create our ,lo!!ed+in, session for us/ .ucho conveniento/ %I never took 8panish" sorry.'.
<>p pRoute..post<Clo4inCE function<= @ // 4et O%#9 data Duserdata H array< CusernameC H> &nput..4et<CusernameC=E Cpass)ordC H> &nput..4et<Cpass)ordC= =A if < -ut ..attempt<Duserdata= = @ // )e are no) lo44ed inE 4o to ome return Redirect..to<C omeC=A B else @ // aut failureG lets 4o "ac+ to t e lo4in return Redirect..to<Clo4inC= 1>)it <Clo4in:errorsCE true=A // pass any error notification you )ant // i li+e to do it t is )ay .= BB=A

6ow if our authentication is successful" the lo!in session is created" and we are redirected to the ome route. Perfect" but before we !o any further" let,s create a lo4out route so that we can lo!out to perform future testin!.
<>p pRoute..4et<Clo4outCE function<= @ Redirect..to<Clo4inC=AB=A -ut ..lo4out<=A return

Here we use the -ut ..lo4out<= method to destroy the lo!in session" and head back to the lo!in pa!e. 0e are now lo!!ed out. :i!ht" now that we have our lo!in workin! perfectly let,s create our super secret home pa!e" add a lo!out link" and welcome our currently lo!!ed in user.
<>p p//1111 9H7 R%897 1111Route..4et<C omeCE function<= @ return Vie)..ma+e<C omeC=AB=A//1111 9H7 V&7F < ome."lade.p p= 1111<di! classH" eader"> Felcome "ac+E @@ -ut ..user<=1>username BBG<"r /> @@ H9,*..lin+<Clo4outCE C*o4outC= BB</di!><di! classH"content"> < 1>#Kuirrel &nfo</ 1> <p>9 is is our super red sKuirrel information pa4e.</p> <p>;e carefulE t e 4rey sKuirrels are )atc in4.</p></di!>

6ow you can test our lo!in loop.. Lo!in" be !reeted with the welcome pa!e" lo!out. :epeat. 7o this at least OKK times to set your mind to rest. 7on,t worry" this is normal behavior" besides.. you !et paid by the hour ri!ht PHP Buru9 )ou will notice that we use -ut ..user<= in the above e ample" this will return a $luent database result ob&ect representin! the current lo!!ed in user. 3ery handy for findin! its id" or echoin! out welcome information.

'rotecting (outes
Ok" we are almost done here/ There is a sli!ht bu!" and security issue that we need to take care of first. Lo!out of the system" %no not the machine you are readin! this on" &ust the site' and head over to the ome >:L by hand. >h oh" now the !ray s2uirrels can see our attack plans without even lo!!in! in/ 0e will need to fi this. *lso because we don,t have a user lo!!ed into the system" we !et an undefined inde' %or somethin! similar' error when tryin! to access the users username. 5ast your mind way back" the solution is there lurkin! in the shadows near the start of the book. 0hat9 6o shadows9 I paid the publisher to put them in... never mind let,s carry on. 7o you remember route filters9 >sin! filters we can run a snippet of code before the route is e ecuted" and if we return somethin! it will be used in place of what we return from our route. 0oah lots of potential there. It,s even easier than that" you see Taylor has a de!ree in amateur mind readin!" he knew we would be writin! this chapter" and he knew we would need to protect a route from non+lo!!ed in users. That is why he created the ,auth, filter" which is included with Laravel as standard. Let,s have a look at the filter itself. %)ou can find this in routes.p p'
<>p pRoute..filter<Caut CE function<=@ Redirect..to<Clo4inC=AB=A if <-ut ..4uest<== return

6eat/ )ou see the -ut ..4uest<= method9 It,s a nicely e pressive method which returns true only if the current re2uest has no lo!!ed in user. 3ery handy/ )ou can also use -ut ..c ec+<= to perform the opposite check" to see if a user is currently lo!!ed in. 0e know these methods do e actly the same thin!" but by providin! clean e pressive method names" usin! the ri!ht one will appear much clearer within your source. *s you can see" if no user is lo!!ed in" the aut filter returns a redirect to the lo!in pa!e" overwritin! the view supplied by our route. *ll we need to do is attach this to our ome route.

<>p pRoute..4et<C omeCE array<C"eforeC H> Caut CE CdoC H> function<= @ Vie)..ma+e<C omeC=AB==A

return

There we !o" now the home route is protected" the undefined notices will never be seen" and unauthori#ed s2uirr... users will no lon!er be able to see the home pa!e. Please remember not to apply the aut filter to your lo4in >:I" you will e perience a terrible loop/

Customi<ation
I know what you,re thinkin!. 0hat if I don,t want to use <lo2uent or $luent" this seems very limited/ Please" this is Laravel. )ou should have learned this by now/ Laravel allows you to create custom classes known as ,*uth 7rivers, so that you can modify parameters or hook into any authentication system you like. 8imply create a new class. I like to put mine in application/li"raries so that they are autoloaded for me/
<>p p// application/li"raries/myaut .p pclass ,yaut e'tends *ara!el/-ut /Dri!ers/Dri!er @ pu"lic function attempt<Dar4uments H array<== B pu"lic function retrie!e<Did= @ BB @

)our authentication driver must e tend *ara!el/-ut /Dri!ers/Dri!er and contain the two methods listed above. The first method accepts the array of username and pass)ord and is used to authenticate usin! your own method. On a successful authentication you should make a call to the lo4in<= method of the parent to inform Laravel that the authentication worked" for e ample..
<>p ppu"lic function attempt<Dar4uments H array<==@ Dusername H Dar4uments5CusernameC6A Dpass)ord H Dar4uments5Cpass)ordC6A Dresult H my:lo4in:met od<DusernameE Dpass)ord=A if<Dresult= @ return Dt is1 >lo4in<Dresult1>idE array:4et<Dar4umentsE Cremem"erC==A B return falseAB

The lo!in method accepts an identifier %that can be used later to retrieve the user' and the value of the ,remember, key from our ar!uments array. On authentication failure the method should always return false. The retrie!e<= method is handed the identifier that you previously passed to the lo4in<= method" you can use this to return an ob&ect that represents the current user. $or e ample..
<>p ppu"lic function retrie!e<Did=@ return 4et:my:user:o"ject<Did=AB

Breat/ 6ow we have a workin! authentication driver. 4efore we can use it we will need to re!ister it with the -ut class. *dd the followin! code to your application/start.p p.
<>p p-ut ..e'tend<Cmyaut CE function<= @ return ne) ,yaut <=AB=A

Pass an identifier for your authentication driver as the first parameter to -ut ..e'tend<=" the second parameter is a 5losure that is used to return a new instance of the class. *ll that is left to do is update your application/confi4/aut .p p file to point to this new authentication driver..
<>p pCdri!erC H> Cmyaut CE

and now en&oy usin! your authentication system in the usual way/

/he 0log /utorial


It,s finally time to write our first full application. If you haven,t read the other chapters you mi!ht find this a little tricky" let,s have a look at what we are !oin! to be usin! to create the blo!. :outes .i!rations <lo2uent 4lade Templates *uthentication $ilters

Let,s have a look at the plan 8tan" and see e actly what we are !oin! to be buildin!.

/he )esign
0e are !oin! to build a three pa!e blo!. The first pa!e will consist of a listin! of blo! posts" similar to the front of a 0ordpre.. 0ordpush blo!. The ne t pa!e will be the full1!ie) pa!e" it is the pa!e you reach when you click an article that you want to read. The final pa!e will be the pa!e where we write our posts. 6ormally you would have the ability to edit or delete posts" but we can add all that stuff later. I,m not countin! the usual lo!in pa!e in that count" as it is used with any application that implements authentication. Let,s think about the database schema for a moment. 0e know that we are !oin! to need a table to store our blo! posts. 0e will also need a table to store our users" and we are !oin! to need some form of relationship between them both. Let,s map this out and think about the fields. 9a"le . posts 4ield id title body authorAid createdAat updatedAat 9a"le . 4ield /ype I6T<B<: 3*:5H*:%DGO' T<CT I6T<B<: 7*T<TI.< 7*T<TI.< users

/ype id I6T<B<: username 3*:5H*:%DGO' nickname 3*:5H*:%DGO' password 3*:5H*:%HP' createdAat 7*T<TI.< updatedAat 7*T<TI.< Ok that looks !ood" we can use the aut or:id field on the Oost ob&ect to reference the 8ser ob&ect which represents the post,s author. :i!ht" to work/

0asic Setup
$irst of all you will need to setup your database and session driver" you should know how to do this by

now. I will be usin! my8=L as my database as always. 6ow let,s create mi!rations for our tables" a!ain usin! *rtisan as we did in the mi!rations chapter.
p p artisan mi4rate.ma+e create:users

6ow our schema for up<= alon! with default user account.
<>p p#c ema..create<CusersCE function<Dta"le= @ Dta"le1>increments<CidC=A Dta"le1>strin4<CusernameCE 12P=A Dta"le1>strin4<Cnic+nameCE 12P=A Dta"le1 >strin4<Cpass)ordCE 2T=A Dta"le1>timestamps<=AB=AD;..ta"le<CusersC=1 >insert<array< CusernameC H> CadminCE Cnic+nameC H> C-dminCE Cpass)ordC H> Has ..ma+e<Cpass)ordC===A

and let,s update our do)n<= method &ust in case.


<>p p#c ema..drop<CusersC=A

Let,s also create our posts mi!ration" I bet you didn,t see that comin!9
p p artisan mi4rate.ma+e create:posts

The schema for up..


<>p p#c ema..create<CpostsCE function<Dta"le= @ Dta"le1>increments<CidC=A Dta"le1>strin4<CtitleCE 12P=A Dta"le1>te't<C"odyC=A Dta"le1 >inte4er<Caut or:idC=A Dta"le1>timestamps<=AB=A

and let,s tear down this table in do)n<= too.


<>p p#c ema..drop<CpostsC=A

Let,s run our mi!rations and !et those tables in place.


p p artisan mi4rate.installp p artisan mi4rate

$inally let,s update our authentication confi!uration in application/confi4/aut .p p to use fluent as an authentication driver" and username as a lo!in identifier.
<>p preturn array< Cdri!erC H> CfluentCE H> C8serCE Cta"leC H> CusersCE=A CusernameC H> CusernameCE CmodelC

There" now we are ready to create our <lo2uent models.

.lo5uent Models
:i!ht" you know e actly how to create <lo2uent models" so let,s &ust have a look at the source.
<>p pclass 8ser e'tends 7loKuent@ pu"lic function posts<= @ return Dt is1> as:many<COostC=A BBclass Oost e'tends 7loKuent@ pu"lic function aut or<= @ return Dt is1>"elon4s:to<C8serCE Caut or:idC=A BB

6ice and simple" we have our 8ser ob&ect which as:many posts" and our Oost ob&ect which "elon4s:to a user.

(outes
Ok" we have our tables" we have models" and since we are now followin! my work flow let,s create placeholders for the routes we will need.
<>p pRoute..4et<C/CE function<= @ // t is is our list of postsB=ARoute..4et<C!ie)/<.num=CE function<Dpost= @ // t is is our sin4le !ie)B=ARoute..4et<CadminCE function<= @ // s o) t e create ne) post

formB=ARoute..post<CadminCE function<= @ formB=ARoute..4et<Clo4inCE function<= @ formB=ARoute..post<Clo4inCE function<= @ formB=ARoute..4et<Clo4outCE function<= @

// andle t e create ne) post // s o) t e lo4in // andle t e lo4in // lo4out from t e systemB=A

:i!ht" those are done. *s you can see I am usin! B<T-PO8T to show and handle forms with the same >:I.

Views
Let,s start by creatin! a blade layout as a wrapper for our application. templates/main."lade.p p
<GD%?9SO7 H9,*>< tml lan4H"en1J;">< ead> <meta c arsetH"89(1P"> <title>Fordpus </title> @@ H9,*..style<Ccss/style.cssC= BB</ ead><"ody> <di! classH" eader"> < 1>Fordpus </ 1> < 2>?ode is *immeric+s</ 2> </di!> <di! classH"content"> Iyield<CcontentC= </di!></"ody></ tml>

*s you can see we have a very simple HT.L5 template" with a 588 style+sheet %which we will not be coverin!" by all means use it to make your blo! pretty.. but this is not a desi!n book' and a yielded content area" for our pa!e content. 0e are !oin! to need a lo!in form" so our post authors can create new entries. I am !oin! to steal this view from the last tutorial" and hack it a bit to work with blade layouts. This is actually !ood practice" re+ use anythin! you can and eventually you will have built up your own Laravel development toolkit. pa4es/lo4in."lade.p p
Ilayout<Ctemplates.mainC=Isection<CcontentC= @@ (orm..open<Clo4inC= BB <G11 c ec+ for lo4in errors flas !ar 11> Iif <#ession.. as<Clo4in:errorsC== <span classH"error">8sername or pass)ord incorrect.</span> Iendif <G11 username field 11> <p>@@ (orm..la"el<CusernameCE C8sernameC= BB</p> <p>@@ (orm..te't<CusernameC= BB</p> <G11 pass)ord field 11> <p>@@ (orm..la"el<Cpass)ordCE COass)ordC= BB</p> <p>@@ (orm..pass)ord<Cpass)ordC= BB</p> <G11 su"mit "utton 11> <p>@@ (orm..su"mit<C*o4inC= BB</p> @@ (orm..close<= BBIendsection

*s you can see" our lo!in form is usin! our newly created blade layout. Let,s also create our ,5reate 6ew Post, form. pa4es/ne)."lade.p p
<>p pIlayout<Ctemplates.mainC=Isection<CcontentC= @@ (orm..open<CadminC= BB <G11 title field 11> <p>@@ (orm..la"el<CtitleCE C9itleC= BB</p> @@ Derrors1>first<CtitleCE C<p classH"error">.messa4e</p>C= BB <p>@@ (orm..te't<CtitleCE &nput..old<CtitleC== BB</p> <G11 "ody field 11> <p>@@ (orm..la"el<C"odyCE C;odyC= BB</p> @@ Derrors1>first<C"odyCE C<p classH"error">.messa4e</p>C= BB <p>@@ (orm..te'tarea<C"odyCE &nput..old<C"odyC== BB</p> <G11 su"mit "utton 11> <p>@@ (orm..su"mit<C?reateC= BB</p> @@ (orm..close<= BBIendsection

Get Coding
$inally it,s time to !et our hands dirty" let,s start with the authentication routine. $irst we need to link our lo!in route to the lo!in form view.
<>p pRoute..4et<Clo4inCE function<= @ return Vie)..ma+e<Cpa4es.lo4inC=AB=A

There" that wasn,t so hard. 6ow let,s handle the authentication in the O%#9 route in the usual way.
<>p pRoute..post<Clo4inCE function<= @ Duserdata H array< CusernameC H>

&nput..4et<CusernameC=E Cpass)ordC H> &nput..4et<Cpass)ordC= =A < -ut ..attempt<Duserdata= = @ return Redirect..to<CadminC=A B @ return Redirect..to<Clo4inC= 1>)it <Clo4in:errorsCE true=A BB=A

if else

6ow we can lo!in to our system" if you have any trouble understandin! these topics" refer to the previous chapters" we aren,t coverin! anythin! new here. Let,s create the lo!out route" so we can test the lo!in process.
<>p pRoute..4et<Clo4outCE function<= @ Redirect..to<C/C=AB=A -ut ..lo4out<=A return

Let,s add a small profile section to the header of our main template. 0e can use this to lo!in or lo!out from the system.
<di! classH" eader"> Iif < -ut ..4uest<= = @@ H9,*..lin+<CadminCE C*o4inC= BB Ielse @@ H9,*..lin+<Clo4outCE C*o4outC= BB Iendif < r /> < 1>Fordpus </ 1> < 2>?ode is *immeric+s</ 2></di!>

6ow to add the aut filter to both admin routes" you will notice that admin is the only route that needs protectin!" since we want people to be able to browse our blo!" but not write anythin!.
<>p pRoute..4et<CadminCE array<C"eforeC H> Caut CE CdoC H> function<= @ // s o) t e create ne) post formB==ARoute..post<CadminCE array<C"eforeC H> Caut CE CdoC H> function<= @ // andle t e create ne) post formB==A

Let,s also attach the create new post form to the admin J79 route while we are here. 0e should also hand the current lo!!ed in user to this view" that way we can use the user ob&ects id field to identify the author.
<>p pRoute..4et<CadminCE array<C"eforeC H> Caut CE CdoC H> function<= @ -ut ..user<=A return Vie)..ma+e<Cpa4es.ne)C=1>)it <CuserCE Duser=AB==A Duser H

6ow that we have a handle on our currently lo!!ed in user" let,s add that information to the create ne) post view" to identify our author.
<>p p...@@ (orm..open<Clo4inC= BB <G11 aut or 11> @@ (orm.. idden<Caut or:idCE Duser1>id= BB <G11 title field 11> <p>@@ (orm..la"el<CtitleCE C9itleC= BB</p> <p>@@ (orm..te't<CtitleC= BB</p>...

0e can now identify our author" and the create ne) post pa!e is ready. 0e don,t need to link to it" we want it hidden. 0e can simply hit the >:L /admin if we want to create a new post. Let,s handle a new post creation.
<>p pRoute..post<CadminCE function<= @ // letCs 4et t e ne) post from t e O%#9 data // t is is muc safer t an usin4 mass assi4nment Dne):post H array< CtitleC H> &nput..4et<CtitleC=E C"odyC H> &nput..4et<C"odyC=E Caut or:idC H> &nput..4et<Caut or:idC= =A // letCs setup some rules for our ne) data // &Cm sure you can come up )it "etter ones Drules H array< CtitleC H> CreKuiredMmin.0Mma'.12PCE C"odyC H> CreKuiredC =A // ma+e t e !alidator D! H Validator..ma+e<Dne):postE Drules=A if < D!1>fails<= = @ // redirect "ac+ to t e form )it // errorsE input and our currently // lo44ed in user return Redirect..to<CadminC= 1>)it <CuserCE -ut ..user<== 1>)it :errors<D!= 1>)it :input<=A B // create t e ne) post Dpost H ne) Oost<Dne):post=A Dpost1>sa!e<=A // redirect to !ie)in4 our ne) post return Redirect..to<C!ie)/C.Dpost1>id=AB=A

6ow we should be able to create some blo! posts" !o ahead/ 0rite a few articles so we have somethin! to view in our list all posts view. 8peakin! of which" let,s !et to work on that.

<>p pRoute..4et<C/CE function<= @ // lets 4et our posts and ea4er load t e // aut or Dposts H Oost..)it <Caut orC=1>all<=A return Vie)..ma+e<Cpa4es. omeC= 1>)it <CpostsCE Dposts=AB=A

0e also need a view to list all of our blo! posts" here we !o.. pa4es/ ome."lade.p p
<>p pIlayout<Ctemplates.mainC=Isection<CcontentC= Iforeac <Dposts as Dpost= <di! classH"post"> < 1>@@ H9,*..lin+<C!ie)/C.Dpost1>idE Dpost1 >title= BB</ 1> <p>@@ su"str<Dpost1>"odyE0E 120=.C 5..6C BB</p> <p>@@ H9,*..lin+<C!ie)/C.Dpost1>idE CRead more ZrarrAC= BB</p> </di!> Iendforeac Iendsection

$inally we need a full view for our blo! posts" let,s call it.. pa4es/full."lade.p p
<>p pIlayout<Ctemplates.mainC=Isection<CcontentC= <di! classH"post"> < 1>@@ H9,*..lin+<C!ie)/C.Dpost1>idE Dpost1>title= BB</ 1> <p>@@ Dpost1 >"ody BB</p> <p>@@ H9,*..lin+<C/CE CZlarrA ;ac+ to inde'.C= BB</p> </di!>Iendsection

0e also need to add a route to enable the view..


Route..4et<C!ie)/<.num=CE function<Dpost= @ Dpost H Oost..find<Dpost=A Vie)..ma+e<Cpa4es.fullC= 1>)it <CpostCE Dpost=AB=A return

6ow we have a fully workin! blo!" with &ust the basics. Let,s take a 2uick look at what we could do to improve it. These improvements may come up in future chapters.

/he 4uture
'agination
0e could add some pa!ination to the posts list pa!e" which would come in handy when the post count !ets len!thy.

.dit = )elete 'osts


*ddin! the functionality to edit or remove posts wouldn,t be a lot of work" and would allow for maintenance to be performed on the blo!.

'ost Slugs
0e could create post slu!s to use instead of post ids in our >:Ls" this will result in better search en!ine optimi#ation.

,nit /esting
>nit testin! can be a very useful tool for a web developer" it can be used to check whether addin! a feature" or modifyin! the codebase in some way has accidentally altered another feature" causin! it to fail. 8ome developers even practice Test+7riven development" where tests are written before the code" to ensure that the code bein! written meets all re2uirements. Laravel provides the tests directory to contain all of your applications tests" and even adds a helper command to *rtisan" the 5LI interface for runnin! PHP>nit test cases. 6ot only can the application be tested" but bundles can also contain their own test suites. In fact Laravel has a bundle devoted to testin! the core features of the framework" it can be found in the Laravel tests !ithub respository.

$nstallation
6o we,re not !oin! to cover the Laravel installation a!ain/ Laravel uses the PHP>nit software to e ecute its tests" before we can use the unit testin! features of Laravel we will need to install this software. Installation of PHP>nit can vary from operatin! system to operatin! system" therefore I think it would be best to look at the official documentation for PHP >nit to find installation instructions. )ou will find the installation pa!e here.

Creating a /est
Let,s take a look at a test case" fortunately Laravel has included an e ample test case for us/
<>p p// application/tests/e'ample.test.p pclass 9est7'ample e'tends OHO8nit:(rame)or+:9est?ase @ /NN N 9est t at a 4i!en condition is met. N N Ireturn !oid N/ pu"lic function test#omet in4&s9rue<= @ Dt is1 >assert9rue<true=A BB

*s you can see we create our test cases in a file with the e tension test.p p" the name of the class must start with the word 9est and it must e tend the class OHO8nit:(rame)or+:9est?ase these are limitations set not by Laravel" but by the PHP>nit software. * PHP>nit test case may contain any number of tests" as camel+cased actions" prefi ed with the word test. Our tests can contain a number of different assertions" that decide whether our tests will pass or fail. * full list of assertations can be found on the PHP>nit documentation website.

(unning /ests
Tests can be ran usin! the *rtisan command line interface" simply use the test command to run all test cases.
p p artisan test

and the result..


OHO8nit 0.2.10 "y #e"astian ;er4mann.?onfi4uration read from / ome/daylerees/)))/lara!el/de!elop/p punit.'ml.9ime. 0 secondsE ,emory. 2.2L,"%V <1 testE 1 assertion=

0ith the %V part appearin! in bri!ht !reen to show us that the tests have passed.

Of course we knew that the test would succeed because we are usin! the assert9rue<= method to check the value true. There is no way it could fail. Let,s bully the test so that it will fail" we will simply chan!e the parameter to false.
...Dt is1>assert9rue<false=A...

and the result (


OHO8nit 0.2.10 "y #e"astian ;er4mann.?onfi4uration read from / ome/daylerees/)))/lara!el/de!elop/p punit.'ml(9ime. 0 secondsE ,emory. 2.L0,"9 ere )as 1 failure.1= 9est7'ample..test#omet in4&s9rue(ailed assertin4 t at false is true./ ome/daylerees/)))/lara!el/de!elop/application/tests/e'ample.test.p p.12/usr/" in/p punit.T2(-&*8R7#G9ests. 1E -ssertions. 1E (ailures. 1.

6ow we have some bri!ht red lines to indicate that the tests have failed" includin! some details about why the test failed. If we wanted to test a bundle" we would simply pass a parameter to the test command" for e ample.
p p artisan test my"undle

/esting /he Core


Laravel,s core is well unit tested" if you would like to run the tests yourself" here is how you can do it.

$nstall the tests bundle


7ownload the tests bundle from !ithub and e tract it in the "undles/lara!el1tests directory. Or use p p artisan "undle.install lara!el1tests to achieve the same !oal. 6ow simply use the command test.core to e ecute the core test packa!e.
p p artisan test.core

Caching
Laravel offers a very simple to use 5achin! class" allowin! you to easily cache anythin! you need to" for however lon! you like. 5onfused9 Let,s take a look at it in action.

Setup
There are many ways to store your cached data" you must set a driver statin! which method you want to use in application/confi4/cac e.p p. The options are ,file," ,memcached," ,apc," ,redis," and ,database,. )ou may e perience better performance with ,apc, or ,memcached, but I am !oin! to use ,file, based cachin! for its simplicity to setup.
<>p pCdri!erC H> CfileCE

Setting %alues
)ou can use the put<= or fore!er<= methods to store data in the 5ache. The put<= method allows you to store a value for a set period of time" let,s have a look at a code sample..
<>p pDdata H Ccomplicated:4enerated:dataCA?ac e..put<CmydataCE DdataE 10=A

Let,s pretend that Ddata wasn,t &ust an assi!ned strin!" but the result of a complicated al!orithm that would take some time to process" we don,t want to process this data all the time" so we keep it in the cache. The first parameter to the method is the key" a strin! used to identify the cached data. The second parameter is the data itself" and the third is the amount of time in minutes" to cache to the data. The fore!er<= method takes only the first two parameters" and acts e actly as the name implies. The data is cached forever.

(etrie%ing Values
To retrieve an item from the cache" use the 4et<= method" and supply the key" for e ample..
<>p pDdata H ?ac e..4et<CmydataC=A

4y default" if the cached item does not e ist" or has e pired already" the method will return $8**. However" you can pass an optional second parameter to provide an alternate default value.
<>p pDdata H ?ac e..4et<CmydataCE Ccomplicated dataC=A

)ou can also pass a closures as the second parameter" and the value returned by the closure will be used if the cache data does not e ist. The closure will only be e ecuted if the key does not e ist.

+ better way
)ou mi!ht find yourself usin! the as<= method" to check if a cached item e ists" and fallin! into this familiar pattern..
<>p pif <G ?ac e.. as<CmydataC==@ ?ac e..put<CmydataCE DdataE 10=A Ddata H Ccomplicated:4enerated:dataCA Breturn DdataA

However" you can use the remem"er<= method as a much more ele!ant solution. The remem"er<= method will return the value if it e ists in the cache" or it will store and return the value of the second

parameter for a defined len!th of time" for e ample..


<>p preturn ?ac e..remem"er<CmydataCE function <= @ Ccomplicated:4enerated:dataCABE 10=A return

Of course the closure will not be e ecuted unless the key does not e ist" or has e pired. Have fun usin! the 5ache/

+utoloading Classes
0ith many frameworks" knowin! where to put your files" and how to load class definitions can be a tricky topic" however with Laravel there are no strict rules applied to the layout of your application. Laravel,s auto loader is a clever library which simplifies the loadin! of classes with various namin! or sub+folder conventions. It is fle ible enou!h to handle the addition of comple libraries or packa!es with ease. Let,s have a look at the functions we have available.

Mappings
.appin!s are the simplest method of loadin! classes" you can pass the auto loader an array of 5lass name to file location key+value pairs and Laravel will handle the rest. It,s efficient autoloader will only load the re2uired class definition when the class is used. 4y default the *utoloader mappin!s are set within the start.p p file" you can however use the class from anywhere" but the start.p p file is a !ood choice due to it bein! loaded early. Let,s take a look at a mappin!..
<>p p// application/start.p p-utoloader..map<array< pat <CappC=.Cli"raries/ff/cloud.p pCE C9ifaC pat <CappC=.Cli"raries/ff/tifa.p pCE==A C?loudC H> H>

The pat <CappC= is a handy helper method to retrieve the absolute path to your pro&ects application folder. )ou can also retrieve absolute paths to other folders usin! the pat <= method" here is a short list. Method )irectory path%,app,' application path%,sys,' laravel path%,bundle,' bundles path%,stora!e,' stora!e In the mappin! e ample" you see that we specify our 5lass name as the array inde " and the file and location as the value" now if we wish to use the ?loud class..
<>p pDc H ne) ?loud<=A

Laravel,s autoloader will ,detect, %php ma!ic methods' that a class definition needs to be loaded" it will look at the mappin! definitions to see if our 5lass e ists there" and proceed to include<= the source.

)irectory Mapping
If you have a number of 5lasses which follow the 5lass name to lower+case file name pattern" you may want to specify the directory" rather than each file individually. )ou can do this by usin! the directories<= method of the *utoloader" however this time you need only supply an array of values as locations and file names. $or e ample..
<>p p-utoloader..directories<array< pat <CappC=.CsmurfsC==A

6ow all of our classes inside the application/smurfs directory will be auto loaded" so lon! as their file name matches the lower+case of their 5lass name.

amespace Mapping
PHP 5.3 saw the arrival of namespacin!. *lthou!h far from perfect" namespacin! allow the P8:+K convention of loadin! files. >nder the P8:+K" namespaces are used to indicate directory structure" and class names are used to identify the file name" therefore we can assume that..

<>p p namespace Oaladin/,a4eAclass Orincess@

// so prettyB

will live in the file.. paladin/ma4e/princess.p p 4efore we can use this convention" Laravel needs to know where our root namespace folder is. 0e can help it find our files by usin! the namespaces<= method of the -utoloader class" for e ample..
<>p p-utoloader..namespaces<array< COaladinC H> pat <Cli"rariesC=.CpaladinC==A

*s you can see we pass an array to the method. The array key represents the name of the root namespace" in this case Oaladin and the and array value is used to indicate the root folder that is matched by this namespace" in my e ample application/li"raries/paladin.

Mapping ,nderscores
0ell we don,t actually need to map the underscore" it,s sittin! ri!ht there on the keyboard" always watchin!" &ud!in!... Look I,m sorry underscore" I may abuse you a little but it,s purely out of love. 5amel+ casin! simply looks wron! to me/ 8orry about that outburst" we will discuss it later in private. The reason that the title is named mappin! underscores" is because in ,ye olde, days of PHP" before namespaces %and Laravel' had arrived" many developers chose to use underscores within file names to separate sub directories. Laravel offers the underscored method on the *utoloader to accommodate this type of class loadin!. Once more" pass an array with the key representin! the class prefi " and the value representin! the root directory" for e ample..
<>p p-utoloader..underscored<array< COaladinC H> pat <CappC=.Cjo"s/pldC==A

and now the 5lass Oaladin:*i4 t:Vni4 t will have its definition loaded from the file application/jo"s/pld/li4 t/+ni4 t.p p. 8o now that you know how to auto load your classes with Laravel" you will no lon!er have to plaster your source code with include<= statements/ I would like to say thanks to <nri2ue Lope#" who !ets to break the character limit because he was clever enou!h to comment bilin!ually. Bracias <nri2ue/ 0ith Laravel I think what I want and not how to write it. I en&oy pro!rammin!. %5on Laravel pienso 2uQ es lo 2ue 2uiero y no como escribirlo. .e divierto pro!ramando.'

Configuration
Laravel has many confi!uration files in application/confi4 to tweak almost every feature that the framework offers. 0ouldn,t it be !reat if you could create your own confi!uration files this way9 0ell today is your lucky day" because you can/

Creating new Configuration 4iles


Laravel confi! files are simply PHP files that live in application/confi4 or a subdirectory" and return a PHP array. $or e ample..
<>p p// application/confi4/ourconfi4.p preturn array< trueE=A CsiQeC H> 2E CeatC H>

)ou can use comments to make your confi! files more descriptive" I like to use the style of the comments Laravel provides" for e ample..
<>p p// application/confi4/ourconfi4.p preturn array< /N M111111111111111111111111111111 M #iQe M111111111111111111111111111111 M 9 is is t e siQe of my t in4. M N/ CsiQeC H> 2E=A M

I,m sure you can come up with a better description/ )ou will have noticed by now that Laravel confi!uration files are key+value pairs" with the array inde representin! the key" and the value... its value. The value of the settin! can be any value or ob&ect that PHP supports" it can even be a closure. 4y providin! a closure you are makin! it easy for the user to chan!e the confi!uration to enable it to be loaded from another source" for e ample..
<>p p// application/confi4/ourconfi4.p preturn array< /N M111111111111111111111111111111 M #iQe M111111111111111111111111111111 M M 9 is is t e siQe of my t in4. M N/ CsiQeC H> function<= @ DsiQe H file:4et:contents<Cpat /to/file.jsonC=A DsiQe H json:decode<DsiQe=A return DsiQeA BE=A

6ow our ,si#e, confi!uration is read from the ;8O6 contents of a file" simple/

(eading Configuration
0e can read a confi!uration settin! usin! the 4et<= method..
<>p pDoption H ?onfi4..4et<Courconfi4.siQeC=A

8imply pass a strin! to the method" with the name of the file a period %.' and the name of the confi!uration key. The value will be returned. If your confi!uration file is in a subdirectory you will need to use e tra periods to indicate the subdirectories" for e ample..
<>p pDoption H ?onfi4..4et<Courconfi4.su".directory.siQeC=A

8ometimes it,s useful to retrieve the entire confi!uration array" to do this simply specify the filename without the option. To retrieve the entire confi!uration array from our file we would use.
<>p pDoption H ?onfi4..4et<Courconfi4C=A

Setting Configuration
To set a confi!uration item" use the set<= method. The first parameter represents the file and confi!uration item name" in the same format as the 4et<= method. The second parameter is the value you wish to set.

<>p p?onfi4..set<Courconfi4.siQeCE 7=A

If a confi!uration item e ists within a confi!uration file" it will be written in the runtime confi!uration when you use set<=" however it will not be overwritten in the confi!uration file itself. If a confi!uration item doesn,t e ist" a call to the set<= method will create it" but a!ain not within the confi!uration file. Try to put as many confi!urable settin!s as possible from your application into confi!uration files" it will make it much easier to confi!ure if you have to move or redistribute the application.

/he $oC Container


The Io5 container is a tricky sub&ect" many people are confused by its description in the documentation" and for a short time I was included in those people. * !reat deal of research" and the support of the fantastic Laravel community %&oin us in Rlaravel on freenode I:5' has cleared up the topic nicely. Hopefully I will be able to shed some li!ht on this mysterious topic. Io5 stands for Inversion of 5ontrol" I don,t want to complicate thin!s with a full description" there are many online articles which will cover the nerdier side of this topic. Instead think of the container as ,Invertin! the 5ontrol, or ,Handin! control back to Laravel, to resolve our ob&ects. That,s what the container is all about" resolvin! ob&ects. Other than its use for in&ectin! dependencies for use in unit tests %we will cover this later' you can simply think of the Io5 container as a ,shortcut, for resolvin! comple ob&ects" or followin! a sin!leton pattern" without the usual class associated with the pattern. .ore on sin!letons later" let,s have a look at re!isterin! a ob&ects with the container.

(egistering 8b&ects
Let,s use our ima!inations" like the bi! purple dinosaur on the T3 tau!ht us. 0e will be ima!inin! a class called ,7iscoball, which will be used all over our application for various !roovy purposes. >nfortunately" our 7iscoball class re2uires a lot of confi!uration before it can be used" let,s have a look at that.
<>p pDd" H ne) Disco"all<Disco"all..#H&$S=ADd"1>confi4ure:s inyness<Cma'C=ADd"1 >spin:speed<CPU00rpmC=A

0oah/ That,s a lot of settin!s. 6ow it would soon !et borin! to have to instantiate and setup our discoball every time we want to use it. Let,s let the Io5 container instantiate it for us" and &ump ri!ht in with a code sample. I like to put this code into start.php" but you can put it anywhere you like" as lon! as your ob&ects are re!istered before you try to resolve them.
<>p p// application/start.p p&o?..re4ister<Cdisco"allCE function<= @ // instantiate our o"ject as "efore Dd" H ne) Disco"all<Disco"all..#H&$S=A Dd"1 >confi4ure:s inyness<Cma'C=A Dd"1>spin:speed<CPU00rpmC=A // and t e o"ject as t e result of t e closure return Dd"AB=A

0e use the &o?..re4ister<= method to re!ister our ob&ect with the controller. The first parameter is a strin! that will be used to resolve the ob&ect later" I used the word ,discoball, as it made the most sense to me. The second parameter is a closure that we can use to instantiate our ob&ect. Inside the closure you will see the familiar discoball confi!uration code" and we will return the confi!ured discoball ob&ect from the closure. Breat/ Our ob&ect is re!istered" and that,s all there is to the Io... &ust kiddin!. Let,s have a look at how we can use our re!istered ob&ect.

(esol%ing 8b&ects
6ow we have our disco ball re!istered" let,s see how we can !et it back. Let,s make a call to resolve.
<>p pDd" H &o?..resol!e<Cdisco"allC=A

*nd that,s it/ Instead of creatin! and confi!urin! a new instance of our discoball each time" we make a call to the resol!e<= method" passin! the strin! that identifies the ob&ect and the Io5 container will e ecute the closure we created in the first section" and return our instantiated and confi!ured discoball ob&ect.

Handy" and saves many lines of code/ )ou can re!ister and resolve as many ob&ects as you want" !o ahead and try it. $or now lets move on to sin!letons.

Singletons
:esolvin! our discoball is useful" but what if our discoball was e pensive on resources to instantiate" or should only be instantiated once9 The re!ister method will not be useful in this case" since the closure is e ecuted with every call to resol!e<= and a new instance of the ob&ect is returned each time. This is where the sin!leton desi!n pattern comes in. The sin!leton desi!n pattern involves writin! your classes in a certain way" so that they can be called usin! a static method" and will always return the same instance of itself. This way the class is instantiated only once. $or more information on the 8in!leton desi!n pattern" I would su!!est a 2uick Boo!le search" or check out the PHP *PI which has an article on the sub&ect. 8in!letons can be useful" but they re2uire a certain class structure to be able to use them. The Io5 container has a sin4leton<= method which makes the process a lot more simple" and does not re2uire any special kind of class. Let,s re!ister our discoball as a sin!leton instead..
<>p p// application/start.p p&o?..sin4leton<Cdisco"allCE function<= @ // instantiate our o"ject as "efore Dd" H ne) Disco"all<Disco"all..#H&$S=A Dd"1 >confi4ure:s inyness<Cma'C=A Dd"1>spin:speed<CPU00rpmC=A // and t e o"ject as t e result of t e closure return Dd"AB=A

*s you can see" the process is almost identical to re!isterin! an ob&ect" e cept that we use the method sin4leton<= which accepts the same parameters. 0hen we resolve our discoball" the closure will only be run the first time resol!e<= is called" the resultin! ob&ect will be stored" and any future calls to the resol!e<= method will return the same ob&ect instance. $or e ample..
<>p p// closure is e'ecutedE and a disco"all// instance is returnedDd" H &o?..resol!e<Cdisco"allC=A// t e same instance of t e disco"all// in t e a"o!e statement is returnedDanot er H &o?..resol!e<Cdisco"allC=A

Breat/ It,s also worth notin! that you can pass an already instantiated ob&ect as a second parameter to the sin4leton<= method" and it will be returned by all future re2uests to resol!e<= for e ample..
<>p pDd" H ne) Disco"all<Disco"all..#H&$S=A&o?..sin4leton<Cdisco"allCE Dd"=A// 4et old of our disco"allD"all H &o?..resol!e<Cdisco"allC=A

In a future chapter we will discuss usin! the Io5 container and dependency in&ection in combination with unit testin!. Thanks to *ndrew 8mith and ;ulien Tant %*o8i ' for buyin! the book. ;ulien had the followin! to say.. Hey 7ayle" thanks a lot for this book" the Laravel framework is &ust awesome / If any french !uys read this" visit http(--www.laravel.fr- / Thanks !uys" and !reat work translatin! the tutorials to $rench/ *lso thanks to Pro!erACP for buyin! the book and translatin! my tutorials to :ussian" which are available at Laravel.ru. Breat work/

.ncryption
8ometimes you need to protect your important data. Laravel provides two different methods to help you do that. One+way and two+way encryption. Let,s take a look at these methods.

8ne 2ay .ncryption


One way encryption is the best way to store user passwords" or other sensitive data. One way means that your data can be converted into an encrypted strin!" but due to a comple al!orithm with painful maths" reversin! the process is not possible. This makes storin! passwords a doddle/ )our customers don,t have to worry about you knowin! their passwords" but you are still able to compare them %by hashin! the password they provide' or chan!e the password if needed. $ote t at as in4 is t e process of creatin4 a strin4 from anot er strin4.
<>p pDpass H &nput..4et<Cpass)ordC=A

as

or encrypted

Let,s take a look at how password hashin! works with one way encryption.

6ow we have retrieved the password from our ,create user, form" but it,s in plain+te t/ Let,s hash it 2uickly so we can store it securely in our database.
<>p pDpass H Has ..ma+e<Dpass=A

0e have used another of Laravel,s hi!hly e pressive methods" this time ma+e<=in! a new Has . Our Dpass value will now contain a bcrypt encrypted version of our password" neat/ Let,s say that our user has entered their password to lo!in" and now we need to check to see if its authentic before they can be lo!!ed into the system. 0e can simply compare our hash to the value stored in the database with the c ec+<= method.
<>p pDpass H &nput..4et<Cpass)ordC=Aif < Has ..c ec+<DpassE Duser1>pass)ord= = @ // aut successfulB

The c ec+<= method accepts two parameters" the plain+te t value provided by your user" and the hashed password that you have stored. It returns a boolean value to indicate whether the true values match or not. 0hat if we want to decode our data at a later date9 Let,s two way encrypt it.

/wo 2ay .ncryption


Two way encryption" allows you to return your encrypted data to its ori!inal form" kind of like those spy code sheets you played with when you were a kid/ The Laravel 5rypter class uses *<8+G5H encryption which is provided by the .crypt PHP e tension" so make sure that this PHP e tension has been installed before attemptin! to use the class/ The 5rypter class works usin! two simple methods" encrypt<= and decrypt<=" let,s take a look at encryptin! a strin!.
<>p pDsecret H ?rypter..encrypt<C& actually li+e Hello VittyC=A

6ow our dirty little secret has been *<8+G5H encrypted" and the result has been returned. This would be of no use if we couldn,t decrypt the secret at a later date. Let,s look at how you can decrypt an encrypted piece of data.
<>p pDdecrypted:secret H ?rypter..decrypt<Dsecret=A

<asy as that/ 8imply hand the encrypted strin! to the decrypt<= and the decrypted result is handed back. <n&oy usin! the 5rypter class to simulate the feelin! of usin! your super secret decoder rin!s you !ot that one time in a cereal bo /

+7+> Content
.odern web applications don,t have the time to be waitin! around for the ne t HTTP re2uest. ;avascript has chan!ed the way we browse" we want our content to automatically update. 0e want to post information without havin! to reload the pa!e. In the Laravel I:5 channel we often !et asked how to use *&a alon!side Laravel" which seems confusin!" because the answer is simply ,like any other HTTP re2uest,. Let,s dive ri!ht in and look at some *&a re2uests usin! the framework. 0e are !oin! to need to make some HTTP re2uests throu!h ;avascript" this can !et u!ly so I have decided to use the &=uery ;avascript framework in these e amples.

'age /emplate
0e will need a view" or pa!e template to serve with our first re2uest" so let,s put to!ether somethin! basic.
<G11 application/!ie)s/template.p p 11><GD%?9SO7 H9,*>< tml>< ead> <meta c arsetH"89(1P"> <title>,y -ja' Oa4e</title></ ead><"ody> <di! idH"content"> <p>Hello and )elcome to t e siteG</p> </di!> <a refH"3" idH"load1 content">*oad ?ontent</a></"ody></ tml>

There we !o" now we have a content area" defined in a <D&V> element with the id of content" this is where we will load out future content. 0e also have a link with the id of load1content which we can use as a tri!!er to load our new content into the <D&V> above. 4efore we can see this view" we will need to define a route to load it" I am !oin! to make it my base route..
<>p p// application/routes.p pRoute..4et<C/CE function<= @ Vie)..ma+e<CtemplateC=AB=A return

6ow if we visit ttp.//local ost we are !reeted with our site template" but clickin! on the load content link isn,t !oin! to do a lot without some ;avascript. *lthou!h we wouldn,t need ;avascript if we didn,t have somethin! to load" let,s create a new route and view for content that is to be loaded into the content <D&V>. $irst the view..
<G11 application/!ie)s/content.p p 11>< 1>$e) ?ontent</ 1><p>9 is is our -R-[ loaded content.</p>

and a route to serve the content" note that we aren,t embeddin! the content within a template" if we did that the template would be repeated twice when we *;*C load our new content.
<>p p// application/routes.p pRoute..4et<CcontentCE function<= @ Vie)..ma+e<CcontentC=AB=A return

Breat so now we have our main template" and we have a secondary route with some content to load via *;*C" so let,s !et started with the ;avascript.

/he 7a%ascript
6ow I,m a PHP developer" so my ;avascript skills aren,t !oin! to blow anyones minds in this chapter. If you can find a better way to perform these actions %and there are many alternatives' then !o ahead and try them" I,m sure you can do better/ $irst let,s create a new file called script.js and put it in pu"lic/js alon! with the latest version of &=uery which in my case is simply called jKuery.js. Let,s edit our main template to add references to these files usin! the H9,*..script<= method.

<G11 application/!ie)s/template.p p 11><GD%?9SO7 H9,*>< tml>< ead> <meta c arsetH"89(1P"> <title>,y -ja' Oa4e</title></ ead><"ody> <di! idH"content"> <p>Hello and )elcome to t e siteG</p> </di!> <a refH"3" idH"load1 content">*oad ?ontent</a> <G11 ja!ascript files 11> <script typeH"te't/ja!ascript">!ar ;-#7 H "<>p p ec o 8R*.."ase<=A >>"A</script> <>p p ec o H9,*..script<Cjs/jKuery.jsC=A >> <>p p ec o H9,*..script<Cjs/script.jsC=A > ></"ody></ tml>

*s you can see" I have referenced my ;avascript files before the closin! ta!" so that the HTTP re2uests to load them don,t block the pa!e loadin!. This is a !ood practice to stick to. Let,s !et started and add some ;avascript to our pu"lic/js/script.js file. 0e also create a new ;-#7 variable so that ;avascript is aware of the base >:L to our application" we will need this later to create re2uest >:Ls.
// pu"lic/js/script.jsjXuery<document=.ready<function<D= @ only ) en t e document // as "een fully loadedB=A // perform ja!ascript

Here we are usin! the &=uery%' ob&ect to !et a handle on the current document" and addin! a ready<= event with a closure to hold our code. 4y waitin! for the document ob&ect to be ready<= we can be sure that all D%, ob&ects have loaded" and that the &=uery library has been loaded. )ou may see other e amples written like this..
// pu"lic/js/script.jsD<document=.ready<function<= @ ) en t e document // as "een fully loadedB=A // perform ja!ascript only

This is fine" but could lead to problems if other ;avascript libraries chose to use the D ob&ect at a later date. .y method uses the &=uery class" and hands the inner closure a D which is reassi!ned to the &=uery ob&ect. This prevents any collisions. Let,s !et started on creatin! a click event for our content loader link" there are many ways to do this with &=uery" I am !oin! to use the .clic+<= method. Here we !o..
// pu"lic/js/script.jsD<document=.ready<function<= @ D<C3load1 contentC=.clic+<function<e= @ e.pre!entDefault<=A B=B=A

6ow we have a click event defined" with a callback closure. 4y providin! an e!ent parameter called e to the inner closure" we can use the e.pre!entDefault<=A method to prevent the default click action from bein! performed. In this case the link will not act as a hyper+link. 6ow we need to make another HTTP re2uest to J79 the new content" and load it into our 3content area. Let,s use the &=uery .4et<= method to perform this task.
// pu"lic/js/script.jsD<document=.ready<function<= @ D<C3load1 contentC=.clic+<function<e= @ // pre!ent t e lin+s default action // from firin4 e.pre!entDefault<=A // attempt to J79 t e ne) content D.4et<;-#7YCcontentCE function<data= @ D <C3contentC=. tml<data=A B=A B=B=A

:emember the ;-#7 attribute we set earlier9 0e can use it to build our re2uest >:L" and create a callback method to catch the data that is returned. 0e will in&ect the response from our J79 re2uest into the 3content element usin! the . tml<= method. That was a lot of hard work wasn,t it9 0ell at least now we can see our hard work in action" let,s load up the application at ttp.//local ost and click the load content link. Hopefully it worked/ 8o as you can see" usin! *;*C with Laravel is the same as usin! any other framework or plain PHP" &ust be sure you format the views for your *;*C routes in a suitable manner.

'ost )ata
8ometimes you need to send e tra alon! with your re2uests" let,s create a new O%#9 HTTP re2uest with

&=uery to demonstrate how this can be done. $irst we will need a route that will respond to a O%#9 re2uest.
<>p p// application/routes.p pRoute..post<CcontentCE function<= @ t e post data..B=A // deal )it

4y usin! the Route..post<= method instead of 4et<= our content route will now respond to our PO8T re2uest" let,s !et started on the ;avascript.
// attempt a O%#9 reKuest )it // some additional dataD.post<;-#7YCcontentCE @ name. "Dayle"E a4e. 27BE function<data= @ D<C3contentC=. tml<data=AB=A

0e are usin! the O%#9 method to post some data to the content route" we can receive the data with Laravel in a similar manner to form processin! usin! the &nput class.
<>p p// application/routes.p pRoute..post<CcontentCE function<= @ ec o &nput..4et<CnameC=A // Dayle ec o &nput..4et<Ca4eC=A // 27B=A

8imple as that/

7S8 (esponses
0hen interactin! with ;avascript" its useful to be able to return data in ;8O6 format" a strin! based array that ;avascript is more familiar with. To return a ;8O6 response" first we need to encode our PHP array" and then send the appropriate headers to inform the client of our ;8O6 content type. The above 2uote used to be true" but the method Response..json<= was added with Laravel 3.G which achieves the same !oal. Let,s create a new route.
<>p p// application/routes.p pRoute..4et<CcontentCE function<= @ // our data arrayE soon to "e R#%$ Ddata H array< CnameC H> CDummyCE CsiQeC H> C[*CE CcolorC H> C;lueC =A return Response..json<Ddata=AB=A

$inally we return a response ob&ect" passin! our data array to the json<= method which is ;8O6 encoded for us. 0e can optionally pass a different status code other than GKK as a second parameter.

)etecting an +7+> (e5uest


8ometimes its useful to within the route whether a re2uest has been made usin! *;*C. $ortunately Laravel provides a method to detect *;*C re2uests. Let,s take a look.
<>p p// application/routes.p pRoute..4et<CcontentCE function<= @ if t e reKuest is // an -R-[ one. if <ReKuest..aja'<== @ t e aja' content return Vie)..ma+e<Conly:contentC=A B full content return Vie)..ma+e<Ccontent:)it :layoutC=AB=A // c ec+ to see // pro!ide // pro!ide t e

The ReKuest..aja'<= returns a boolean true if the re2uest is an *;*C re2uest" and boolean false if not. I would like to say thanks to the followin! people for buyin! a copy of 5ode Happy" thanks/ 0illiam .anley 6ate 6oltin! ;ori&n 8chri&vershof

5aleb Briffin $lorian >hlrich 8tefano Biordano 8imon <dwards

I,d also like to say thanks to everyone that sent kind emails about the book" thanks for all the support/

)ebugging +pplications
*pplications written usin! the Laravel framework are best e perienced without bu!s" however we all know how easily they can arise when we have deadlines to meet" and an!ry bosses standin! over our shoulders. PHP itself has a number of different methods of debu!!in!" from simple !ar:dump<=s" print:r<=s" the famous die<= and the advanced debu!!in! features of the PHP debu! e tension. I,m not !oin! to cover these basic methods in detail" because this is a book about Laravel" not the basics of the PHP lan!ua!e. Instead let,s have a look at the features that Laravel offers to help us track down those mean little bu!s.

.rror Handler
Laravel includes a custom error handler" which overwrites the default one liner PHP errors" and instead provides some !reater detail alon! with a stacktrace. Let,s have a look at the output from the error handler..
8n andled 7'ception,essa4e.Vie) 5pa4e.panda6 doesnCt e'ist.*ocation./8sers/daylerees/)))/panda/lara!el/!ie).p p on line 1L1#tac+ 9race.30 /8sers/daylerees/)))/panda/lara!el/!ie).p p<U0=. *ara!el/Vie)1 >pat <Cpa4e.pandaC=31 /8sers/daylerees/)))/panda/lara!el/!ie).p p<1UU=. *ara!el/Vie)1>::construct<C pa4e.panda CE -rray=32 /8sers/daylerees/)))/panda/application/routes.p p<0L=. *ara!el/Vie)..ma+e<C pa4e.panda C=30 5internal function6. @closureB<=3T /8sers/daylerees/)))/panda/lara!el/routin4/route.p p<120=. call:user:func:array<%"ject<?losure=E -rray=3L /8sers/daylerees/)))/panda/lara!el/routin4/route.p p<12T=. *ara!el/Routin4/Route1 >response<=32 /8sers/daylerees/)))/panda/lara!el/lara!el.p p<12L=. *ara!el/Routin4/Route1>call<=37 /8sers/daylerees/)))/panda/pu"lic/inde'.p p<0T=. reKuire<C/8sers/dayleree...C=3P @mainB

This is the error that is shown if a re2uested view doesn,t e ist at run time. *s you can see we have an informative error messa!e from Laravel" as well as the file in which the error was encountered" and a line number. In addition we also have a stacktrace that shows the initial error" followin! all the method calls throu!h the ,3iew, layer all the way down to the routin! system. .ost of the time you won,t need the stacktrace" but it could prove useful for the more e perienced developers" for e ample when an error occurs within a comple library.

.rror Configuration
0e don,t always want our errors to show in this way" especially on a production site where showin! a stacktrace could pose a si!nificant security risk. $ortunately" and as always" Laravel has made it easy for us to chan!e the confi!uration for the display of errors. The confi!uration file for the error reportin! system can be found at application/confi4/error.p p. Let,s have a run throu!h the confi!uration options that are contained in this array.
Ci4noreC H> array<=E

The i!nore array contains a list of errors that are to be i!nored by the error handler. *lthou!h these errors will no lon!er be displayed when they are encountered" they will always be lo!!ed. Eeep this in mind when usin! the i!nore array. To add an error type to this array" add the PHP error type constant" or an inte!er value to the array.
Ci4noreC H> array<7:7RR%R=A

* full list of PHP error type constants can be found on the PHP *PI" however here are some of the more useful ones. 4 4RR5R This will match all fatal run time errors. 4 6AR3738 This constant will match all warnin!" or non fatal type errors. 4 9AR:4 This constant will match all parse time errors" or synta errors. 4 35;7C4 This constant will match all run time notices. 4 A<< This constant will match all of the above" e cept for 7:#9R&?9 errors.
CdetailC H> trueE

The detail confi! option can be used to switch the detailed error reportin! on or off. 0hen enabled %true' it will show the full error report alon! with stack trace as shown above. 7isablin! this option %false' will cause the default error 5KK pa!e to be displayed instead.
Clo4C H> falseE

If the lo4 confi! option is set to true" the closure contained within the lo44er confi! option will be e ecuted with each error" and passed an e ception ob&ect.
Clo44erC H> function<De'ception=@ *o4..e'ception<De'ception=ABE

4y default" the closure contained within the lo44er confi! option will write an entry to a lo! file within the stora4e/lo4s. However" providin! a closure has provided a !reat deal of fle ibility" allowin! you to override the default lo!!in! method with anythin! you can think of. Perhaps you would prefer to lo! to a database9 .ake it so number D/ <n!a!e.

-ogging
4ein! able to show errors" and lo! them to files is handy" but what if we want to lo! our own custom information9 The Laravel *o4 class contains two different methods for lo!!in! useful information from your application. Let,s take a look at these methods now. The *o4..)rite<= method accepts a lo! type" and a strin! messa!e to be written to the lo! file. $or e ample..
<>p p*o4..)rite<CmyappCE CHere is some useful information.C=A

0ill result in the followin! line bein! written to the lo! file.
201210L12U 1U.10.17 ,S-OO 1 Here is some useful information.

The entry will of course be written to the active lo! file in the stora4e/lo4s directory in a file named after the current day" for e ample 201110210L.lo4. This allows for the lo!s to be rotated and avoid havin! lo! files that are hu!e/ )ou can also use a ma!ic method to set the lo! type" for e ample..
<>p p*o4..s oe<Cmy lo4 entryC=A

0ill have the same effect as..


<>p p*o4..)rite<Cs oeCE Cmy lo4 entryC=A

3ery useful/ .ake use of all of the features you have learned in this chapter to dia!nose your applications if anythin! !oes wron!/

Das könnte Ihnen auch gefallen