table of contents · laravel 5.0 laravel 4.2 laravel 4.1 laravel 5.0 introduces a fresh application...

242

Upload: others

Post on 06-Aug-2020

35 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better
Page 2: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

1. Introduction2. Prologue

i. ReleaseNotesi. Laravel5.0ii. Laravel4.2iii. Laravel4.1

ii. UpgradeGuidei. UpgradingTo5.0From4.2ii. UpgradingTo4.2From4.1iii. UpgradingTo4.1.29From<=4.1.xiv. UpgradingTo4.1.26From<=4.1.25v. UpgradingTo4.1From4.0

iii. ContributionGuidei. BugReportsii. CoreDevelopmentDiscussioniii. WhichBranch?iv. SecurityVulnerabilitiesv. CodingStyle

3. Setupi. Installation

i. InstallComposerii. InstallLaraveliii. ServerRequirements

ii. Configurationi. Introductionii. AfterInstallationiii. AccessingConfigurationValuesiv. EnvironmentConfigurationv. ConfigurationCachingvi. MaintenanceModevii. PrettyURLs

iii. Homesteadi. Introductionii. IncludedSoftwareiii. Installation&Setupiv. DailyUsagev. Ports

4. TheBasicsi. Routing

i. BasicRoutingii. CSRFProtectioniii. MethodSpoofingiv. RouteParametersv. NamedRoutesvi. RouteGroupsvii. RouteModelBindingviii. Throwing404Errors

ii. Middlewarei. Introductionii. DefiningMiddlewareiii. RegisteringMiddlewareiv. TerminableMiddleware

TableofContents

Page 3: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

iii. Controllersi. Introductionii. BasicControllersiii. ControllerMiddlewareiv. ImplicitControllersv. RESTfulResourceControllersvi. DependencyInjection&Controllersvii. RouteCaching

iv. Requestsi. ObtainingARequestInstanceii. RetrievingInputiii. OldInputiv. Cookiesv. Filesvi. OtherRequestInformation

v. Responsesi. BasicResponsesii. Redirectsiii. OtherResponsesiv. ResponseMacros

vi. Viewsi. BasicUsageii. ViewComposers

5. ArchitectureFoundationsi. ServiceProviders

i. Introductionii. BasicProviderExampleiii. RegisteringProvidersiv. DeferredProviders

ii. ServiceContaineri. Introductionii. BasicUsageiii. BindingInterfacesToImplementationsiv. ContextualBindingv. Taggingvi. PracticalApplicationsvii. ContainerEvents

iii. Contractsi. Introductionii. WhyContracts?iii. ContractReferenceiv. HowToUseContracts

iv. Facadesi. Introductionii. Explanationiii. PracticalUsageiv. CreatingFacadesv. MockingFacadesvi. FacadeClassReference

v. RequestLifecyclei. Introductionii. LifecycleOverviewiii. FocusOnServiceProviders

vi. ApplicationStructurei. Introductionii. TheRootDirectory

Page 4: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

iii. TheAppDirectoryiv. NamespacingYourApplication

6. Servicesi. Authentication

i. Introductionii. AuthenticatingUsersiii. RetrievingTheAuthenticatedUseriv. ProtectingRoutesv. HTTPBasicAuthenticationvi. PasswordReminders&Resetvii. SocialAuthentication

ii. Billingi. Introductionii. Configurationiii. SubscribingToAPlaniv. NoCardUpFrontv. SwappingSubscriptionsvi. SubscriptionQuantityvii. CancellingASubscriptionviii. ResumingASubscriptionix. CheckingSubscriptionStatusx. HandlingFailedPaymentsxi. HandlingOtherStripeWebhooksxii. Invoices

iii. Cachei. Configurationii. CacheUsageiii. Increments&Decrementsiv. CacheTagsv. DatabaseCache

iv. Collectionsi. Introductionii. BasicUsage

v. CommandBusi. Introductionii. CreatingCommandsiii. DispatchingCommandsiv. QueuedCommandsv. CommandPipeline

vi. CoreExtensioni. Managers&Factoriesii. Cacheiii. Sessioniv. Authenticationv. IoCBasedExtension

vii. Elixiri. Introductionii. Installation&Setupiii. Usageiv. Gulpv. Extensions

viii. Encryptioni. Introductionii. BasicUsage

ix. Errors&Loggingi. Configuration

Page 5: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ii. HandlingErrorsiii. HTTPExceptionsiv. Logging

x. Eventsi. BasicUsageii. QueuedEventHandlersiii. EventSubscribers

xi. Filesystem/CloudStoragei. Introductionii. Configurationiii. BasicUsage

xii. Hashingi. Introductionii. BasicUsage

xiii. Helpersi. Arraysii. Pathsiii. Stringsiv. URLsv. Miscellaneous

xiv. Localizationi. Introductionii. LanguageFilesiii. BasicUsageiv. Pluralizationv. ValidationLocalizationvi. OverridingPackageLanguageFiles

xv. Maili. Configurationii. BasicUsageiii. EmbeddingInlineAttachmentsiv. QueueingMailv. Mail&LocalDevelopment

xvi. PackageDevelopmenti. Introductionii. Viewsiii. Translationsiv. Configurationv. PublishingFileGroupsvi. Routing

xvii. Paginationi. Configurationii. Usageiii. AppendingToPaginationLinksiv. ConvertingToJSON

xviii. Queuesi. Configurationii. BasicUsageiii. QueueingClosuresiv. RunningTheQueueListenerv. DaemonQueueWorkervi. PushQueuesvii. FailedJobs

xix. Sessioni. Configurationii. SessionUsage

Page 6: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

iii. FlashDataiv. DatabaseSessionsv. SessionDrivers

xx. Templatesi. BladeTemplatingii. OtherBladeControlStructuresiii. ExtendingBlade

xxi. UnitTestingi. Introductionii. Defining&RunningTestsiii. TestEnvironmentiv. CallingRoutesFromTestsv. MockingFacadesvi. FrameworkAssertionsvii. HelperMethodsviii. RefreshingTheApplication

xxii. Validationi. BasicUsageii. ControllerValidationiii. FormRequestValidationiv. WorkingWithErrorMessagesv. ErrorMessages&Viewsvi. AvailableValidationRulesvii. ConditionallyAddingRulesviii. CustomErrorMessagesix. CustomValidationRules

7. Databasei. BasicUsage

i. Configurationii. Read/WriteConnectionsiii. RunningQueriesiv. DatabaseTransactionsv. AccessingConnectionsvi. QueryLogging

ii. QueryBuilderi. Introductionii. Selectsiii. Joinsiv. AdvancedWheresv. Aggregatesvi. RawExpressionsvii. Insertsviii. Updatesix. Deletesx. Unionsxi. PessimisticLocking

iii. EloquentORMi. Introductionii. BasicUsageiii. MassAssignmentiv. Insert,Update,Deletev. SoftDeletingvi. Timestampsvii. QueryScopesviii. GlobalScopesix. Relationships

Page 7: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

x. QueryingRelationsxi. EagerLoadingxii. InsertingRelatedModelsxiii. TouchingParentTimestampsxiv. WorkingWithPivotTablesxv. Collectionsxvi. Accessors&Mutatorsxvii. DateMutatorsxviii. AttributeCastingxix. ModelEventsxx. ModelObserversxxi. ConvertingToArrays/JSON

iv. SchemaBuilderi. Introductionii. Creating&DroppingTablesiii. AddingColumnsiv. ChangingColumnsv. RenamingColumnsvi. DroppingColumnsvii. CheckingExistenceviii. AddingIndexesix. ForeignKeysx. DroppingIndexesxi. DroppingTimestamps&SoftDeletesxii. StorageEngines

v. Migrations&Seedingi. Introductionii. CreatingMigrationsiii. RunningMigrationsiv. RollingBackMigrationsv. DatabaseSeeding

vi. Redisi. Introductionii. Configurationiii. Usageiv. Pipelining

8. ArtisanCLIi. Overview

i. Introductionii. Usageiii. CallingCommandsOutsideOfCLIiv. SchedulingArtisanCommands

ii. Developmenti. Introductionii. BuildingACommandiii. RegisteringCommands

Page 8: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

AGitBookversionofLaravel5.0Documentation

Introduction

Page 9: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ReleaseNotesLaravel5.0Laravel4.2Laravel4.1

UpgradeGuideUpgradingTo5.0From4.2UpgradingTo4.2From4.1UpgradingTo4.1.29From<=4.1.xUpgradingTo4.1.26From<=4.1.25UpgradingTo4.1From4.0

ContributionGuideBugReportsCoreDevelopmentDiscussionWhichBranch?SecurityVulnerabilitiesCodingStyle

Prologue

Page 10: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Laravel5.0Laravel4.2Laravel4.1

Laravel5.0introducesafreshapplicationstructuretothedefaultLaravelproject.ThisnewstructureservesasabetterfoundationforbuildingrobustapplicationinLaravel,aswellasembracesnewauto-loadingstandards(PSR-4)throughouttheapplication.First,let'sexaminesomeofthemajorchanges:

Theoldapp/modelsdirectoryhasbeenentirelyremoved.Instead,allofyourcodelivesdirectlywithintheappfolder,and,bydefault,isorganizedtotheAppnamespace.Thisdefaultnamespacecanbequicklychangedusingthenewapp:nameArtisancommand.

Controllers,middleware,andrequests(anewtypeofclassinLaravel5.0)arenowgroupedundertheapp/Httpdirectory,astheyareallclassesrelatedtotheHTTPtransportlayerofyourapplication.Insteadofasingle,flatfileofroutefilters,allmiddlewarearenowbrokenintotheirownclassfiles.

Anewapp/Providersdirectoryreplacestheapp/startfilesfrompreviousversionsofLaravel4.x.Theseserviceprovidersprovidevariousbootstrappingfunctionstoyourapplication,suchaserrorhandling,logging,routeloading,andmore.Ofcourse,youarefreetocreateadditionalserviceprovidersforyourapplication.

Applicationlanguagefilesandviewshavebeenmovedtotheresourcesdirectory.

AllmajorLaravelcomponentsimplementinterfaceswhicharelocatedintheilluminate/contractsrepository.Thisrepositoryhasnoexternaldependencies.Havingaconvenient,centrallylocatedsetofinterfacesyoumayusefordecouplinganddependencyinjectionwillserveasaneasyalternativeoptiontoLaravelFacades.

Formoreinformationoncontracts,consultthefulldocumentation.

Ifyourapplicationismadeupentirelyofcontrollerroutes,youmayutilizethenewroute:cacheArtisancommandtodrasticallyspeeduptheregistrationofyourroutes.Thisisprimarilyusefulonapplicationswith100+routesandwilldrasticallyspeedupthisportionofyourapplication.

InadditiontoLaravel4styleroute"filters",Laravel5nowsupportsHTTPmiddleware,andtheincludedauthenticationandCSRF"filters"havebeenconvertedtomiddleware.Middlewareprovidesasingle,consistentinterfacetoreplacealltypesoffilters,allowingyoutoeasilyinspect,andevenreject,requestsbeforetheyenteryourapplication.

Formoreinformationonmiddleware,checkoutthedocumentation.

Inadditiontotheexistingconstructorinjection,youmaynowtype-hintdependenciesoncontrollermethods.TheIoCcontainerwillautomaticallyinjectthedependencies,eveniftheroutecontainsotherparameters:

ReleaseNotes

Laravel5.0

NewFolderStructure

Contracts

RouteCache

RouteMiddleware

ControllerMethodInjection

Page 11: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

publicfunctioncreatePost(Request$request,PostRepository$posts)

{

//

}

Userregistration,authentication,andpasswordresetcontrollersarenowincludedoutofthebox,aswellassimplecorrespondingviews,whicharelocatedatresources/views/auth.Inaddition,a"users"tablemigrationhasbeenincludedwiththeframework.Includingthesesimpleresourcesallowsrapiddevelopmentofapplicationideaswithoutboggingdownonauthenticationboilerplate.Theauthenticationviewsmaybeaccessedontheauth/loginandauth/registerroutes.TheApp\Services\Auth\Registrarserviceisresponsibleforuservalidationandcreation.

Youmaynowdefineeventsasobjectsinsteadofsimplyusingstrings.Forexample,checkoutthefollowingevent:

classPodcastWasPurchased{

public$podcast;

publicfunction__construct(Podcast$podcast)

{

$this->podcast=$podcast;

}

}

Theeventmaybedispatchedlikenormal:

Event::fire(newPodcastWasPurchased($podcast));

Ofcourse,youreventhandlerwillreceivetheeventobjectinsteadofalistofdata:

classReportPodcastPurchase{

publicfunctionhandle(PodcastWasPurchased$event)

{

//

}

}

Formoreinformationonworkingwithevents,checkoutthefulldocumentation.

InadditiontothequeuejobformatsupportedinLaravel4,Laravel5allowsyoutorepresentyourqueuedjobsassimplecommandobjects.Thesecommandsliveintheapp/Commandsdirectory.Here'sasamplecommand:

classPurchasePodcastextendsCommandimplementsSelfHandling,ShouldBeQueued{

useSerializesModels;

protected$user,$podcast;

/**

*Createanewcommandinstance.

*

*@returnvoid

AuthenticationScaffolding

EventObjects

Commands/Queueing

Page 12: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

*/

publicfunction__construct(User$user,Podcast$podcast)

{

$this->user=$user;

$this->podcast=$podcast;

}

/**

*Executethecommand.

*

*@returnvoid

*/

publicfunctionhandle()

{

//Handlethelogictopurchasethepodcast...

event(newPodcastWasPurchased($this->user,$this->podcast));

}

}

ThebaseLaravelcontrollerutilizesthenewDispatchesCommandstrait,allowingyoutoeasilydispatchyourcommandsforexecution:

$this->dispatch(newPurchasePodcastCommand($user,$podcast));

Ofcourse,youmayalsousecommandsfortasksthatareexecutedsynchonrously(arenotqueued).Infact,usingcommandsisagreatwaytoencapsulatecomplextasksyourapplicationneedstoperform.Formoreinformation,checkoutthecommandbusdocumentation.

AdatabasequeuedriverisnowincludedinLaravel,providingasimple,localqueuedriverthatrequiresnoextrapackageinstallationbeyondyourdatabasesoftware.

Inthepast,developershavegeneratedaCronentryforeachconsolecommandtheywishedtoschedule.However,thisisaheadache.Yourconsolescheduleisnolongerinsourcecontrol,andyoumustSSHintoyourservertoaddtheCronentries.Let'smakeourliveseasier.TheLaravelcommandschedulerallowsyoutofluentlyandexpressivelydefineyourcommandschedulewithinLaravelitself,andonlyasingleCronentryisneededonyourserver.

Itlookslikethis:

$schedule->command('artisan:command')->dailyAt('15:00');

Ofcourse,checkoutthefulldocumentationtolearnallaboutthescheduler!

ThephpartisantinkercommandnowutilizesPsyshbyJustinHileman,amorerobustREPLforPHP.IfyoulikedBorisinLaravel4,you'regoingtolovePsysh.Evenbetter,itworksonWindows!Togetstarted,justtry:

phpartisantinker

Insteadofavarietyofconfusing,nestedenvironmentconfigurationdirectories,Laravel5nowutilizesDotEnvbyVance

DatabaseQueue

LaravelScheduler

Tinker/Psysh

DotEnv

Page 13: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Lucas.Thislibraryprovidesasupersimplewaytomanageyourenvironmentconfiguration,andmakesenvironmentdetectioninLaravel5abreeze.Formoredetails,checkoutthefullconfigurationdocumentation.

LaravelElixir,byJeffreyWay,providesafluent,expressiveinterfacetocompilingandconcatenatingyourassets.Ifyou'veeverbeenintimidatedbylearningGruntorGulp,fearnomore.ElixirmakesitacinchtogetstartedusingGulptocompileyourLess,Sass,andCoffeeScript.Itcanevenrunyourtestsforyou!

FormoreinformationonElixir,checkoutthefulldocumentation.

LaravelSocialiteisanoptional,Laravel5.0+compatiblepackagethatprovidestotallypainlessauthenticationwithOAuthproviders.Currently,SocialitesupportsFacebook,Twitter,Google,andGitHub.Here'swhatitlookslike:

publicfunctionredirectForAuth()

{

returnSocialize::with('twitter')->redirect();

}

publicfunctiongetUserFromProvider()

{

$user=Socialize::with('twitter')->user();

}

NomorespendinghourswritingOAuthauthenticationflows.Getstartedinminutes!Thefulldocumentationhasallthedetails.

LaravelnowincludesthepowerfulFlysystemfilesystemabstractionlibrary,providingpainfreeintegrationwithlocal,AmazonS3,andRackspacecloudstorage-allwithone,unifiedandelegantAPI!StoringafileinAmazonS3isnowassimpleas:

Storage::put('file.txt','contents');

FormoreinformationontheLaravelFlysystemintegration,consultthefulldocumentation.

Laravel5.0introducesformrequests,whichextendtheIlluminate\Foundation\Http\FormRequestclass.Theserequestobjectscanbecombinedwithcontrollermethodinjectiontoprovideaboiler-platefreemethodofvalidatinguserinput.Let'sdiginandlookatasampleFormRequest:

<?phpnamespaceApp\Http\Requests;

classRegisterRequestextendsFormRequest{

publicfunctionrules()

{

return[

'email'=>'required|email|unique:users',

'password'=>'required|confirmed|min:8',

];

}

publicfunctionauthorize()

{

returntrue;

}

LaravelElixir

LaravelSocialite

FlysystemIntegration

FormRequests

Page 14: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

}

Oncetheclasshasbeendefined,wecantype-hintitonourcontrolleraction:

publicfunctionregister(RegisterRequest$request)

{

var_dump($request->input());

}

WhentheLaravelIoCcontaineridentifiesthattheclassitisinjectingisaFormRequestinstance,therequestwillautomaticallybevalidated.Thismeansthatifyourcontrolleractioniscalled,youcansafelyassumetheHTTPrequestinputhasbeenvalidatedaccordingtotherulesyouspecifiedinyourformrequestclass.Evenmore,iftherequestisinvalid,anHTTPredirect,whichyoumaycustomize,willautomaticallybeissued,andtheerrormessageswillbeeitherflashedtothesessionorconvertedtoJSON.Formvalidationhasneverbeenmoresimple.FormoreinformationonFormRequestvalidation,checkoutthedocumentation.

TheLaravel5basecontrollernowincludesaValidatesRequeststrait.Thistraitprovidesasimplevalidatemethodtovalidateincomingrequests.IfFormRequestsarealittletoomuchforyourapplication,checkthisout:

publicfunctioncreatePost(Request$request)

{

$this->validate($request,[

'title'=>'required|max:255',

'body'=>'required',

]);

}

Ifthevalidationfails,anexceptionwillbethrownandtheproperHTTPresponsewillautomaticallybesentbacktothebrowser.Thevalidationerrorswillevenbeflashedtothesession!IftherequestwasanAJAXrequest,LaraveleventakescareofsendingaJSONrepresentationofthevalidationerrorsbacktoyou.

Formoreinformationonthisnewmethod,checkoutthedocumentation.

Tocomplimentthenewdefaultapplicationstructure,newArtisangeneratorcommandshavebeenaddedtotheframework.Seephpartisanlistformoredetails.

Youmaynowcacheallofyourconfigurationinasinglefileusingtheconfig:cachecommand.

Thepopularddhelperfunction,whichdumpsvariabledebuginformation,hasbeenupgradedtousetheamazingSymfonyVarDumper.Thisprovidescolor-codedoutputandevencollapsingofarrays.Justtrythefollowinginyourproject:

dd([1,2,3]);

Thefullchangelistforthisreleasebyrunningthephpartisanchangescommandfroma4.2installation,orbyviewingthe

SimpleControllerRequestValidation

NewGenerators

ConfigurationCache

SymfonyVarDumper

Laravel4.2

Page 15: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

changefileonGithub.Thesenotesonlycoverthemajorenhancementsandchangesfortherelease.

Note:Duringthe4.2releasecycle,manysmallbugfixesandenhancementswereincorporatedintothevariousLaravel4.1pointreleases.So,besuretocheckthechangelistforLaravel4.1aswell!

Laravel4.2requiresPHP5.4orgreater.ThisupgradedPHPrequirementallowsustousenewPHPfeaturessuchastraitstoprovidemoreexpressiveinterfacesfortoolslikeLaravelCashier.PHP5.4alsobringssignificantspeedandperformanceimprovementsoverPHP5.3.

LaravelForge,anewwebbasedapplication,providesasimplewaytocreateandmanagePHPserversonthecloudofyourchoice,includingLinode,DigitalOcean,Rackspace,andAmazonEC2.SupportingautomatedNginxconfiguration,SSHkeyaccess,Cronjobautomation,servermonitoringviaNewRelic&Papertrail,"PushToDeploy",Laravelqueueworkerconfiguration,andmore,ForgeprovidesthesimplestandmostaffordablewaytolaunchallofyourLaravelapplications.

ThedefaultLaravel4.2installation'sapp/config/database.phpconfigurationfileisnowconfiguredforForgeusagebydefault,allowingformoreconvenientdeploymentoffreshapplicationsontotheplatform.

MoreinformationaboutLaravelForgecanbefoundontheofficialForgewebsite.

LaravelHomesteadisanofficialVagrantenvironmentfordevelopingrobustLaravelandPHPapplications.Thevastmajorityoftheboxes'provisioningneedsarehandledbeforetheboxispackagedfordistribution,allowingtheboxtobootextremelyquickly.HomesteadincludesNginx1.6,PHP5.6,MySQL,Postgres,Redis,Memcached,Beanstalk,Node,Gulp,Grunt,&Bower.HomesteadincludesasimpleHomestead.yamlconfigurationfileformanagingmultipleLaravelapplicationsonasinglebox.

ThedefaultLaravel4.2installationnowincludesanapp/config/local/database.phpconfigurationfilethatisconfiguredtousetheHomesteaddatabaseoutofthebox,makingLaravelinitialinstallationandconfigurationmoreconvenient.

TheofficialdocumentationhasalsobeenupdatedtoincludeHomesteaddocumentation.

LaravelCashierisasimple,expressivelibraryformanagingsubscriptionbillingwithStripe.WiththeintroductionofLaravel4.2,weareincludingCashierdocumentationalongwiththemainLaraveldocumentation,thoughinstallationofthecomponentitselfisstilloptional.ThisreleaseofCashierbringsnumerousbugfixes,multi-currencysupport,andcompatibilitywiththelatestStripeAPI.

TheArtisanqueue:workcommandnowsupportsa--daemonoptiontostartaworkerin"daemonmode",meaningtheworkerwillcontinuetoprocessjobswithouteverre-bootingtheframework.ThisresultsinasignificantreductioninCPUusageatthecostofaslightlymorecomplexapplicationdeploymentprocess.

Moreinformationaboutdaemonqueueworkerscanbefoundinthequeuedocumentation.

Laravel4.2introducesnewMailgunandMandrillAPIdriversfortheMailfunctions.Formanyapplications,thisprovidesafasterandmorereliablemethodofsendinge-mailsthantheSMTPoptions.ThenewdriversutilizetheGuzzle4HTTPlibrary.

PHP5.4Requirement

LaravelForge

LaravelHomestead

LaravelCashier

DaemonQueueWorkers

MailAPIDrivers

Page 16: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Amuchcleanerarchitecturefor"softdeletes"andother"globalscopes"hasbeenintroducedviaPHP5.4traits.Thisnewarchitectureallowsfortheeasierconstructionofsimilarglobaltraits,andacleanerseparationofconcernswithintheframeworkitself.

MoreinformationonthenewSoftDeletingTraitmaybefoundintheEloquentdocumentation.

ThedefaultLaravel4.2installationnowusessimpletraitsforincludingtheneededpropertiesfortheauthenticationandpasswordreminderuserinterfaces.ThisprovidesamuchcleanerdefaultUsermodelfileoutofthebox.

AnewsimplePaginatemethodwasaddedtothequeryandEloquentbuilderwhichallowsformoreefficientquerieswhenusingsimple"Next"and"Previous"linksinyourpaginationview.

Inproduction,destructivemigrationoperationswillnowaskforconfirmation.Commandsmaybeforcedtorunwithoutanypromptsusingthe--forcecommand.

Thefullchangelistforthisreleasebyrunningthephpartisanchangescommandfroma4.1installation,orbyviewingthechangefileonGithub.Thesenotesonlycoverthemajorenhancementsandchangesfortherelease.

AnentirelynewSSHcomponenthasbeenintroducedwiththisrelease.ThisfeatureallowsyoutoeasilySSHintoremoteserversandruncommands.Tolearnmore,consulttheSSHcomponentdocumentation.

ThenewphpartisantailcommandutilizesthenewSSHcomponent.Formoreinformation,consultthetailcommanddocumentation.

ThephpartisantinkercommandnowutilizestheBorisREPLifyoursystemsupportsit.ThereadlineandpcntlPHPextensionsmustbeinstalledtousethisfeature.Ifyoudonothavetheseextensions,theshellfrom4.0willbeused.

AnewhasManyThroughrelationshiphasbeenaddedtoEloquent.Tolearnhowtouseit,consulttheEloquentdocumentation.

AnewwhereHasmethodhasalsobeenintroducedtoallowretrievingmodelsbasedonrelationshipconstraints.

Automatichandlingofseparateread/writeconnectionsisnowavailablethroughoutthedatabaselayer,includingthequerybuilderandEloquent.Formoreinformation,consultthedocumentation.

SoftDeletingTraits

ConvenientAuth&RemindableTraits

"SimplePaginate"

MigrationConfirmation

Laravel4.1

FullChangeList

NewSSHComponent

BorisInTinker

EloquentImprovements

DatabaseRead/WriteConnections

Page 17: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Queueprioritiesarenowsupportedbypassingacomma-delimitedlisttothequeue:listencommand.

Thequeuefacilitiesnowincludeautomatichandlingoffailedjobswhenusingthenew--triesswitchonqueue:listen.Moreinformationonhandlingfailedjobscanbefoundinthequeuedocumentation.

Cache"sections"havebeensupersededby"tags".Cachetagsallowyoutoassignmultiple"tags"toacacheitem,andflushallitemsassignedtoasingletag.Moreinformationonusingcachetagsmaybefoundinthecachedocumentation.

Thepasswordreminderenginehasbeenchangedtoprovidegreaterdeveloperflexibilitywhenvalidatingpasswords,flashingstatusmessagestothesession,etc.Formoreinformationonusingtheenhancedpasswordreminderengine,consultthedocumentation.

Laravel4.1featuresatotallyre-writtenroutinglayer.TheAPIisthesame;however,registeringroutesisafull100%fastercomparedto4.0.Theentireenginehasbeengreatlysimplified,andthedependencyonSymfonyRoutinghasbeenminimizedtothecompilingofrouteexpressions.

Withthisrelease,we'realsointroducinganentirelynewsessionengine.Similartotheroutingimprovements,thenewsessionlayerisleanerandfaster.WearenolongerusingSymfony's(andthereforePHP's)sessionhandlingfacilities,andareusingacustomsolutionthatissimplerandeasiertomaintain.

IfyouareusingtherenameColumnfunctioninyourmigrations,youwillneedtoaddthedoctrine/dbaldependencytoyourcomposer.jsonfile.ThispackageisnolongerincludedinLaravelbydefault.

QueuePriority

FailedQueueJobHandling

CacheTags

FlexiblePasswordReminders

ImprovedRoutingEngine

ImprovedSessionEngine

DoctrineDBAL

Page 18: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

UpgradingTo5.0From4.2UpgradingTo4.2From4.1UpgradingTo4.1.29From<=4.1.xUpgradingTo4.1.26From<=4.1.25UpgradingTo4.1From4.0

TherecommendedmethodofupgradingistocreateanewLaravel5.0installandthentocopyyour4.2site'suniqueapplicationfilesintothenewapplication.Thiswouldincludecontrollers,routes,Eloquentmodels,Artisancommands,assets,andothercodespecifictoyourapplication.

Tostart,installanewLaravel5applicationintoafreshdirectoryinyourlocalenvironment.We'lldiscusseachpieceofthemigrationprocessinfurtherdetailbelow.

Don'tforgettocopyanyadditionalComposerdependenciesintoyour5.0application.Thisincludesthird-partycodesuchasSDKs.

SomeLaravel-specificpackagesmaynotbecompatiblewithLaravel5oninitialrelease.Checkwithyourpackage'smaintainertodeterminetheproperversionofthepackageforLaravel5.OnceyouhaveaddedanyadditionalComposerdependenciesyourapplicationneeds,runcomposerupdate.

Bydefault,Laravel4applicationsdidnotutilizenamespacingwithinyourapplicationcode.So,forexample,allEloquentmodelsandcontrollerssimplylivedinthe"global"namespace.Foraquickermigration,youcansimplyleavetheseclassesintheglobalnamespaceinLaravel5aswell.

Copythenew.env.examplefileto.env,whichisthe5.0equivalentoftheold.env.phpfile.Setanyappropriatevaluesthere,likeyourAPP_ENVandAPP_KEY(yourencryptionkey),yourdatabasecredentials,andyourcacheandsessiondrivers.

Additionally,copyanycustomvaluesyouhadinyourold.env.phpfileandplacetheminboth.env(therealvalueforyourlocalenvironment)and.env.example(asampleinstructionalvalueforotherteammembers).

Formoreinformationonenvironmentconfiguration,viewthefulldocumentation.

Note:Youwillneedtoplacetheappropriate.envfileandvaluesonyourproductionserverbeforedeployingyourLaravel5application.

Laravel5.0nolongerusesapp/config/{environmentName}/directoriestoprovidespecificconfigurationfilesforagivenenvironment.Instead,moveanyconfigurationvaluesthatvarybyenvironmentinto.env,andthenaccesstheminyour

UpgradeGuide

UpgradingTo5.0From4.2

FreshInstall,ThenMigrate

ComposerDependencies&Packages

Namespacing

Configuration

MigratingEnvironmentVariables

ConfigurationFiles

Page 19: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

configurationfilesusingenv('key','defaultvalue').Youwillseeexamplesofthisintheconfig/database.phpconfigurationfile.

Settheconfigfilesintheconfig/directorytorepresenteitherthevaluesthatareconsistentacrossallofyourenvironments,orsetthemtouseenv()toloadvaluesthatvarybyenvironment.

Remember,ifyouaddmorekeysto.envfile,addsamplevaluestothe.env.examplefileaswell.Thiswillhelpyourotherteammemberscreatetheirown.envfiles.

Copyandpasteyouroldroutes.phpfileintoyournewapp/Http/routes.php.

Next,moveallofyourcontrollersintotheapp/Http/Controllersdirectory.Sincewearenotgoingtomigratetofullnamespacinginthisguide,addtheapp/Http/Controllersdirectorytotheclassmapdirectiveofyourcomposer.jsonfile.Next,youcanremovethenamespacefromtheabstractapp/Http/Controllers/Controller.phpbaseclass.Verifythatyourmigratedcontrollersareextendingthisbaseclass.

Inyourapp/Providers/RouteServiceProvider.phpfile,setthenamespacepropertytonull.

Copyyourfilterbindingsfromapp/filters.phpandplacethemintotheboot()methodofapp/Providers/RouteServiceProvider.php.AdduseIlluminate\Support\Facades\Route;intheapp/Providers/RouteServiceProvider.phpinordertocontinueusingtheRouteFacade.

YoudonotneedtomoveoveranyofthedefaultLaravel4.0filterssuchasauthandcsrf;they'reallhere,butasmiddleware.Editanyroutesorcontrollersthatreferencetheolddefaultfilters(e.g.['before'=>'auth'])andchangethemtoreferencethenewmiddleware(e.g.['middleware'=>'auth'].)

FiltersarenotremovedinLaravel5.Youcanstillbindanduseyourowncustomfiltersusingbeforeandafter.

Bydefault,CSRFprotectionisenabledonallroutes.Ifyou'dliketodisablethis,oronlymanuallyenableitoncertainroutes,removethislinefromApp\Http\Kernel'smiddlewarearray:

'App\Http\Middleware\VerifyCsrfToken',

Ifyouwanttouseitelsewhere,addthislineto$routeMiddleware:

'csrf'=>'App\Http\Middleware\VerifyCsrfToken',

Nowyoucanaddthemiddlewaretoindividualroutes/controllersusing['middleware'=>'csrf']ontheroute.Formoreinformationonmiddleware,consultthefulldocumentation.

Feelfreetocreateanewapp/ModelsdirectorytohouseyourEloquentmodels.Again,addthisdirectorytotheclassmapdirectiveofyourcomposer.jsonfile.

UpdateanymodelsusingSoftDeletingTraittouseIlluminate\Database\Eloquent\SoftDeletes.

Routes

Controllers

RouteFilters

GlobalCSRF

EloquentModels

Page 20: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Eloquentnolongerprovidestheremembermethodforcachingqueries.YounowareresponsibleforcachingyourqueriesmanuallyusingtheCache::rememberfunction.Formoreinformationoncaching,consultthefulldocumentation.

ToupgradeyourUsermodelforLaravel5'sauthenticationsystem,followtheseinstructions:

Deletethefollowingfromyouruseblock:

useIlluminate\Auth\UserInterface;

useIlluminate\Auth\Reminders\RemindableInterface;

Addthefollowingtoyouruseblock:

useIlluminate\Auth\Authenticatable;

useIlluminate\Auth\Passwords\CanResetPassword;

useIlluminate\Contracts\Auth\AuthenticatableasAuthenticatableContract;

useIlluminate\Contracts\Auth\CanResetPasswordasCanResetPasswordContract;

RemovetheUserInterfaceandRemindableInterfaceinterfaces.

Marktheclassasimplementingthefollowinginterfaces:

implementsAuthenticatableContract,CanResetPasswordContract

Includethefollowingtraitswithintheclassdeclaration:

useAuthenticatable,CanResetPassword;

Ifyouusedthem,removeIlluminate\Auth\Reminders\RemindableTraitandIlluminate\Auth\UserTraitfromyouruseblockandyourclassdeclaration.

ThenameofthetraitandinterfaceusedbyLaravelCashierhaschanged.InsteadofusingBillableTrait,usetheLaravel\Cashier\Billabletrait.And,insteadofLaravel\Cashier\BillableInterfaceimplementtheLaravel\Cashier\Contracts\Billableinterfaceinstead.Noothermethodchangesarerequired.

Moveallofyourcommandclassesfromyouroldapp/commandsdirectorytothenewapp/Console/Commandsdirectory.Next,addtheapp/Console/Commandsdirectorytotheclassmapdirectiveofyourcomposer.jsonfile.

Then,copyyourlistofArtisancommandsfromstart/artisan.phpintothecommandarrayoftheapp/Console/Kernel.phpfile.

DeletethetwomigrationsincludedwithLaravel5.0,sinceyoushouldalreadyhavetheuserstableinyourdatabase.

Moveallofyourmigrationclassesfromtheoldapp/database/migrationsdirectorytothenewdatabase/migrations.Allofyourseedsshouldbemovedfromapp/database/seedstodatabase/seeds.

EloquentCaching

UserAuthenticationModel

CashierUserChanges

ArtisanCommands

DatabaseMigrations&Seeds

Page 21: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IfyouhaveanyIoCbindingsinstart/global.php,movethemalltotheregistermethodoftheapp/Providers/AppServiceProvider.phpfile.YoumayneedtoimporttheAppfacade.

Optionally,youmaybreakthesebindingsupintoseparateserviceprovidersbycategory.

Moveyourviewsfromapp/viewstothenewresources/viewsdirectory.

Forbettersecuritybydefault,Laravel5.0escapesalloutputfromboththe{{}}and{{{}}}Bladedirectives.Anew{!!!!}directivehasbeenintroducedtodisplayraw,unescapedoutput.Themostsecureoptionwhenupgradingyourapplicationistoonlyusethenew{!!!!}directivewhenyouarecertainthatitissafetodisplayrawoutput.

However,ifyoumustusetheoldBladesyntax,addthefollowinglinesatthebottomofAppServiceProvider@register:

\Blade::setRawTags('{{','}}');

\Blade::setContentTags('{{{','}}}');

\Blade::setEscapedContentTags('{{{','}}}');

Thisshouldnotbedonelightly,andmaymakeyourapplicationmorevulnerabletoXSSexploits.Also,commentswith{{--willnolongerwork.

Moveyourlanguagefilesfromapp/langtothenewresources/langdirectory.

Copyyourapplication'spublicassetsfromyour4.2application'spublicdirectorytoyournewapplication'spublicdirectory.Besuretokeepthe5.0versionofindex.php.

Moveyourtestsfromapp/teststothenewtestsdirectory.

Copyinanyotherfilesinyourproject.Forexample,.scrutinizer.yml,bower.jsonandothersimilartoolingconfigurationfiles.

YoumaymoveyourSass,Less,orCoffeeScripttoanylocationyouwish.Theresources/assetsdirectorycouldbeagooddefaultlocation.

Ifyou'reusingFormorHTMLhelpers,youwillseeanerrorstatingclass'Form'notfoundorclass'Html'notfound.Tofixthis,add"illuminate/html":"~5.0"toyourcomposer.jsonfile'srequiresection.

You'llalsoneedtoaddtheFormandHTMLfacadesandserviceprovider.Editconfig/app.php,andaddthislinetothe'providers'array:

GlobalIoCBindings

Views

BladeTagChanges

TranslationFiles

PublicDirectory

Tests

Misc.Files

Form&HTMLHelpers

Page 22: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

'Illuminate\Html\HtmlServiceProvider',

Next,addtheselinestothe'aliases'array:

'Form'=>'Illuminate\Html\FormFacade',

'Html'=>'Illuminate\Html\HtmlFacade',

IfyourapplicationcodewasinjectingIlluminate\Cache\CacheManagertogetanon-FacadeversionofLaravel'scache,injectIlluminate\Contracts\Cache\Repositoryinstead.

Replaceanycallsto$paginator->links()with$paginator->render().

Laravel5.0nowrequires"pda/pheanstalk":"~3.0"insteadof"pda/pheanstalk":"~2.1".

TheRemotecomponenthasbeendeprecated.

TheWorkbenchcomponenthasbeendeprecated.

Laravel4.2requiresPHP5.4.0orgreater.

Addanewcipheroptioninyourapp/config/app.phpconfigurationfile.ThevalueofthisoptionshouldbeMCRYPT_RIJNDAEL_256.

'cipher'=>MCRYPT_RIJNDAEL_256

ThissettingmaybeusedtocontrolthedefaultcipherusedbytheLaravelencryptionfacilities.

Note:InLaravel4.2,thedefaultcipherisMCRYPT_RIJNDAEL_128(AES),whichisconsideredtobethemostsecurecipher.ChangingthecipherbacktoMCRYPT_RIJNDAEL_256isrequiredtodecryptcookies/valuesthatwereencryptedinLaravel<=4.1

Ifyouareusingsoftdeletingmodels,thesoftDeletespropertyhasbeenremoved.YoumustnowusetheSoftDeletingTraitlikeso:

CacheManager

Pagination

BeanstalkQueuing

Remote

Workbench

UpgradingTo4.2From4.1

PHP5.4+

EncryptionDefaults

SoftDeletingModelsNowUseTraits

Page 23: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

useIlluminate\Database\Eloquent\SoftDeletingTrait;

classUserextendsEloquent{

useSoftDeletingTrait;

}

Youmustalsomanuallyaddthedeleted_atcolumntoyourdatesproperty:

classUserextendsEloquent{

useSoftDeletingTrait;

protected$dates=['deleted_at'];

}

TheAPIforallsoftdeleteoperationsremainsthesame.

Note:TheSoftDeletingTraitcannotbeappliedonabasemodel.Itmustbeusedonanactualmodelclass.

IfyouaredirectlyreferencingtheIlluminate\View\EnvironmentclassorIlluminate\Pagination\Environmentclass,updateyourcodetoreferenceIlluminate\View\FactoryandIlluminate\Pagination\Factoryinstead.Thesetwoclasseshavebeenrenamedtobetterreflecttheirfunction.

IfyouareextendingtheIlluminate\Pagination\Presenterclass,theabstractmethodgetPageLinkWrappersignaturehaschangedtoaddtherelargument:

abstractpublicfunctiongetPageLinkWrapper($url,$page,$rel=null);

IfyouareusingtheIron.ioqueuedriver,youwillneedtoaddanewencryptoptiontoyourqueueconfigurationfile:

'encrypt'=>true

Laravel4.1.29improvesthecolumnquotingforalldatabasedrivers.Thisprotectsyourapplicationfromsomemassassignmentvulnerabilitieswhennotusingthefillablepropertyonmodels.Ifyouareusingthefillablepropertyonyourmodelstoprotectagainstmassassignment,yourapplicationisnotvulnerable.However,ifyouareusingguardedandarepassingausercontrolledarrayintoan"update"or"save"typefunction,youshouldupgradeto4.1.29immediatelyasyourapplicationmaybeatriskofmassassignment.

ToupgradetoLaravel4.1.29,simplycomposerupdate.Nobreakingchangesareintroducedinthisrelease.

Laravel4.1.26introducessecurityimprovementsfor"rememberme"cookies.Beforethisupdate,ifaremembercookiewashijackedbyanothermalicioususer,thecookiewouldremainvalidforalongperiodoftime,evenafterthetrueowneroftheaccountresettheirpassword,loggedout,etc.

View/PaginationEnvironmentRenamed

AdditionalParameterOnPaginationPresenter

Iron.IoQueueEncryption

UpgradingTo4.1.29From<=4.1.x

UpgradingTo4.1.26From<=4.1.25

Page 24: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Thischangerequirestheadditionofanewremember_tokencolumntoyourusers(orequivalent)databasetable.Afterthischange,afreshtokenwillbeassignedtotheusereachtimetheylogintoyourapplication.Thetokenwillalsoberefreshedwhentheuserlogsoutoftheapplication.Theimplicationsofthischangeare:ifa"rememberme"cookieishijacked,simplyloggingoutoftheapplicationwillinvalidatethecookie.

First,addanew,nullableremember_tokenofVARCHAR(100),TEXT,orequivalenttoyouruserstable.

Next,ifyouareusingtheEloquentauthenticationdriver,updateyourUserclasswiththefollowingthreemethods:

publicfunctiongetRememberToken()

{

return$this->remember_token;

}

publicfunctionsetRememberToken($value)

{

$this->remember_token=$value;

}

publicfunctiongetRememberTokenName()

{

return'remember_token';

}

Note:Allexisting"rememberme"sessionswillbeinvalidatedbythischange,soalluserswillbeforcedtore-authenticatewithyourapplication.

TwonewmethodswereaddedtotheIlluminate\Auth\UserProviderInterfaceinterface.Sampleimplementationsmaybefoundinthedefaultdrivers:

publicfunctionretrieveByToken($identifier,$token);

publicfunctionupdateRememberToken(UserInterface$user,$token);

TheIlluminate\Auth\UserInterfacealsoreceivedthethreenewmethodsdescribedinthe"UpgradePath".

ToupgradeyourapplicationtoLaravel4.1,changeyourlaravel/frameworkversionto4.1.*inyourcomposer.jsonfile.

Replaceyourpublic/index.phpfilewiththisfreshcopyfromtherepository.

Replaceyourartisanfilewiththisfreshcopyfromtherepository.

Updateyouraliasesandprovidersarraysinyourapp/config/app.phpconfigurationfile.Theupdatedvaluesforthesearrayscanbefoundinthisfile.Besuretoaddyourcustomandpackageserviceproviders/aliasesbacktothearrays.

Addthenewapp/config/remote.phpfilefromtherepository.

UpgradePath

PackageMaintainers

UpgradingTo4.1From4.0

UpgradingYourComposerDependency

ReplacingFiles

AddingConfigurationFiles&Options

Page 25: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Addthenewexpire_on_closeconfigurationoptiontoyourapp/config/session.phpfile.Thedefaultvalueshouldbefalse.

Addthenewfailedconfigurationsectiontoyourapp/config/queue.phpfile.Herearethedefaultvaluesforthesection:

'failed'=>array(

'database'=>'mysql','table'=>'failed_jobs',

),

(Optional)Updatethepaginationconfigurationoptioninyourapp/config/view.phpfiletopagination::slider-3.

Ifapp/controllers/BaseController.phphasausestatementatthetop,changeuseIlluminate\Routing\Controllers\Controller;touseIlluminate\Routing\Controller;.

Passwordremindershavebeenoverhauledforgreaterflexibility.Youmayexaminethenewstubcontrollerbyrunningthephpartisanauth:reminders-controllerArtisancommand.Youmayalsobrowsetheupdateddocumentationandupdateyourapplicationaccordingly.

Updateyourapp/lang/en/reminders.phplanguagefiletomatchthisupdatedfile.

Forsecurityreasons,URLdomainsmaynolongerbeusedtodetectyourapplicationenvironment.Thesevaluesareeasilyspoofableandallowattackerstomodifytheenvironmentforarequest.Youshouldconvertyourenvironmentdetectiontousemachinehostnames(hostnamecommandonMac,Linux,andWindows).

Laravelnowgeneratesasinglelogfile:app/storage/logs/laravel.log.However,youmaystillconfigurethisbehaviorinyourapp/start/global.phpfile.

Inyourbootstrap/start.phpfile,removethecallto$app->redirectIfTrailingSlash().Thismethodisnolongerneededasthisfunctionalityisnowhandledbythe.htaccessfileincludedwiththeframework.

Next,replaceyourApache.htaccessfilewiththisnewonethathandlestrailingslashes.

ThecurrentrouteisnowaccessedviaRoute::current()insteadofRoute::getCurrentRoute().

Onceyouhavecompletedthechangesabove,youcanrunthecomposerupdatefunctiontoupdateyourcoreapplicationfiles!Ifyoureceiveclassloaderrors,tryrunningtheupdatecommandwiththe--no-scriptsoptionenabledlikeso:composerupdate--no-scripts.

Thewildcardeventlistenersnolongerappendtheeventtoyourhandlerfunctionsparameters.IfyourequirefindingtheeventthatwasfiredyoushoulduseEvent::firing().

ControllerUpdates

PasswordRemindersUpdates

EnvironmentDetectionUpdates

SimplerLogFiles

RemovingRedirectTrailingSlash

CurrentRouteAccess

ComposerUpdate

WildcardEventListeners

Page 26: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

BugReportsCoreDevelopmentDiscussionWhichBranch?SecurityVulnerabilitiesCodingStyle

Toencourageactivecollaboration,Laravelstronglyencouragespullrequests,notjustbugreports."Bugreports"mayalsobesentintheformofapullrequestcontainingafailingunittest.

However,ifyoufileabugreport,yourissueshouldcontainatitleandacleardescriptionoftheissue.Youshouldalsoincludeasmuchrelevantinformationaspossibleandacodesamplethatdemonstratestheissue.Thegoalofabugreportistomakeiteasyforyourself-andothers-toreplicatethebuganddevelopafix.

Remember,bugreportsarecreatedinthehopethatotherswiththesameproblemwillbeabletocollaboratewithyouonsolvingit.Donotexpectthatthebugreportwillautomaticallyseeanyactivityorthatotherswilljumptofixit.Creatingabugreportservestohelpyourselfandothersstartonthepathoffixingtheproblem.

TheLaravelsourcecodeismanagedonGithub,andtherearerepositoriesforeachoftheLaravelprojects:

LaravelFrameworkLaravelApplicationLaravelDocumentationLaravelCashierLaravelEnvoyLaravelHomesteadLaravelHomesteadBuildScriptsLaravelWebsiteLaravelArt

Discussionregardingbugs,newfeatures,andimplementationofexistingfeaturestakesplaceinthe#laravel-devIRCchannel(Freenode).TaylorOtwell,themaintainerofLaravel,istypicallypresentinthechannelonweekdaysfrom8am-5pm(UTC-06:00orAmerica/Chicago),andsporadicallypresentinthechannelatothertimes.

The#laravel-devIRCchannelisopentoall.Allarewelcometojointhechanneleithertoparticipateorsimplyobservethediscussions!

Allbugfixesshouldbesenttothelateststablebranch.Bugfixesshouldneverbesenttothemasterbranchunlesstheyfixfeaturesthatexistonlyintheupcomingrelease.

MinorfeaturesthatarefullybackwardscompatiblewiththecurrentLaravelreleasemaybesenttothelateststablebranch.

Majornewfeaturesshouldalwaysbesenttothemasterbranch,whichcontainstheupcomingLaravelrelease.

Ifyouareunsureifyourfeaturequalifiesasamajororminor,pleaseaskTaylorOtwellinthe#laravel-devIRCchannel

ContributionGuide

BugReports

CoreDevelopmentDiscussion

WhichBranch?

Page 27: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

(Freenode).

IfyoudiscoverasecurityvulnerabilitywithinLaravel,pleasesendane-mailtoTaylorOtwellattaylorotwell@gmail.com.Allsecurityvulnerabilitieswillbepromptlyaddressed.

LaravelfollowsthePSR-0andPSR-1codingstandards.Inadditiontothesestandards,thefollowingcodingstandardsshouldbefollowed:

Theclassnamespacedeclarationmustbeonthesamelineas<?php.Aclass'opening{mustbeonthesamelineastheclassname.FunctionsandcontrolstructuresmustuseAllmanstylebraces.Indentwithtabs,alignwithspaces.

SecurityVulnerabilities

CodingStyle

Page 28: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

InstallationInstallComposerInstallLaravelServerRequirements

ConfigurationIntroductionAfterInstallationAccessingConfigurationValuesEnvironmentConfigurationConfigurationCachingMaintenanceModePrettyURLs

HomesteadIntroductionIncludedSoftwareInstallation&SetupDailyUsagePorts

Setup

Page 29: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

InstallComposerInstallLaravelServerRequirements

LaravelutilizesComposertomanageitsdependencies.So,beforeusingLaravel,youwillneedtomakesureyouhaveComposerinstalledonyourmachine.

First,downloadtheLaravelinstallerusingComposer.

composerglobalrequire"laravel/installer=~1.1"

Makesuretoplacethe~/.composer/vendor/bindirectoryinyourPATHsothelaravelexecutablecanbelocatedbyyoursystem.

Onceinstalled,thesimplelaravelnewcommandwillcreateafreshLaravelinstallationinthedirectoryyouspecify.Forinstance,laravelnewblogwouldcreateadirectorynamedblogcontainingafreshLaravelinstallationwithalldependenciesinstalled.ThismethodofinstallationismuchfasterthaninstallingviaComposer:

laravelnewblog

YoumayalsoinstallLaravelbyissuingtheComposercreate-projectcommandinyourterminal:

composercreate-projectlaravel/laravel--prefer-dist

TheLaravelframeworkhasafewsystemrequirements:

PHP>=5.4McryptPHPExtensionOpenSSLPHPExtensionMbstringPHPExtension

AsofPHP5.5,someOSdistributionsmayrequireyoutomanuallyinstallthePHPJSONextension.WhenusingUbuntu,thiscanbedoneviaapt-getinstallphp5-json.

Installation

InstallComposer

InstallLaravel

ViaLaravelInstaller

ViaComposerCreate-Project

ServerRequirements

Configuration

Page 30: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ThefirstthingyoushoulddoafterinstallingLaravelissetyourapplicationkeytoarandomstring.IfyouinstalledLaravelviaComposer,thiskeyhasprobablyalreadybeensetforyoubythekey:generatecommand.

Typically,thisstringshouldbe32characterslong.Thekeycanbesetinthe.envenvironmentfile.Iftheapplicationkeyisnotset,yourusersessionsandotherencrypteddatawillnotbesecure!

Laravelneedsalmostnootherconfigurationoutofthebox.Youarefreetogetstarteddeveloping!However,youmaywishtoreviewtheconfig/app.phpfileanditsdocumentation.Itcontainsseveraloptionssuchastimezoneandlocalethatyoumaywishtochangeaccordingtoyourapplication.

OnceLaravelisinstalled,youshouldalsoconfigureyourlocalenvironment.

Note:Youshouldneverhavetheapp.debugconfigurationoptionsettotrueforaproductionapplication.

Laravelmayrequiresomepermissionstobeconfigured:folderswithinstoragerequirewriteaccessbythewebserver.

Theframeworkshipswithapublic/.htaccessfilethatisusedtoallowURLswithoutindex.php.IfyouuseApachetoserveyourLaravelapplication,besuretoenablethemod_rewritemodule.

Ifthe.htaccessfilethatshipswithLaraveldoesnotworkwithyourApacheinstallation,trythisone:

Options+FollowSymLinks

RewriteEngineOn

RewriteCond%{REQUEST_FILENAME}!-d

RewriteCond%{REQUEST_FILENAME}!-f

RewriteRule^index.php[L]

OnNginx,thefollowingdirectiveinyoursiteconfigurationwillallow"pretty"URLs:

location/{

try_files$uri$uri//index.php?$query_string;

}

Ofcourse,whenusingHomestead,prettyURLswillbeconfiguredautomatically.

Permissions

PrettyURLs

Apache

Nginx

Page 31: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionAfterInstallationAccessingConfigurationValuesEnvironmentConfigurationConfigurationCachingMaintenanceModePrettyURLs

AlloftheconfigurationfilesfortheLaravelframeworkarestoredintheconfigdirectory.Eachoptionisdocumented,sofeelfreetolookthroughthefilesandgetfamiliarwiththeoptionsavailabletoyou.

AfterinstallingLaravel,youmaywishto"name"yourapplication.Bydefault,theappdirectoryisnamespacedunderApp,andautoloadedbyComposerusingthePSR-4autoloadingstandard.However,youmaychangethenamespacetomatchthenameofyourapplication,whichyoucaneasilydoviatheapp:nameArtisancommand.

Forexample,ifyourapplicationisnamed"Horsefly",youcouldrunthefollowingcommandfromtherootofyourinstallation:

phpartisanapp:nameHorsefly

Renamingyourapplicationisentirelyoptional,andyouarefreetokeeptheAppnamespaceifyouwish.

Laravelneedsverylittleconfigurationoutofthebox.Youarefreetogetstarteddeveloping!However,youmaywishtoreviewtheconfig/app.phpfileanditsdocumentation.Itcontainsseveraloptionssuchastimezoneandlocalethatyoumaywishtochangeaccordingtoyourlocation.

OnceLaravelisinstalled,youshouldalsoconfigureyourlocalenvironment.

Note:Youshouldneverhavetheapp.debugconfigurationoptionsettotrueforaproductionapplication.

Laravelmayrequireonesetofpermissionstobeconfigured:folderswithinstoragerequirewriteaccessbythewebserver.

YoumayeasilyaccessyourconfigurationvaluesusingtheConfigfacade:

$value=Config::get('app.timezone');

Config::set('app.timezone','America/Chicago');

Configuration

Introduction

AfterInstallation

NamingYourApplication

OtherConfiguration

Permissions

AccessingConfigurationValues

Page 32: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Youmayalsousetheconfighelperfunction:

$value=config('app.timezone');

Itisoftenhelpfultohavedifferentconfigurationvaluesbasedontheenvironmenttheapplicationisrunningin.Forexample,youmaywishtouseadifferentcachedriverlocallythanyoudoonyourproductionserver.It'seasyusingenvironmentbasedconfiguration.

Tomakethisacinch,LaravelutilizestheDotEnvPHPlibrarybyVanceLucas.InafreshLaravelinstallation,therootdirectoryofyourapplicationwillcontaina.env.examplefile.IfyouinstallLaravelviaComposer,thisfilewillautomaticallyberenamedto.env.Otherwise,youshouldrenamethefilemanually.

Allofthevariableslistedinthisfilewillbeloadedintothe$_ENVPHPsuper-globalwhenyourapplicationreceivesarequest.Youmayusetheenvhelpertoretrievevaluesfromthesevariables.Infact,ifyoureviewtheLaravelconfigurationfiles,youwillnoticeseveraloftheoptionsalreadyusingthishelper!

Feelfreetomodifyyourenvironmentvariablesasneededforyourownlocalserver,aswellasyourproductionenvironment.However,your.envfileshouldnotbecommittedtoyourapplication'ssourcecontrol,sinceeachdeveloper/serverusingyourapplicationcouldrequireadifferentenvironmentconfiguration.

Ifyouaredevelopingwithateam,youmaywishtocontinueincludinga.env.examplefilewithyourapplication.Byputtingplace-holdervaluesintheexampleconfigurationfile,otherdevelopersonyourteamcanclearlyseewhichenvironmentvariablesareneededtorunyourapplication.

YoumayaccessthecurrentapplicationenvironmentviatheenvironmentmethodontheApplicationinstance:

$environment=$app->environment();

Youmayalsopassargumentstotheenvironmentmethodtocheckiftheenvironmentmatchesagivenvalue:

if($app->environment('local'))

{

//Theenvironmentislocal

}

if($app->environment('local','staging'))

{

//TheenvironmentiseitherlocalORstaging...

}

Toobtainaninstanceoftheapplication,resolvetheIlluminate\Contracts\Foundation\Applicationcontractviatheservicecontainer.Ofcourse,ifyouarewithinaserviceprovider,theapplicationinstanceisavailableviathe$this->appinstancevariable.

AnapplicationinstancemayalsobeaccessedviatheapphelperoftheAppfacade:

$environment=app()->environment();

$environment=App::environment();

EnvironmentConfiguration

AccessingTheCurrentApplicationEnvironment

Page 33: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Togiveyourapplicationalittlespeedboost,youmaycacheallofyourconfigurationfilesintoasinglefileusingtheconfig:cacheArtisancommand.Thiswillcombinealloftheconfigurationoptionsforyourapplicationintoasinglefilewhichcanbeloadedquicklybytheframework.

Youshouldtypicallyruntheconfig:cachecommandaspartofyourdeploymentroutine.

Whenyourapplicationisinmaintenancemode,acustomviewwillbedisplayedforallrequestsintoyourapplication.Thismakesiteasyto"disable"yourapplicationwhileitisupdatingorwhenyouareperformingmaintenance.Amaintenancemodecheckisincludedinthedefaultmiddlewarestackforyourapplication.Iftheapplicationisinmaintenancemode,anHttpExceptionwillbethrownwithastatuscodeof503.

Toenablemaintenancemode,simplyexecutethedownArtisancommand:

phpartisandown

Todisablemaintenancemode,usetheupcommand:

phpartisanup

Thedefaulttemplateformaintenancemoderesponsesislocatedinresources/views/errors/503.blade.php.

Whileyourapplicationisinmaintenancemode,noqueuedjobswillbehandled.Thejobswillcontinuetobehandledasnormaloncetheapplicationisoutofmaintenancemode.

Theframeworkshipswithapublic/.htaccessfilethatisusedtoallowURLswithoutindex.php.IfyouuseApachetoserveyourLaravelapplication,besuretoenablethemod_rewritemodule.

Ifthe.htaccessfilethatshipswithLaraveldoesnotworkwithyourApacheinstallation,trythisone:

Options+FollowSymLinks

RewriteEngineOn

RewriteCond%{REQUEST_FILENAME}!-d

RewriteCond%{REQUEST_FILENAME}!-f

RewriteRule^index.php[L]

OnNginx,thefollowingdirectiveinyoursiteconfigurationwillallow"pretty"URLs:

ConfigurationCaching

MaintenanceMode

MaintenanceModeResponseTemplate

MaintenanceMode&Queues

PrettyURLs

Apache

Nginx

Page 34: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

location/{

try_files$uri$uri//index.php?$query_string;

}

Ofcourse,whenusingHomestead,prettyURLswillbeconfiguredautomatically.

Page 35: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionIncludedSoftwareInstallation&SetupDailyUsagePorts

LaravelstrivestomaketheentirePHPdevelopmentexperiencedelightful,includingyourlocaldevelopmentenvironment.Vagrantprovidesasimple,elegantwaytomanageandprovisionVirtualMachines.

LaravelHomesteadisanofficial,pre-packagedVagrant"box"thatprovidesyouawonderfuldevelopmentenvironmentwithoutrequiringyoutoinstallPHP,HHVM,awebserver,andanyotherserversoftwareonyourlocalmachine.Nomoreworryingaboutmessingupyouroperatingsystem!Vagrantboxesarecompletelydisposable.Ifsomethinggoeswrong,youcandestroyandre-createtheboxinminutes!

HomesteadrunsonanyWindows,Mac,orLinuxsystem,andincludestheNginxwebserver,PHP5.6,MySQL,Postgres,Redis,Memcached,andalloftheothergoodiesyouneedtodevelopamazingLaravelapplications.

Note:IfyouareusingWindows,youmayneedtoenablehardwarevirtualization(VT-x).ItcanusuallybeenabledviayourBIOS.

HomesteadiscurrentlybuiltandtestedusingVagrant1.6.

Ubuntu14.04PHP5.6HHVMNginxMySQLPostgresNode(WithBower,Grunt,andGulp)RedisMemcachedBeanstalkdLaravelEnvoyFabric+HipChatExtension

BeforelaunchingyourHomesteadenvironment,youmustinstallVirtualBoxandVagrant.Bothofthesesoftwarepackagesprovideeasy-to-usevisualinstallersforallpopularoperatingsystems.

OnceVirtualBoxandVagranthavebeeninstalled,youshouldaddthelaravel/homesteadboxtoyourVagrantinstallationusingthefollowingcommandinyourterminal.Itwilltakeafewminutestodownloadthebox,dependingonyourInternet

LaravelHomestead

Introduction

IncludedSoftware

Installation&Setup

InstallingVirtualBox&Vagrant

AddingTheVagrantBox

Page 36: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

connectionspeed:

vagrantboxaddlaravel/homestead

Alternatively,ifyoudonotwanttoinstallPHPonyourlocalmachine,youmayinstallHomesteadmanuallybysimplycloningtherepository.ConsidercloningtherepositoryintoaHomesteadfolderwithinyour"home"directory,astheHomesteadboxwillserveasthehosttoallofyourLaravel(andPHP)projects:

gitclonehttps://github.com/laravel/homestead.gitHomestead

OnceyouhaveinstalledtheHomesteadCLItool,runthebashinit.shcommandtocreatetheHomestead.yamlconfigurationfile:

bashinit.sh

TheHomestead.yamlfilewillbeplacedinyour~/.homesteaddirectory.

OncetheboxhasbeenaddedtoyourVagrantinstallation,youarereadytoinstalltheHomesteadCLItoolusingtheComposerglobalcommand:

composerglobalrequire"laravel/homestead=~2.0"

Makesuretoplacethe~/.composer/vendor/bindirectoryinyourPATHsothehomesteadexecutableisfoundwhenyourunthehomesteadcommandinyourterminal.

OnceyouhaveinstalledtheHomesteadCLItool,runtheinitcommandtocreatetheHomestead.yamlconfigurationfile:

homesteadinit

TheHomestead.yamlfilewillbeplacedinthe~/.homesteaddirectory.Ifyou'reusingaMacorLinuxsystem,youmayeditHomestead.yamlfilebyrunningthehomesteadeditcommandinyourterminal:

homesteadedit

Next,youshouldedittheHomestead.yamlfile.Inthisfile,youcanconfigurethepathtoyourpublicSSHkey,aswellasthefoldersyouwishtobesharedbetweenyourmainmachineandtheHomesteadvirtualmachine.

Don'thaveanSSHkey?OnMacandLinux,youcangenerallycreateanSSHkeypairusingthefollowingcommand:

ssh-keygen-trsa-C"you@homestead"

InstallingHomestead

ManuallyViaGit(NoLocalPHP)

WithComposer+PHPTool

SetYourSSHKey

Page 37: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

OnWindows,youmayinstallGitandusetheGitBashshellincludedwithGittoissuethecommandabove.Alternatively,youmayusePuTTYandPuTTYgen.

OnceyouhavecreatedaSSHkey,specifythekey'spathintheauthorizepropertyofyourHomestead.yamlfile.

ThefolderspropertyoftheHomestead.yamlfilelistsallofthefoldersyouwishtosharewithyourHomesteadenvironment.Asfileswithinthesefoldersarechanged,theywillbekeptinsyncbetweenyourlocalmachineandtheHomesteadenvironment.Youmayconfigureasmanysharedfoldersasnecessary!

NotfamiliarwithNginx?Noproblem.Thesitespropertyallowsyoutoeasilymapa"domain"toafolderonyourHomesteadenvironment.AsamplesiteconfigurationisincludedintheHomestead.yamlfile.Again,youmayaddasmanysitestoyourHomesteadenvironmentasnecessary.Homesteadcanserveasaconvenient,virtualizedenvironmentforeveryLaravelprojectyouareworkingon!

YoucanmakeanyHomesteadsiteuseHHVMbysettingthehhvmoptiontotrue:

sites:

-map:homestead.app

to:/home/vagrant/Code/Laravel/public

hhvm:true

ToaddBashaliasestoyourHomesteadbox,simplyaddtothealiasesfileintherootofthe~/.homesteaddirectory.

OnceyouhaveeditedtheHomestead.yamltoyourliking,runthevagrantupcommandfromyourHomesteaddirectory.

Vagrantwillbootthevirtualmachine,andconfigureyoursharedfoldersandNginxsitesautomatically!Todestroythemachine,youmayusethevagrantdestroy--forcecommand.

Don'tforgettoaddthe"domains"foryourNginxsitestothehostsfileonyourmachine!ThehostsfilewillredirectyourrequestsforthelocaldomainsintoyourHomesteadenvironment.OnMacandLinux,thisfileislocatedat/etc/hosts.OnWindows,itislocatedatC:\Windows\System32\drivers\etc\hosts.Thelinesyouaddtothisfilewilllooklikethefollowing:

192.168.10.10homestead.app

MakesuretheIPaddresslistedistheoneyousetinyourHomestead.yamlfile.Onceyouhaveaddedthedomaintoyourhostsfile,youcanaccessthesiteviayourwebbrowser!

http://homestead.app

Tolearnhowtoconnecttoyourdatabases,readon!

ConfigureYourSharedFolders

ConfigureYourNginxSites

BashAliases

LaunchTheVagrantBox

DailyUsage

ConnectingViaSSH

Page 38: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ToconnecttoyourHomesteadenvironmentviaSSH,issuethevagrantsshcommandfromyourHomesteaddirectory.

SinceyouwillprobablyneedtoSSHintoyourHomesteadmachinefrequently,considercreatingan"alias"onyourhostmachine:

aliasvm="[email protected]"

Onceyoucreatethisalias,youcansimplyusethe"vm"commandtoSSHintoyourHomesteadmachinefromanywhereonyoursystem.

AhomesteaddatabaseisconfiguredforbothMySQLandPostgresoutofthebox.Forevenmoreconvenience,Laravel'slocaldatabaseconfigurationissettousethisdatabasebydefault.

ToconnecttoyourMySQLorPostgresdatabasefromyourmainmachineviaNavicatorSequelPro,youshouldconnectto127.0.0.1andport33060(MySQL)or54320(Postgres).Theusernameandpasswordforbothdatabasesishomestead/secret.

Note:Youshouldonlyusethesenon-standardportswhenconnectingtothedatabasesfromyourmainmachine.Youwillusethedefault3306and5432portsinyourLaraveldatabaseconfigurationfilesinceLaravelisrunningwithintheVirtualMachine.

OnceyourHomesteadenvironmentisprovisionedandrunning,youmaywanttoaddadditionalNginxsitesforyourLaravelapplications.YoucanrunasmanyLaravelinstallationsasyouwishonasingleHomesteadenvironment.Therearetwowaystodothis:First,youmaysimplyaddthesitestoyourHomestead.yamlfileandthenrunvagrantprovision.

Alternatively,youmayusetheservescriptthatisavailableonyourHomesteadenvironment.Tousetheservescript,SSHintoyourHomesteadenvironmentandrunthefollowingcommand:

servedomain.app/home/vagrant/Code/path/to/public/directory

Note:Afterrunningtheservecommand,donotforgettoaddthenewsitetothehostsfileonyourmainmachine!

ThefollowingportsareforwardedtoyourHomesteadenvironment:

SSH:2222→ForwardsTo22HTTP:8000→ForwardsTo80MySQL:33060→ForwardsTo3306Postgres:54320→ForwardsTo5432

ConnectingToYourDatabases

AddingAdditionalSites

Ports

Page 39: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

RoutingBasicRoutingCSRFProtectionMethodSpoofingRouteParametersNamedRoutesRouteGroupsRouteModelBindingThrowing404Errors

MiddlewareIntroductionDefiningMiddlewareRegisteringMiddlewareTerminableMiddleware

ControllersIntroductionBasicControllersControllerMiddlewareImplicitControllersRESTfulResourceControllersDependencyInjection&ControllersRouteCaching

RequestsObtainingARequestInstanceRetrievingInputOldInputCookiesFilesOtherRequestInformation

ResponsesBasicResponsesRedirectsOtherResponsesResponseMacros

ViewsBasicUsageViewComposers

TheBasics

Page 40: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

BasicRoutingCSRFProtectionMethodSpoofingRouteParametersNamedRoutesRouteGroupsRouteModelBindingThrowing404Errors

Youwilldefinemostoftheroutesforyourapplicationintheapp/Http/routes.phpfile,whichisloadedbytheApp\Providers\RouteServiceProviderclass.ThemostbasicLaravelroutessimplyacceptaURIandaClosure:

Route::get('/',function()

{

return'HelloWorld';

});

Route::post('foo/bar',function()

{

return'HelloWorld';

});

Route::put('foo/bar',function()

{

//

});

Route::delete('foo/bar',function()

{

//

});

Route::match(['get','post'],'/',function()

{

return'HelloWorld';

});

Route::any('foo',function()

{

return'HelloWorld';

});

Often,youwillneedtogenerateURLstoyourroutes,youmaydosousingtheurlhelper:

HTTPRouting

BasicRouting

BasicGETRoute

OtherBasicRoutesRoute

RegisteringARouteForMultipleVerbs

RegisteringARouteThatRespondsToAnyHTTPVerb

Page 41: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$url=url('foo');

Laravelmakesiteasytoprotectyourapplicationfromcross-siterequestforgeries.Cross-siterequestforgeriesareatypeofmaliciousexploitwherebyunauthorizedcommandsareperformedonbehalfoftheauthenticateduser.

LaravelautomaticallygeneratesaCSRF"token"foreachactiveusersessionmanagedbytheapplication.Thistokenisusedtoverifythattheauthenticateduseristheoneactuallymakingtherequeststotheapplication.

<inputtype="hidden"name="_token"value="<?phpechocsrf_token();?>">

Ofcourse,usingtheBladetemplatingengine:

<inputtype="hidden"name="_token"value="{{csrf_token()}}">

YoudonotneedtomanuallyverifytheCSRFtokenonPOST,PUT,orDELETErequests.TheVerifyCsrfTokenHTTPmiddlewarewillverifytokenintherequestinputmatchesthetokenstoredinthesession.

InadditiontolookingfortheCSRFtokenasa"POST"parameter,themiddlewarewillalsocheckfortheX-XSRF-TOKENrequestheader,whichiscommonlyusedbyJavaScriptframeworks.

HTMLformsdonotsupportPUTorDELETEactions.So,whendefiningPUTorDELETEroutesthatarecalledfromanHTMLform,youwillneedtoaddahidden_methodfieldtotheform.

Thevaluesentwiththe_methodfieldwillbeusedastheHTTPrequestmethod.Forexample:

<formaction="/foo/bar"method="POST">

<inputtype="hidden"name="_method"value="PUT">

<inputtype="hidden"name="_token"value="<?phpechocsrf_token();?>">

</form>

Ofcourse,youcancapturesegmentsoftherequestURIwithinyourroute:

Route::get('user/{id}',function($id)

{

return'User'.$id;

});

CSRFProtection

InsertTheCSRFTokenIntoAForm

MethodSpoofing

RouteParameters

BasicRouteParameter

OptionalRouteParameters

Page 42: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Route::get('user/{name?}',function($name=null)

{

return$name;

});

Route::get('user/{name?}',function($name='John')

{

return$name;

});

Route::get('user/{name}',function($name)

{

//

})

->where('name','[A-Za-z]+');

Route::get('user/{id}',function($id)

{

//

})

->where('id','[0-9]+');

Route::get('user/{id}/{name}',function($id,$name)

{

//

})

->where(['id'=>'[0-9]+','name'=>'[a-z]+'])

Ifyouwouldlikearouteparametertoalwaysbeconstrainedbyagivenregularexpression,youmayusethepatternmethod.YoushoulddefinethesepatternsinthebeforemethodofyourRouteServiceProvider:

$router->pattern('id','[0-9]+');

Oncethepatternhasbeendefined,itisappliedtoallroutesusingthatparameter:

Route::get('user/{id}',function($id)

{

//Onlycalledif{id}isnumeric.

});

Ifyouneedtoaccessarouteparametervalueoutsideofaroute,usetheinputmethod:

if($route->input('id')==1)

{

//

}

OptionalRouteParametersWithDefaultValue

RegularExpressionParameterConstraints

PassingAnArrayOfConstraints

DefiningGlobalPatterns

AccessingARouteParameterValue

Page 43: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

YoumayalsoaccessthecurrentrouteparametersviatheIlluminate\Http\Requestinstance.TherequestinstanceforthecurrentrequestmaybeaccessedviatheRequestfacade,orbytype-hintingtheIlluminate\Http\Requestwheredependenciesareinjected:

useIlluminate\Http\Request;

Route::get('user/{id}',function(Request$request,$id)

{

if($request->route('id'))

{

//

}

});

NamedroutesallowyoutoconvenientlygenerateURLsorredirectsforaspecificroute.Youmayspecifyanameforaroutewiththeasarraykey:

Route::get('user/profile',['as'=>'profile',function()

{

//

}]);

Youmayalsospecifyroutenamesforcontrolleractions:

Route::get('user/profile',[

'as'=>'profile','uses'=>'UserController@showProfile'

]);

Now,youmayusetheroute'snamewhengeneratingURLsorredirects:

$url=route('profile');

$redirect=redirect()->route('profile');

ThecurrentRouteNamemethodreturnsthenameoftheroutehandlingthecurrentrequest:

$name=Route::currentRouteName();

Sometimesyoumayneedtoapplyfilterstoagroupofroutes.Insteadofspecifyingthefilteroneachroute,youmayusearoutegroup:

Route::group(['middleware'=>'auth'],function()

{

Route::get('/',function()

{

//HasAuthFilter

});

Route::get('user/profile',function()

{

//HasAuthFilter

NamedRoutes

RouteGroups

Page 44: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

});

});

Youmayusethenamespaceparameterwithinyourgrouparraytospecifythenamespaceforallcontrollerswithinthegroup:

Route::group(['namespace'=>'Admin'],function()

{

//

});

Note:Bydefault,theRouteServiceProviderincludesyourroutes.phpfilewithinanamespacegroup,allowingyoutoregistercontrollerrouteswithoutspecifyingthefullnamespace.

Laravelroutesalsohandlewildcardsub-domains,andwillpassyourwildcardparametersfromthedomain:

Route::group(['domain'=>'{account}.myapp.com'],function()

{

Route::get('user/{id}',function($account,$id)

{

//

});

});

Agroupofroutesmaybeprefixedbyusingtheprefixoptionintheattributesarrayofagroup:

Route::group(['prefix'=>'admin'],function()

{

Route::get('user',function()

{

//

});

});

Laravelmodelbindingprovidesaconvenientwaytoinjectclassinstancesintoyourroutes.Forexample,insteadofinjectingauser'sID,youcaninjecttheentireUserclassinstancethatmatchesthegivenID.

First,usetherouter'smodelmethodtospecifytheclassforagivenparameter.YoushoulddefineyourmodelbindingsintheRouteServiceProvider::bootmethod:

publicfunctionboot(Router$router)

{

parent::boot($router);

Sub-DomainRouting

RegisteringSub-DomainRoutes

RoutePrefixing

RouteModelBinding

BindingAParameterToAModel

Page 45: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$router->model('user','App\User');

}

Next,definearoutethatcontainsa{user}parameter:

Route::get('profile/{user}',function(App\User$user)

{

//

});

Sincewehaveboundthe{user}parametertotheApp\Usermodel,aUserinstancewillbeinjectedintotheroute.So,forexample,arequesttoprofile/1willinjecttheUserinstancewhichhasanIDof1.

Note:Ifamatchingmodelinstanceisnotfoundinthedatabase,a404errorwillbethrown.

Ifyouwishtospecifyyourown"notfound"behavior,passaClosureasthethirdargumenttothemodelmethod:

Route::model('user','User',function()

{

thrownewNotFoundHttpException;

});

Ifyouwishtouseyourownresolutionlogic,youshouldusetheRouter::bindmethod.TheClosureyoupasstothebindmethodwillreceivethevalueoftheURIsegment,andshouldreturnaninstanceoftheclassyouwanttobeinjectedintotheroute:

Route::bind('user',function($value)

{

returnUser::where('name',$value)->first();

});

Therearetwowaystomanuallytriggera404errorfromaroute.First,youmayusetheaborthelper:

abort(404);

TheaborthelpersimplythrowsaSymfony\Component\HttpFoundation\Exception\HttpExceptionwiththespecifiedstatuscode.

Secondly,youmaymanuallythrowaninstanceofSymfony\Component\HttpKernel\Exception\NotFoundHttpException.

Moreinformationonhandling404exceptionsandusingcustomresponsesfortheseerrorsmaybefoundintheerrorssectionofthedocumentation.

Throwing404Errors

Page 46: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionDefiningMiddlewareRegisteringMiddlewareTerminableMiddleware

HTTPmiddlewareprovideaconvenientmechanismforfilteringHTTPrequestsenteringyourapplication.Forexample,Laravelincludesamiddlewarethatverifiestheuserofyourapplicationisauthenticated.Iftheuserisnotauthenticated,themiddlewarewillredirecttheusertotheloginscreen.However,iftheuserisauthenticated,themiddlewarewillallowtherequesttoproceedfurtherintotheapplication.

Ofcourse,middlewarecanbewrittentoperformavarietyoftasksbesidesauthentication.ACORSmiddlewaremightberesponsibleforaddingtheproperheaderstoallresponsesleavingyourapplication.Aloggingmiddlewaremightlogallincomingrequeststoyourapplication.

ThereareseveralmiddlewareincludedintheLaravelframework,includingmiddlewareformaintenance,authentication,CSRFprotection,andmore.Allofthesemiddlewarearelocatedintheapp/Http/Middlewaredirectory.

Tocreateanewmiddleware,usethemake:middlewareArtisancommand:

phpartisanmake:middlewareOldMiddleware

ThiscommandwillplaceanewOldMiddlewareclasswithinyourapp/Http/Middlewaredirectory.Inthismiddleware,wewillonlyallowaccesstotherouteifthesuppliedageisgreaterthan200.Otherwise,wewillredirecttheusersbacktothe"home"URI.

<?phpnamespaceApp\Http\Middleware;

classOldMiddleware{

/**

*Runtherequestfilter.

*

*@param\Illuminate\Http\Request$request

*@param\Closure$next

*@returnmixed

*/

publicfunctionhandle($request,Closure$next)

{

if($request->input('age')<200)

{

returnredirect('home');

}

return$next($request);

}

}

Asyoucansee,ifthegivenageislessthan200,themiddlewarewillreturnanHTTPredirecttotheclient;otherwise,therequestwillbepassedfurtherintotheapplication.Topasstherequestdeeperintotheapplication(allowingthemiddlewareto"pass"),simplycallthe$nextcallbackwiththe$request.

HTTPMiddleware

Introduction

DefiningMiddleware

Page 47: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

It'sbesttoenvisionmiddlewareasaseriesof"layers"HTTPrequestsmustpassthroughbeforetheyhityourapplication.Eachlayercanexaminetherequestandevenrejectitentirely.

IfyouwantamiddlewaretoberunduringeveryHTTPrequesttoyourapplication,simplylistthemiddlewareclassinthe$middlewarepropertyofyourapp/Http/Kernel.phpclass.

Ifyouwouldliketoassignmiddlewaretospecificroutes,youshouldfirstassignthemiddlewareashort-handkeyinyourapp/Http/Kernel.phpfile.Bydefault,the$routeMiddlewarepropertyofthisclasscontainsentriesforthemiddlewareincludedwithLaravel.Toaddyourown,simplyappendittothislistandassignitakeyofyourchoosing.

OncethemiddlewarehasbeendefinedintheHTTPkernel,youmayusethemiddlewarekeyintherouteoptionsarray:

Route::get('admin/profile',['middleware'=>'auth',function()

{

//

}]);

SometimesamiddlewaremayneedtodosomeworkaftertheHTTPresponsehasalreadybeensenttothebrowser.Forexample,the"session"middlewareincludedwithLaravelwritesthesessiondatatostorageaftertheresponsehasbeensenttothebrowser.Toaccomplishthis,youmaydefinethemiddlewareas"terminable".

useIlluminate\Contracts\Routing\TerminableMiddleware;

classStartSessionimplementsTerminableMiddleware{

publicfunctionhandle($request,$next)

{

return$next($request);

}

publicfunctionterminate($request,$response)

{

//Storethesessiondata...

}

}

Asyoucansee,inadditiontodefiningahandlemethod,TerminableMiddlewaredefineaterminatemethod.Thismethodreceivesboththerequestandtheresponse.Onceyouhavedefinedaterminablemiddleware,youshouldaddittothelistofglobalmiddlewaresinyourHTTPkernel.

RegisteringMiddleware

GlobalMiddleware

AssigningMiddlewareToRoutes

TerminableMiddleware

Page 48: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionBasicControllersControllerMiddlewareImplicitControllersRESTfulResourceControllersDependencyInjection&ControllersRouteCaching

Insteadofdefiningallofyourrequesthandlinglogicinasingleroutes.phpfile,youmaywishtoorganizethisbehaviorusingControllerclasses.ControllerscangrouprelatedHTTPrequesthandlinglogicintoaclass.Controllersaretypicallystoredintheapp/Http/Controllersdirectory.

Hereisanexampleofabasiccontrollerclass:

<?phpnamespaceApp\Http\Controllers;

useApp\Http\Controllers\Controller;

classUserControllerextendsController{

/**

*Showtheprofileforthegivenuser.

*

*@paramint$id

*@returnResponse

*/

publicfunctionshowProfile($id)

{

returnview('user.profile',['user'=>User::findOrFail($id)]);

}

}

Wecanroutetothecontrolleractionlikeso:

Route::get('user/{id}','UserController@showProfile');

Note:Allcontrollersshouldextendthebasecontrollerclass.

Itisveryimportanttonotethatwedidnotneedtospecifythefullcontrollernamespace,onlytheportionoftheclassnamethatcomesaftertheApp\Http\Controllersnamespace"root".Bydefault,theRouteServiceProviderwillloadtheroutes.phpfilewithinaroutegroupcontainingtherootcontrollernamespace.

IfyouchoosetonestororganizeyourcontrollersusingPHPnamespacesdeeperintotheApp\Http\Controllersdirectory,simplyusethespecificclassnamerelativetotheApp\Http\Controllersrootnamespace.So,ifyourfullcontrollerclassisApp\Http\Controllers\Photos\AdminController,youwouldregisteraroutelikeso:

HTTPControllers

Introduction

BasicControllers

Controllers&Namespaces

Page 49: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Route::get('foo','Photos\AdminController@method');

LikeClosureroutes,youmayspecifynamesoncontrollerroutes:

Route::get('foo',['uses'=>'FooController@method','as'=>'name']);

TogenerateaURLtoacontrolleraction,usetheactionhelpermethod:

$url=action('App\Http\Controllers\FooController@method');

IfyouwishtogenerateaURLtoacontrolleractionwhileusingonlytheportionoftheclassnamerelativetoyourcontrollernamespace,registertherootcontrollernamespacewiththeURLgenerator:

URL::setRootControllerNamespace('App\Http\Controllers');

$url=action('FooController@method');

YoumayaccessthenameofthecontrolleractionbeingrunusingthecurrentRouteActionmethod:

$action=Route::currentRouteAction();

Middlewaremaybespecifiedoncontrollerrouteslikeso:

Route::get('profile',[

'middleware'=>'auth',

'uses'=>'UserController@showProfile'

]);

Additionally,youmayspecifymiddlewarewithinyourcontroller'sconstructor:

classUserControllerextendsController{

/**

*InstantiateanewUserControllerinstance.

*/

publicfunction__construct()

{

$this->middleware('auth');

$this->middleware('log',['only'=>['fooAction','barAction']]);

$this->middleware('subscribed',['except'=>['fooAction','barAction']]);

}

}

NamingControllerRoutes

URLsToControllerActions

ControllerMiddleware

ImplicitControllers

Page 50: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Laravelallowsyoutoeasilydefineasingleroutetohandleeveryactioninacontroller.First,definetherouteusingtheRoute::controllermethod:

Route::controller('users','UserController');

Thecontrollermethodacceptstwoarguments.ThefirstisthebaseURIthecontrollerhandles,whilethesecondistheclassnameofthecontroller.Next,justaddmethodstoyourcontroller,prefixedwiththeHTTPverbtheyrespondto:

classUserControllerextendsBaseController{

publicfunctiongetIndex()

{

//

}

publicfunctionpostProfile()

{

//

}

publicfunctionanyLogin()

{

//

}

}

TheindexmethodswillrespondtotherootURIhandledbythecontroller,which,inthiscase,isusers.

Ifyourcontrolleractioncontainsmultiplewords,youmayaccesstheactionusing"dash"syntaxintheURI.Forexample,thefollowingcontrolleractiononourUserControllerwouldrespondtotheusers/admin-profileURI:

publicfunctiongetAdminProfile(){}

ResourcecontrollersmakeitpainlesstobuildRESTfulcontrollersaroundresources.Forexample,youmaywishtocreateacontrollerthathandlesHTTPrequestsregarding"photos"storedbyyourapplication.Usingthemake:controllerArtisancommand,wecanquicklycreatesuchacontroller:

phpartisanmake:controllerPhotoController

Next,weregisteraresourcefulroutetothecontroller:

Route::resource('photo','PhotoController');

ThissingleroutedeclarationcreatesmultipleroutestohandleavarietyofRESTfulactionsonthephotoresource.Likewise,thegeneratedcontrollerwillalreadyhavemethodsstubbedforeachoftheseactions,includingnotesinformingyouwhichURIsandverbstheyhandle.

Verb Path Action RouteName

GET /resource index resource.index

RESTfulResourceControllers

ActionsHandledByResourceController

Page 51: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

GET /resource/create create resource.create

POST /resource store resource.store

GET /resource/{resource} show resource.show

GET /resource/{resource}/edit edit resource.edit

PUT/PATCH /resource/{resource} update resource.update

DELETE /resource/{resource} destroy resource.destroy

Additionally,youmayspecifyonlyasubsetofactionstohandleontheroute:

Route::resource('photo','PhotoController',

['only'=>['index','show']]);

Route::resource('photo','PhotoController',

['except'=>['create','store','update','destroy']]);

Bydefault,allresourcecontrolleractionshavearoutename;however,youcanoverridethesenamesbypassinganamesarraywithyouroptions:

Route::resource('photo','PhotoController',

['names'=>['create'=>'photo.build']]);

To"nest"resourcecontrollers,use"dot"notationinyourroutedeclaration:

Route::resource('photos.comments','PhotoCommentController');

Thisroutewillregistera"nested"resourcethatmaybeaccessedwithURLslikethefollowing:photos/{photos}/comments/{comments}.

classPhotoCommentControllerextendsController{

/**

*Showthespecifiedphotocomment.

*

*@paramint$photoId

*@paramint$commentId

*@returnResponse

*/

publicfunctionshow($photoId,$commentId)

{

//

}

}

Ifitbecomesnecessarytoaddadditionalroutestoaresourcecontrollerbeyondthedefaultresourceroutes,youshoulddefinethoseroutesbeforeyourcalltoRoute::resource:

Route::get('photos/popular');

CustomizingResourceRoutes

HandlingNestedResourceControllers

AddingAdditionalRoutesToResourceControllers

Page 52: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Route::resource('photos','PhotoController');

TheLaravelservicecontainerisusedtoresolveallLaravelcontrollers.Asaresult,youareabletotype-hintanydependenciesyourcontrollermayneedinitsconstructor:

<?phpnamespaceApp\Http\Controllers;

useIlluminate\Routing\Controller;

useApp\Repositories\UserRepository;

classUserControllerextendsController{

/**

*Theuserrepositoryinstance.

*/

protected$users;

/**

*Createanewcontrollerinstance.

*

*@paramUserRepository$users

*@returnvoid

*/

publicfunction__construct(UserRepository$users)

{

$this->users=$users;

}

}

Ofcourse,youmayalsotype-hintanyLaravelcontract.Ifthecontainercanresolveit,youcantype-hintit.

Inadditiontoconstructorinjection,youmayalsotype-hintdependenciesonyourcontroller'smethods.Forexample,let'stype-hinttheRequestinstanceononeofourmethods:

<?phpnamespaceApp\Http\Controllers;

useIlluminate\Http\Request;

useIlluminate\Routing\Controller;

classUserControllerextendsController{

/**

*Storeanewuser.

*

*@paramRequest$request

*@returnResponse

*/

publicfunctionstore(Request$request)

{

$name=$request->input('name');

//

}

}

Ifyourcontrollermethodisalsoexpectinginputfromarouteparameter,simplylistyourrouteargumentsafteryourotherdependencies:

DependencyInjection&Controllers

ConstructorInjection

MethodInjection

Page 53: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

<?phpnamespaceApp\Http\Controllers;

useIlluminate\Http\Request;

useIlluminate\Routing\Controller;

classUserControllerextendsController{

/**

*Storeanewuser.

*

*@paramRequest$request

*@paramint$id

*@returnResponse

*/

publicfunctionupdate(Request$request,$id)

{

//

}

}

Note:Methodinjectionisfullycompatiblewithmodelbinding.Thecontainerwillintelligentlydeterminewhichargumentsaremodelboundandwhichargumentsshouldbeinjected.

Ifyourapplicationisexclusivelyusingcontrollerroutes,youmaytakeadvantageofLaravel'sroutecache.Usingtheroutecachewilldrasticallydecreasetheamountoftimeittaketoregisterallofyourapplication'sroutes.Insomecases,yourrouteregistrationmayevenbeupto100xfaster!Togeneratearoutecache,justexecutetheroute:cacheArtisancommand:

phpartisanroute:cache

That'sallthereistoit!Yourcachedroutesfilewillnowbeusedinsteadofyourapp/Http/routes.phpfile.Remember,ifyouaddanynewroutesyouwillneedtogenerateafreshroutecache.Becauseofthis,youmaywishtoonlyruntheroute:cachecommandduringyourproject'sdeployment.

Toremovethecachedroutesfilewithoutgeneratinganewcache,usetheroute:clearcommand:

phpartisanroute:clear

RouteCaching

Page 54: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ObtainingARequestInstanceRetrievingInputOldInputCookiesFilesOtherRequestInformation

TheRequestfacadewillgrantyouaccesstothecurrentrequestthatisboundinthecontainer.Forexample:

$name=Request::input('name');

Remember,ifyouareinanamespace,youwillhavetoimporttheRequestfacadeusingauseRequest;statementatthetopofyourclassfile.

ToobtainaninstanceofthecurrentHTTPrequestviadependencyinjection,youshouldtype-hinttheclassonyourcontrollerconstructorormethod.Thecurrentrequestinstancewillautomaticallybeinjectedbytheservicecontainer:

<?phpnamespaceApp\Http\Controllers;

useIlluminate\Http\Request;

useIlluminate\Routing\Controller;

classUserControllerextendsController{

/**

*Storeanewuser.

*

*@paramRequest$request

*@returnResponse

*/

publicfunctionstore(Request$request)

{

$name=$request->input('name');

//

}

}

Ifyourcontrollermethodisalsoexpectinginputfromarouteparameter,simplylistyourrouteargumentsafteryourotherdependencies:

<?phpnamespaceApp\Http\Controllers;

useIlluminate\Http\Request;

useIlluminate\Routing\Controller;

classUserControllerextendsController{

/**

*Storeanewuser.

*

HTTPRequests

ObtainingARequestInstance

ViaFacade

ViaDependencyInjection

Page 55: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

*@paramRequest$request

*@paramint$id

*@returnResponse

*/

publicfunctionupdate(Request$request,$id)

{

//

}

}

Usingafewsimplemethods,youmayaccessalluserinputfromyourIlluminate\Http\Requestinstance.YoudonotneedtoworryabouttheHTTPverbusedfortherequest,asinputisaccessedinthesamewayforallverbs.

$name=Request::input('name');

$name=Request::input('name','Sally');

if(Request::has('name'))

{

//

}

$input=Request::all();

$input=Request::only('username','password');

$input=Request::except('credit_card');

Whenworkingonformswith"array"inputs,youmayusedotnotationtoaccessthearrays:

$input=Request::input('products.0.name');

Laravelalsoallowsyoutokeepinputfromonerequestduringthenextrequest.Forexample,youmayneedtore-populateaformaftercheckingitforvalidationerrors.

RetrievingInput

RetrievingAnInputValue

RetrievingADefaultValueIfTheInputValueIsAbsent

DeterminingIfAnInputValueIsPresent

GettingAllInputForTheRequest

GettingOnlySomeOfTheRequestInput

OldInput

Page 56: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Theflashmethodwillflashthecurrentinputtothesessionsothatitisavailableduringtheuser'snextrequesttotheapplication:

Request::flash();

Request::flashOnly('username','email');

Request::flashExcept('password');

Sinceyouoftenwillwanttoflashinputinassociationwitharedirecttothepreviouspage,youmayeasilychaininputflashingontoaredirect.

returnredirect('form')->withInput();

returnredirect('form')->withInput(Request::except('password'));

Toretrieveflashedinputfromthepreviousrequest,usetheoldmethodontheRequestinstance.

$username=Request::old('username');

IfyouaredisplayingoldinputwithinaBladetemplate,itismoreconvenienttousetheoldhelper:

{{old('username')}}

AllcookiescreatedbytheLaravelframeworkareencryptedandsignedwithanauthenticationcode,meaningtheywillbeconsideredinvalidiftheyhavebeenchangedbytheclient.

$value=Request::cookie('name');

ThecookiehelperservesasasimplefactoryforgeneratingnewSymfony\Component\HttpFoundation\Cookieinstances.ThecookiesmaybeattachedtoaResponseinstanceusingthewithCookiemethod:

$response=newIlluminate\Http\Response('HelloWorld');

$response->withCookie(cookie('name','value',$minutes));

FlashingInputToTheSession

FlashingOnlySomeInputToTheSession

Flash&Redirect

RetrievingOldData

Cookies

RetrievingACookieValue

AttachingANewCookieToAResponse

Page 57: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

By"forever",wereallymeanfiveyears.

$response->withCookie(cookie()->forever('name','value'));

$file=Request::file('photo');

if(Request::hasFile('photo'))

{

//

}

TheobjectreturnedbythefilemethodisaninstanceoftheSymfony\Component\HttpFoundation\File\UploadedFileclass,whichextendsthePHPSplFileInfoclassandprovidesavarietyofmethodsforinteractingwiththefile.

if(Request::file('photo')->isValid())

{

//

}

Request::file('photo')->move($destinationPath);

Request::file('photo')->move($destinationPath,$fileName);

ThereareavarietyofothermethodsavailableonUploadedFileinstances.CheckouttheAPIdocumentationfortheclassformoreinformationregardingthesemethods.

TheRequestclassprovidesmanymethodsforexaminingtheHTTPrequestforyourapplicationandextendstheSymfony\Component\HttpFoundation\Requestclass.Herearesomeofthehighlights.

$uri=Request::path();

CreatingACookieThatLastsForever*

Files

RetrievingAnUploadedFile

DeterminingIfAFileWasUploaded

DeterminingIfAnUploadedFileIsValid

MovingAnUploadedFile

OtherFileMethods

OtherRequestInformation

RetrievingTheRequestURI

Page 58: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$method=Request::method();

if(Request::isMethod('post'))

{

//

}

if(Request::is('admin/*'))

{

//

}

$url=Request::url();

RetrievingTheRequestMethod

DeterminingIfTheRequestPathMatchesAPattern

GetTheCurrentRequestURL

Page 59: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

BasicResponsesRedirectsOtherResponsesResponseMacros

ThemostbasicresponsefromaLaravelrouteisastring:

Route::get('/',function()

{

return'HelloWorld';

});

However,formostroutesandcontrolleractions,youwillbereturningafullIlluminate\Http\Responseinstanceoraview.ReturningafullResponseinstanceallowsyoucustomizetheresponse'sHTTPstatuscodeandheaders.AResponseinstanceinheritsfromtheSymfony\Component\HttpFoundation\Responseclass,providingavarietyofmethodsforbuildingHTTPresponses:

useIlluminate\Http\Response;

return(newResponse($content,$status))

->header('Content-Type',$value);

Forconvenience,youmayalsousetheresponsehelper:

returnresponse($content,$status)

->header('Content-Type',$value);

Note:ForafulllistofavailableResponsemethods,checkoutitsAPIdocumentationandtheSymfonyAPIdocumentation.

IfyouneedaccesstotheResponseclassmethods,butwanttoreturnaviewastheresponsecontent,youmayusetheviewmethodforconvenience:

returnresponse()->view('hello')->header('Content-Type',$type);

returnresponse($content)->withCookie(cookie('name','value'));

HTTPResponses

BasicResponses

ReturningStringsFromRoutes

CreatingCustomResponses

SendingAViewInAResponse

AttachingCookiesToResponses

Page 60: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

KeepinmindthatmostResponsemethodsarechainable,allowingforthefluentbuildingofresponses:

returnresponse()->view('hello')->header('Content-Type',$type)

->withCookie(cookie('name','value'));

RedirectresponsesaretypicallyinstancesoftheIlluminate\Http\RedirectResponseclass,andcontaintheproperheadersneededtoredirecttheusertoanotherURL.

ThereareseveralwaystogenerateaRedirectResponseinstance.Thesimplestmethodistousetheredirecthelpermethod.Whentesting,itisnotcommontomockthecreationofaredirectresponse,sousingthehelpermethodisalmostalwaysacceptable:

returnredirect('user/login');

RedirectingtoanewURLandflashingdatatothesessionaretypicallydoneatthesametime.So,forconvenience,youmaycreateaRedirectResponseinstanceandflashdatatothesessioninasinglemethodchain:

returnredirect('user/login')->with('message','LoginFailed');

Youmaywishtoredirecttheusertotheirpreviouslocation,forexample,afteraformsubmission.Youcandosobyusingthebackmethod:

returnredirect()->back();

returnredirect()->back()->withInput();

Whenyoucalltheredirecthelperwithnoparameters,aninstanceofIlluminate\Routing\Redirectorisreturned,allowingyoutocallanymethodontheRedirectorinstance.Forexample,togenerateaRedirectResponsetoanamedroute,youmayusetheroutemethod:

returnredirect()->route('login');

Ifyourroutehasparameters,youmaypassthemasthesecondargumenttotheroutemethod.

//ForaroutewiththefollowingURI:profile/{id}

MethodChaining

Redirects

ReturningARedirect

ReturningARedirectWithFlashData

RedirectingToThePreviousURL

ReturningARedirectToANamedRoute

ReturningARedirectToANamedRouteWithParameters

Page 61: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

returnredirect()->route('profile',[1]);

Ifyouareredirectingtoaroutewithan"ID"parameterthatisbeingpopulatedfromanEloquentmodel,youmaysimplypassthemodelitself.TheIDwillbeextractedautomatically:

returnredirect()->route('profile',[$user]);

//ForaroutewiththefollowingURI:profile/{user}

returnredirect()->route('profile',['user'=>1]);

SimilarlytogeneratingRedirectResponseinstancestonamedroutes,youmayalsogenerateredirectstocontrolleractions:

returnredirect()->action('App\Http\Controllers\HomeController@index');

Note:YoudonotneedtospecifythefullnamespacetothecontrollerifyouhaveregisteredarootcontrollernamespaceviaURL::setRootControllerNamespace.

returnredirect()->action('App\Http\Controllers\UserController@profile',[1]);

returnredirect()->action('App\Http\Controllers\UserController@profile',['user'=>1]);

Theresponsehelpermaybeusedtoconvenientlygenerateothertypesofresponseinstances.Whentheresponsehelperiscalledwithoutarguments,animplementationoftheIlluminate\Contracts\Routing\ResponseFactorycontractisreturned.Thiscontractprovidesseveralhelpfulmethodsforgeneratingresponses.

ThejsonmethodwillautomaticallysettheContent-Typeheadertoapplication/json:

returnresponse()->json(['name'=>'Abigail','state'=>'CA']);

returnresponse()->json(['name'=>'Abigail','state'=>'CA'])

->setCallback($request->input('callback'));

ReturningARedirectToANamedRouteUsingNamedParameters

ReturningARedirectToAControllerAction

ReturningARedirectToAControllerActionWithParameters

ReturningARedirectToAControllerActionUsingNamedParameters

OtherResponses

CreatingAJSONResponse

CreatingAJSONPResponse

Page 62: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

returnresponse()->download($pathToFile);

returnresponse()->download($pathToFile,$name,$headers);

Note:SymfonyHttpFoundation,whichmanagesfiledownloads,requiresthefilebeingdownloadedtohaveanASCIIfilename.

Ifyouwouldliketodefineacustomresponsethatyoucanre-useinavarietyofyourroutesandcontrollers,youmayusethemacromethodonanimplementationofIlluminate\Contracts\Routing\ResponseFactory.

Forexample,fromaserviceprovider'sbootmethod:

<?phpnamespaceApp\Providers;

useResponse;

useIlluminate\Support\ServiceProvider;

classResponseMacroServiceProviderextendsServiceProvider{

/**

*Performpost-registrationbootingofservices.

*

*@returnvoid

*/

publicfunctionboot()

{

Response::macro('caps',function($value)

{

returnResponse::make(strtoupper($value));

});

}

}

Themacrofunctionacceptsanameasitsfirstargument,andaClosureasitssecond.Themacro'sClosurewillbeexecutedwhencallingthemacronamefromaResponseFactoryimplementationortheresponsehelper:

returnresponse()->caps('foo');

CreatingAFileDownloadResponse

ResponseMacros

Page 63: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

BasicUsageViewComposers

ViewscontaintheHTMLservedbyyourapplication,andserveasaconvenientmethodofseparatingyourcontrolleranddomainlogicfromyourpresentationlogic.Viewsarestoredintheresources/viewsdirectory.

Asimpleviewlookslikethis:

<!--Viewstoredinresources/views/greeting.php-->

<html>

<body>

<h1>Hello,<?phpecho$name;?></h1>

</body>

</html>

Theviewmaybereturnedtothebrowserlikeso:

Route::get('/',function()

{

returnview('greeting',['name'=>'James']);

});

Asyoucansee,thefirstargumentpassedtotheviewhelpercorrespondstothenameoftheviewfileintheresources/viewsdirectory.Thesecondargumentpassedtohelperisanarrayofdatathatshouldbemadeavailabletotheview.

Ofcourse,viewsmayalsobenestedwithinsub-directoriesoftheresources/viewsdirectory.Forexample,ifyourviewisstoredatresources/views/admin/profile.php,itshouldbereturnedlikeso:

returnview('admin.profile',$data);

//Usingconventionalapproach

$view=view('greeting')->with('name','Victoria');

//UsingMagicMethods

$view=view('greeting')->withName('Victoria');

Intheexampleabove,thevariable$nameismadeaccessibletotheviewandcontainsVictoria.

Ifyouwish,youmaypassanarrayofdataasthesecondparametertotheviewhelper:

$view=view('greetings',$data);

Views

BasicUsage

PassingDataToViews

SharingDataWithAllViews

Page 64: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Occasionally,youmayneedtoshareapieceofdatawithallviewsthatarerenderedbyyourapplication.Youhaveseveraloptions:theviewhelper,theIlluminate\Contracts\View\Factorycontract,orawildcardviewcomposer.

Forexample,usingtheviewhelper:

view()->share('data',[1,2,3]);

YoumayalsousetheViewfacade:

View::share('data',[1,2,3]);

Typically,youwouldplacecallstothesharemethodwithinaserviceprovider'sbootmethod.YouarefreetoaddthemtotheAppServiceProviderorgenerateaseparateserviceprovidertohousethem.

Note:Whentheviewhelperiscalledwithoutarguments,itreturnsanimplementationoftheIlluminate\Contracts\View\Factorycontract.

Ifyouneedtodetermineifaviewexists,youmayusetheexistsmethod:

if(view()->exists('emails.customer'))

{

//

}

Ifyouwish,youmaygenerateaviewfromafully-qualifiedfilepath:

returnview()->file($pathToFile,$data);

Viewcomposersarecallbacksorclassmethodsthatarecalledwhenaviewisrendered.Ifyouhavedatathatyouwanttobeboundtoavieweachtimethatviewisrendered,aviewcomposerorganizesthatlogicintoasinglelocation.

Let'sorganizeourviewcomposerswithinaserviceprovider.We'llusetheViewfacadetoaccesstheunderlyingIlluminate\Contracts\View\Factorycontractimplementation:

<?phpnamespaceApp\Providers;

useView;

useIlluminate\Support\ServiceProvider;

classComposerServiceProviderextendsServiceProvider{

/**

*Registerbindingsinthecontainer.

*

*@returnvoid

*/

publicfunctionboot()

{

DeterminingIfAViewExists

ReturningAViewFromAFilePath

ViewComposers

DefiningAViewComposer

Page 65: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

//Usingclassbasedcomposers...

View::composer('profile','App\Http\ViewComposers\ProfileComposer');

//UsingClosurebasedcomposers...

View::composer('dashboard',function()

{

});

}

}

Note:Laraveldoesnotincludeadefaultdirectoryforviewcomposers.Youarefreetoorganizethemhoweveryouwish.Forexample,youcouldcreateanApp\Http\Composersdirectory.

Nowthatwehaveregisteredthecomposer,theProfileComposer@composemethodwillbeexecutedeachtimetheprofileviewisbeingrendered.So,let'sdefinethecomposerclass:

<?phpnamespaceApp\Http\Composers;

useIlluminate\Contracts\View\View;

useIlluminate\Users\RepositoryasUserRepository;

classProfileComposer{

/**

*Theuserrepositoryimplementation.

*

*@varUserRepository

*/

protected$users;

/**

*Createanewprofilecomposer.

*

*@paramUserRepository$users

*@returnvoid

*/

publicfunction__construct(UserRepository$users)

{

//Dependenciesautomaticallyresolvedbyservicecontainer...

$this->users=$users;

}

/**

*Binddatatotheview.

*

*@paramView$view

*@returnvoid

*/

publicfunctioncompose(View$view)

{

$view->with('count',$this->users->count());

}

}

Justbeforetheviewisrendered,thecomposer'scomposemethodiscalledwiththeIlluminate\Contracts\View\Viewinstance.Youmayusethewithmethodtobinddatatotheview.

Note:Allviewcomposersareresolvedviatheservicecontainer,soyoumaytype-hintanydependenciesyouneedwithinacomposer'sconstructor.

Thecomposermethodacceptsthe*characterasawildcard,soyoumayattachacomposertoallviewslikeso:

View::composer('*',function()

{

//

WildcardViewComposers

Page 66: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

});

Youmayalsoattachaviewcomposertomultipleviewsatonce:

View::composer(['profile','dashboard'],'App\Http\ViewComposers\MyViewComposer');

Youmayusethecomposersmethodtoregisteragroupofcomposersatthesametime:

View::composers([

'App\Http\ViewComposers\AdminComposer'=>['admin.index','admin.profile'],

'App\Http\ViewComposers\UserComposer'=>'user',

'App\Http\ViewComposers\ProductComposer'=>'product'

]);

Viewcreatorsworkalmostexactlylikeviewcomposers;however,theyarefiredimmediatelywhentheviewisinstantiated.Toregisteraviewcreator,usethecreatormethod:

View::creator('profile','App\Http\ViewCreators\ProfileCreator');

AttachingAComposerToMultipleViews

DefiningMultipleComposers

ViewCreators

Page 67: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ServiceProvidersIntroductionBasicProviderExampleRegisteringProvidersDeferredProviders

ServiceContainerIntroductionBasicUsageBindingInterfacesToImplementationsContextualBindingTaggingPracticalApplicationsContainerEvents

ContractsIntroductionWhyContracts?ContractReferenceHowToUseContracts

FacadesIntroductionExplanationPracticalUsageCreatingFacadesMockingFacadesFacadeClassReference

RequestLifecycleIntroductionLifecycleOverviewFocusOnServiceProviders

ApplicationStructureIntroductionTheRootDirectoryTheAppDirectoryNamespacingYourApplication

ArchitectureFoundations

Page 68: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionBasicProviderExampleRegisteringProvidersDeferredProviders

ServiceprovidersarethecentralplaceofallLaravelapplicationbootstrapping.Yourownapplication,aswellasallofLaravel'scoreservicesarebootstrappedviaserviceproviders.

But,whatdowemeanby"bootstrapped"?Ingeneral,wemeanregisteringthings,includingregisteringservicecontainerbindings,eventlisteners,filters,andevenroutes.Serviceprovidersarethecentralplacetoconfigureyourapplication.

Ifyouopentheconfig/app.phpfileincludedwithLaravel,youwillseeaprovidersarray.Thesearealloftheserviceproviderclassesthatwillbeloadedforyourapplication.Ofcourse,manyofthemare"deferred"providers,meaningtheywillnotbeloadedoneveryrequest,butonlywhentheservicestheyprovideareactuallyneeded.

InthisoverviewyouwilllearnhowtowriteyourownserviceprovidersandregisterthemwithyourLaravelapplication.

AllserviceprovidersextendtheIlluminate\Support\ServiceProviderclass.Thisabstractclassrequiresthatyoudefineatleastonemethodonyourprovider:register.Withintheregistermethod,youshouldonlybindthingsintotheservicecontainer.Youshouldneverattempttoregisteranyeventlisteners,routes,oranyotherpieceoffunctionalitywithintheregistermethod.

TheArtisanCLIcaneasilygenerateanewproviderviathemake:providercommand:

phpartisanmake:providerRiakServiceProvider

Now,let'stakealookatabasicserviceprovider:

<?phpnamespaceApp\Providers;

useRiak\Connection;

useIlluminate\Support\ServiceProvider;

classRiakServiceProviderextendsServiceProvider{

/**

*Registerbindingsinthecontainer.

*

*@returnvoid

*/

publicfunctionregister()

{

$this->app->singleton('Riak\Contracts\Connection',function($app)

{

returnnewConnection($app['config']['riak']);

});

}

}

ServiceProviders

Introduction

BasicProviderExample

TheRegisterMethod

Page 69: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Thisserviceprovideronlydefinesaregistermethod,andusesthatmethodtodefineanimplementationofRiak\Contracts\Connectionintheservicecontainer.Ifyoudon'tunderstandhowtheservicecontainerworks,don'tworry,we'llcoverthatsoon.

ThisclassisnamespacedunderApp\ProviderssincethatisthedefaultlocationforserviceprovidersinLaravel.However,youarefreetochangethisasyouwish.YourserviceprovidersmaybeplacedanywherethatComposercanautoloadthem.

So,whatifweneedtoregisteraneventlistenerwithinourserviceprovider?Thisshouldbedonewithinthebootmethod.Thismethodiscalledafterallotherserviceprovidershavebeenregistered,meaningyouhaveaccesstoallotherservicesthathavebeenregisteredbytheframework.

<?phpnamespaceApp\Providers;

useEvent;

useIlluminate\Support\ServiceProvider;

classEventServiceProviderextendsServiceProvider{

/**

*Performpost-registrationbootingofservices.

*

*@returnvoid

*/

publicfunctionboot()

{

Event::listen('SomeEvent','SomeEventHandler');

}

/**

*Registerbindingsinthecontainer.

*

*@returnvoid

*/

publicfunctionregister()

{

//

}

}

Weareabletotype-hintdependenciesforourbootmethod.Theservicecontainerwillautomaticallyinjectanydependenciesyouneed:

useIlluminate\Contracts\Events\Dispatcher;

publicfunctionboot(Dispatcher$events)

{

$events->listen('SomeEvent','SomeEventHandler');

}

Allserviceprovidersareregisteredintheconfig/app.phpconfigurationfile.Thisfilecontainsaprovidersarraywhereyoucanlistthenamesofyourserviceproviders.Bydefault,asetofLaravelcoreserviceprovidersarelistedinthisarray.TheseprovidersbootstrapthecoreLaravelcomponents,suchasthemailer,queue,cache,andothers.

Toregisteryourprovider,simplyaddittothearray:

'providers'=>[

//OtherServiceProviders

TheBootMethod

RegisteringProviders

Page 70: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

'App\Providers\AppServiceProvider',

],

Ifyourproviderisonlyregisteringbindingsintheservicecontainer,youmaychoosetodeferitsregistrationuntiloneoftheregisteredbindingsisactuallyneeded.Deferringtheloadingofsuchaproviderwillimprovetheperformanceofyourapplication,sinceitisnotloadedfromthefilesystemoneveryrequest.

Todefertheloadingofaprovider,setthedeferpropertytotrueanddefineaprovidesmethod.Theprovidesmethodreturnstheservicecontainerbindingsthattheproviderregisters:

<?phpnamespaceApp\Providers;

useRiak\Connection;

useIlluminate\Support\ServiceProvider;

classRiakServiceProviderextendsServiceProvider{

/**

*Indicatesifloadingoftheproviderisdeferred.

*

*@varbool

*/

protected$defer=true;

/**

*Registertheserviceprovider.

*

*@returnvoid

*/

publicfunctionregister()

{

$this->app->singleton('Riak\Contracts\Connection',function($app)

{

returnnewConnection($app['config']['riak']);

});

}

/**

*Gettheservicesprovidedbytheprovider.

*

*@returnarray

*/

publicfunctionprovides()

{

return['Riak\Contracts\Connection'];

}

}

Laravelcompilesandstoresalistofalloftheservicessuppliedbydeferredserviceproviders,alongwiththenameofitsserviceproviderclass.Then,onlywhenyouattempttoresolveoneoftheseservicesdoesLaravelloadtheserviceprovider.

DeferredProviders

Page 71: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionBasicUsageBindingInterfacesToImplementationsContextualBindingTaggingPracticalApplicationsContainerEvents

TheLaravelservicecontainerisapowerfultoolformanagingclassdependencies.Dependencyinjectionisafancywordthatessentiallymeansthis:classdependenciesare"injected"intotheclassviatheconstructoror,insomecases,"setter"methods.

Let'slookatasimpleexample:

<?phpnamespaceApp\Handlers\Commands;

useApp\User;

useApp\Commands\PurchasePodcast;

useIlluminate\Contracts\Mail\Mailer;

classPurchasePodcastHandler{

/**

*Themailerimplementation.

*/

protected$mailer;

/**

*Createanewinstance.

*

*@paramMailer$mailer

*@returnvoid

*/

publicfunction__construct(Mailer$mailer)

{

$this->mailer=$mailer;

}

/**

*Purchaseapodcast.

*

*@paramPurchasePodcastCommand$command

*@returnvoid

*/

publicfunctionhandle(PurchasePodcastCommand$command)

{

//

}

}

Inthisexample,thePurchasePodcastcommandhandlerneedstosende-mailswhenapodcastispurchased.So,wewillinjectaservicethatisabletosende-mails.Sincetheserviceisinjected,weareabletoeasilyswapitoutwithanotherimplementation.Wearealsoabletoeasily"mock",orcreateadummyimplementationofthemailerwhentestingourapplication.

AdeepunderstandingoftheLaravelservicecontainerisessentialtobuildingapowerful,largeapplication,aswellasforcontributingtotheLaravelcoreitself.

ServiceContainer

Introduction

Page 72: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Almostallofyourservicecontainerbindingswillberegisteredwithinserviceproviders,soalloftheseexampleswilldemonstrateusingthecontainerinthatcontext.However,ifyouneedaninstanceofthecontainerelsewhereinyourapplication,suchasafactory,youmaytype-hinttheIlluminate\Contracts\Container\Containercontractandaninstanceofthecontainerwillbeinjectedforyou.Alternatively,youmayusetheAppfacadetoaccessthecontainer.

Withinaserviceprovider,youalwayshaveaccesstothecontainerviathe$this->appinstancevariable.

Thereareseveralwaystheservicecontainercanregisterdependencies,includingClosurecallbacksandbindinginterfacestoimplementations.First,we'llexploreClosurecallbacks.AClosureresolverisregisteredinthecontainerwithakey(typicallytheclassname)andaClosurethatreturnssomevalue:

$this->app->bind('FooBar',function($app)

{

returnnewFooBar($app['SomethingElse']);

});

Sometimes,youmaywishtobindsomethingintothecontainerthatshouldonlyberesolvedonce,andthesameinstanceshouldbereturnedonsubsequentcallsintothecontainer:

$this->app->singleton('FooBar',function($app)

{

returnnewFooBar($app['SomethingElse']);

});

Youmayalsobindanexistingobjectinstanceintothecontainerusingtheinstancemethod.Thegiveninstancewillalwaysbereturnedonsubsequentcallsintothecontainer:

$fooBar=newFooBar(newSomethingElse);

$this->app->instance('FooBar',$fooBar);

Thereareseveralwaystoresolvesomethingoutofthecontainer.First,youmayusethemakemethod:

$fooBar=$this->app->make('FooBar');

Secondly,youmayuse"arrayaccess"onthecontainer,sinceitimplementsPHP'sArrayAccessinterface:

$fooBar=$this->app['FooBar'];

Lastly,butmostimportantly,youmaysimply"type-hint"thedependencyintheconstructorofaclassthatisresolvedbythe

BasicUsage

Binding

RegisteringABasicResolver

RegisteringASingleton

BindingAnExistingInstanceIntoTheContainer

Resolving

Page 73: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

container,includingcontrollers,eventlisteners,queuejobs,filters,andmore.Thecontainerwillautomaticallyinjectthedependencies:

<?phpnamespaceApp\Http\Controllers;

useIlluminate\Routing\Controller;

useApp\Users\RepositoryasUserRepository;

classUserControllerextendsController{

/**

*Theuserrepositoryinstance.

*/

protected$users;

/**

*Createanewcontrollerinstance.

*

*@paramUserRepository$users

*@returnvoid

*/

publicfunction__construct(UserRepository$users)

{

$this->users=$users;

}

/**

*ShowtheuserwiththegivenID.

*

*@paramint$id

*@returnResponse

*/

publicfunctionshow($id)

{

//

}

}

Averypowerfulfeaturesoftheservicecontainerisitsabilitytobindaninterfacetoagivenimplementation.Forexample,perhapsourapplicationintegrateswiththePusherwebserviceforsendingandreceivingreal-timeevents.IfweareusingPusher'sPHPSDK,wecouldinjectaninstanceofthePusherclientintoaclass:

<?phpnamespaceApp\Handlers\Commands;

useApp\Commands\CreateOrder;

usePusher\ClientasPusherClient;

classCreateOrderHandler{

/**

*ThePusherSDKclientinstance.

*/

protected$pusher;

/**

*Createaneworderhandlerinstance.

*

*@paramPusherClient$pusher

*@returnvoid

*/

publicfunction__construct(PusherClient$pusher)

{

$this->pusher=$pusher;

}

/**

*Executethegivencommand.

BindingInterfacesToImplementations

InjectingConcreteDependencies

Page 74: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

*

*@paramCreateOrder$command

*@returnvoid

*/

publicfunctionexecute(CreateOrder$command)

{

//

}

}

Inthisexample,itisgoodthatweareinjectingtheclassdependencies;however,wearetightlycoupledtothePusherSDK.IfthePusherSDKmethodschangeorwedecidetoswitchtoaneweventserviceentirely,wewillneedtochangeourCreateOrderHandlercode.

Inorderto"insulate"theCreateOrderHandleragainstchangestoeventpushing,wecoulddefineanEventPusherinterfaceandaPusherEventPusherimplementation:

<?phpnamespaceApp\Contracts;

interfaceEventPusher{

/**

*Pushaneweventtoallclients.

*

*@paramstring$event

*@paramarray$data

*@returnvoid

*/

publicfunctionpush($event,array$data);

}

OncewehavecodedourPusherEventPusherimplementationofthisinterface,wecanregisteritwiththeservicecontainerlikeso:

$this->app->bind('App\Contracts\EventPusher','App\Services\PusherEventPusher');

ThistellsthecontainerthatitshouldinjectthePusherEventPusherwhenaclassneedsanimplementationofEventPusher.Nowwecantype-hinttheEventPusherinterfaceinourconstructor:

/**

*Createaneworderhandlerinstance.

*

*@paramEventPusher$pusher

*@returnvoid

*/

publicfunction__construct(EventPusher$pusher)

{

$this->pusher=$pusher;

}

Sometimesyoumayhavetwoclassesthatutilizethesameinterface,butyouwishtoinjectdifferentimplementationsintoeachclass.Forexample,whenoursystemreceivesanewOrder,wemaywanttosendaneventviaPubNubratherthanPusher.Laravelprovidesasimple,fluentinterfacefordefininingthisbehavior:

$this->app->when('App\Handlers\Commands\CreateOrderHandler')

ProgramToAnInterface

ContextualBinding

Page 75: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

->needs('App\Contracts\EventPusher')

->give('App\Services\PubNubEventPusher');

Occasionally,youmayneedtoresolveallofacertain"category"ofbinding.Forexample,perhapsyouarebuildingareportaggregatorthatreceivesanarrayofmanydifferentReportinterfaceimplementations.AfterregisteringtheReportimplementations,youcanassignthematagusingthetagmethod:

$this->app->bind('SpeedReport',function()

{

//

});

$this->app->bind('MemoryReport',function()

{

//

});

$this->app->tag(['SpeedReport','MemoryReport'],'reports');

Oncetheserviceshavebeentagged,youmayeasilyresolvethemallviathetaggedmethod:

$this->app->bind('ReportAggregator',function($app)

{

returnnewReportAggregator($app->tagged('reports'));

});

Laravelprovidesseveralopportunitiestousetheservicecontainertoincreasetheflexibilityandtestabilityofyourapplication.Oneprimaryexampleiswhenresolvingcontrollers.Allcontrollersareresolvedthroughtheservicecontainer,meaningyoucantype-hintdependenciesinacontrollerconstructor,andtheywillautomaticallybeinjected.

<?phpnamespaceApp\Http\Controllers;

useIlluminate\Routing\Controller;

useApp\Repositories\OrderRepository;

classOrdersControllerextendsController{

/**

*Theorderrepositoryinstance.

*/

protected$orders;

/**

*Createacontrollerinstance.

*

*@paramOrderRepository$orders

*@returnvoid

*/

publicfunction__construct(OrderRepository$orders)

{

$this->orders=$orders;

}

/**

*Showalloftheorders.

*

*@returnResponse

*/

publicfunctionindex()

{

$all=$this->orders->all();

Tagging

PracticalApplications

Page 76: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

returnview('orders',['all'=>$all]);

}

}

Inthisexample,theOrderRepositoryclasswillautomaticallybeinjectedintothecontroller.Thismeansthata"mock"OrderRepositorymaybeboundintothecontainerwhenunittesting,allowingforpainlessstubbingofdatabaselayerinteraction.

Ofcourse,asmentionedabove,controllersarenottheonlyclassesLaravelresolvesviatheservicecontainer.Youmayalsotype-hintdependenciesonrouteClosures,filters,queuejobs,eventlisteners,andmore.Forexamplesofusingtheservicecontainerinthesecontexts,pleaserefertotheirdocumentation.

Thecontainerfiresaneventeachtimeitresolvesanobject.Youmaylistentothiseventusingtheresolvingmethod:

$this->app->resolving(function($object,$app)

{

//Calledwhencontainerresolvesobjectofanytype...

});

$this->app->resolving(function(FooBar$fooBar,$app)

{

//Calledwhencontainerresolvesobjectsoftype"FooBar"...

});

Theobjectbeingresolvedwillbepassedtothecallback.

OtherExamplesOfContainerUsage

ContainerEvents

RegisteringAResolvingListener

Page 77: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionWhyContracts?ContractReferenceHowToUseContracts

Laravel'sContractsareasetofinterfacesthatdefinethecoreservicesprovidedbytheframework.Forexample,aQueuecontractdefinesthemethodsneededforqueueingjobs,whiletheMailercontractdefinesthemethodsneededforsendinge-mail.

Eachcontracthasacorrespondingimplementationprovidedbytheframework.Forexample,LaravelprovidesaQueueimplementationwithavarietyofdrivers,andaMailerimplementationthatispoweredbySwiftMailer.

AlloftheLaravelcontractsliveintheirownGitHubrepository.Thisprovidesaquickreferencepointforallavailablecontracts,aswellasasingle,decoupledpackagethatmaybeutilizedbyotherpackagedevelopers.

Youmayhaveseveralquestionsregardingcontracts.Whyuseinterfacesatall?Isn'tusinginterfacesmorecomplicated?

Let'sdistillthereasonsforusinginterfacestothefollowingheadings:loosecouplingandsimplicity.

First,let'sreviewsomecodethatistightlycoupledtoacacheimplementation.Considerthefollowing:

<?phpnamespaceApp\Orders;

classRepository{

/**

*Thecache.

*/

protected$cache;

/**

*Createanewrepositoryinstance.

*

*@param\Package\Cache\Memcached$cache

*@returnvoid

*/

publicfunction__construct(\SomePackage\Cache\Memcached$cache)

{

$this->cache=$cache;

}

/**

*RetrieveanOrderbyID.

*

*@paramint$id

*@returnOrder

*/

publicfunctionfind($id)

{

if($this->cache->has($id))

{

//

}

}

Contracts

Introduction

WhyContracts?

LooseCoupling

Page 78: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

}

Inthisclass,thecodeistightlycoupledtoagivencacheimplementation.ItistightlycoupledbecausewearedependingonaconcreteCacheclassfromapackagevendor.IftheAPIofthatpackagechangesourcodemustchangeaswell.

Likewise,ifwewanttoreplaceourunderlyingcachetechnology(Memcached)withanothertechnology(Redis),weagainwillhavetomodifyourrepository.Ourrepositoryshouldnothavesomuchknowledgeregardingwhoisprovidingthemdataorhowtheyareprovidingit.

Insteadofthisapproach,wecanimproveourcodebydependingonasimple,vendoragnosticinterface:

<?phpnamespaceApp\Orders;

useIlluminate\Contracts\Cache\RepositoryasCache;

classRepository{

/**

*Createanewrepositoryinstance.

*

*@paramCache$cache

*@returnvoid

*/

publicfunction__construct(Cache$cache)

{

$this->cache=$cache;

}

}

Nowthecodeisnotcoupledtoanyspecificvendor,orevenLaravel.Sincethecontractspackagecontainsnoimplementationandnodependencies,youmayeasilywriteanalternativeimplementationofanygivencontract,allowingyoutoreplaceyourcacheimplementationwithoutmodifyinganyofyourcacheconsumingcode.

WhenallofLaravel'sservicesareneatlydefinedwithinsimpleinterfaces,itisveryeasytodeterminethefunctionalityofferedbyagivenservice.Thecontractsserveassuccinctdocumentationtotheframework'sfeatures.

Inaddition,whenyoudependonsimpleinterfaces,yourcodeiseasiertounderstandandmaintain.Ratherthantrackingdownwhichmethodsareavailabletoyouwithinalarge,complicatedclass,youcanrefertoasimple,cleaninterface.

ThisisareferencetomostLaravelContracts,aswellastheirLaravel"facade"counterparts:

Contract Laravel4.xFacade

Illuminate\Contracts\Auth\Guard Auth

Illuminate\Contracts\Auth\PasswordBroker Password

Illuminate\Contracts\Cache\Repository Cache

Illuminate\Contracts\Cache\Factory Cache::driver()

Illuminate\Contracts\Config\Repository Config

Illuminate\Contracts\Container\Container App

Illuminate\Contracts\Cookie\Factory Cookie

Illuminate\Contracts\Cookie\QueueingFactory Cookie::queue()

Illuminate\Contracts\Encryption\Encrypter Crypt

Simplicity

ContractReference

Page 79: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Illuminate\Contracts\Events\Dispatcher Event

Illuminate\Contracts\Filesystem\Cloud

Illuminate\Contracts\Filesystem\Factory File

Illuminate\Contracts\Filesystem\Filesystem File

Illuminate\Contracts\Foundation\Application App

Illuminate\Contracts\Hashing\Hasher Hash

Illuminate\Contracts\Logging\Log Log

Illuminate\Contracts\Mail\MailQueue Mail::queue()

Illuminate\Contracts\Mail\Mailer Mail

Illuminate\Contracts\Queue\Factory Queue::driver()

Illuminate\Contracts\Queue\Queue Queue

Illuminate\Contracts\Redis\Database Redis

Illuminate\Contracts\Routing\Registrar Route

Illuminate\Contracts\Routing\ResponseFactory Response

Illuminate\Contracts\Routing\UrlGenerator URL

Illuminate\Contracts\Support\Arrayable

Illuminate\Contracts\Support\Jsonable

Illuminate\Contracts\Support\Renderable

Illuminate\Contracts\Validation\Factory Validator::make()

Illuminate\Contracts\Validation\Validator

Illuminate\Contracts\View\Factory View::make()

Illuminate\Contracts\View\View

So,howdoyougetanimplementationofacontract?It'sactuallyquitesimple.ManytypesofclassesinLaravelareresolvedthroughtheservicecontainer,includingcontrollers,eventlisteners,filters,queuejobs,andevenrouteClosures.So,togetanimplementationofacontract,youcanjust"type-hint"theinterfaceintheconstructoroftheclassbeingresolved.Forexample,takealookatthiseventhandler:

<?phpnamespaceApp\Handlers\Events;

useApp\User;

useApp\Events\NewUserRegistered;

useIlluminate\Contracts\Redis\Database;

classCacheUserInformation{

/**

*TheRedisdatabaseimplementation.

*/

protected$redis;

/**

*Createaneweventhandlerinstance.

*

*@paramDatabase$redis

*@returnvoid

*/

publicfunction__construct(Database$redis)

{

$this->redis=$redis;

HowToUseContracts

Page 80: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

}

/**

*Handletheevent.

*

*@paramNewUserRegistered$event

*@returnvoid

*/

publicfunctionhandle(NewUserRegistered$event)

{

//

}

}

Whentheeventlistenerisresolved,theservicecontainerwillreadthetype-hintsontheconstructoroftheclass,andinjecttheappropriatevalue.Tolearnmoreaboutregisteringthingsintheservicecontainer,checkoutthedocumentation.

Page 81: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionExplanationPracticalUsageCreatingFacadesMockingFacadesFacadeClassReference

Facadesprovidea"static"interfacetoclassesthatareavailableintheapplication'sIoCcontainer.Laravelshipswithmanyfacades,andyouhaveprobablybeenusingthemwithoutevenknowingit!Laravel"facades"serveas"staticproxies"tounderlyingclassesintheIoCcontainer,providingthebenefitofaterse,expressivesyntaxwhilemaintainingmoretestabilityandflexibilitythantraditionalstaticmethods.

Occasionally,Youmaywishtocreateyourownfacadesforyourapplicationsandpackages,solet'sexploretheconcept,developmentandusageoftheseclasses.

Note:Beforediggingintofacades,itisstronglyrecommendedthatyoubecomeveryfamiliarwiththeLaravelIoCcontainer.

InthecontextofaLaravelapplication,afacadeisaclassthatprovidesaccesstoanobjectfromthecontainer.ThemachinerythatmakesthisworkisintheFacadeclass.Laravel'sfacades,andanycustomfacadesyoucreate,willextendthebaseFacadeclass.

Yourfacadeclassonlyneedstoimplementasinglemethod:getFacadeAccessor.It'sthegetFacadeAccessormethod'sjobtodefinewhattoresolvefromthecontainer.TheFacadebaseclassmakesuseofthe__callStatic()magic-methodtodefercallsfromyourfacadetotheresolvedobject.

So,whenyoumakeafacadecalllikeCache::get,LaravelresolvestheCachemanagerclassoutoftheIoCcontainerandcallsthegetmethodontheclass.Intechnicalterms,LaravelFacadesareaconvenientsyntaxforusingtheLaravelIoCcontainerasaservicelocator.

Intheexamplebelow,acallismadetotheLaravelcachesystem.Byglancingatthiscode,onemightassumethatthestaticmethodgetisbeingcalledontheCacheclass.

$value=Cache::get('key');

However,ifwelookatthatIlluminate\Support\Facades\Cacheclass,you'llseethatthereisnostaticmethodget:

classCacheextendsFacade{

/**

*Gettheregisterednameofthecomponent.

*

*@returnstring

*/

protectedstaticfunctiongetFacadeAccessor(){return'cache';}

Facades

Introduction

Explanation

PracticalUsage

Page 82: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

}

TheCacheclassextendsthebaseFacadeclassanddefinesamethodgetFacadeAccessor().Remember,thismethod'sjobistoreturnthenameofanIoCbinding.

WhenauserreferencesanystaticmethodontheCachefacade,LaravelresolvesthecachebindingfromtheIoCcontainerandrunstherequestedmethod(inthiscase,get)againstthatobject.

So,ourCache::getcallcouldbere-writtenlikeso:

$value=$app->make('cache')->get('key');

Remember,ifyouareusingafacadewhenacontrollerthatisnamespaced,youwillneedtoimportthefacadeclassintothenamespace.Allfacadesliveintheglobalnamespace:

<?phpnamespaceApp\Http\Controllers;

useCache;

classPhotosControllerextendsController{

/**

*Getalloftheapplicationphotos.

*

*@returnResponse

*/

publicfunctionindex()

{

$photos=Cache::get('photos');

//

}

}

Creatingafacadeforyourownapplicationorpackageissimple.Youonlyneed3things:

AnIoCbinding.Afacadeclass.Afacadealiasconfiguration.

Let'slookatanexample.Here,wehaveaclassdefinedasPaymentGateway\Payment.

namespacePaymentGateway;

classPayment{

publicfunctionprocess()

{

//

}

}

WeneedtobeabletoresolvethisclassfromtheIoCcontainer.So,let'saddabindingtoaserviceprovider:

ImportingFacades

CreatingFacades

Page 83: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

App::bind('payment',function()

{

returnnew\PaymentGateway\Payment;

});

AgreatplacetoregisterthisbindingwouldbetocreateanewserviceprovidernamedPaymentServiceProvider,andaddthisbindingtotheregistermethod.YoucanthenconfigureLaraveltoloadyourserviceproviderfromtheconfig/app.phpconfigurationfile.

Next,wecancreateourownfacadeclass:

useIlluminate\Support\Facades\Facade;

classPaymentextendsFacade{

protectedstaticfunctiongetFacadeAccessor(){return'payment';}

}

Finally,ifwewish,wecanaddanaliasforourfacadetothealiasesarrayintheconfig/app.phpconfigurationfile.Now,wecancalltheprocessmethodonaninstanceofthePaymentclass.

Payment::process();

ClassesinthealiasesarrayarenotavailableinsomeinstancesbecausePHPwillnotattempttoautoloadundefinedtype-hintedclasses.If\ServiceWrapper\ApiTimeoutExceptionisaliasedtoApiTimeoutException,acatch(ApiTimeoutException$e)outsideofthenamespace\ServiceWrapperwillnevercatchtheexception,evenifoneisthrown.Asimilarproblemisfoundinclasseswhichhavetypehintstoaliasedclasses.Theonlyworkaroundistoforegoaliasingandusetheclassesyouwishtotypehintatthetopofeachfilewhichrequiresthem.

Unittestingisanimportantaspectofwhyfacadesworkthewaythattheydo.Infact,testabilityistheprimaryreasonforfacadestoevenexist.Formoreinformation,checkoutthemockingfacadessectionofthedocumentation.

Belowyouwillfindeveryfacadeanditsunderlyingclass.ThisisausefultoolforquicklydiggingintotheAPIdocumentationforagivenfacaderoot.TheIoCbindingkeyisalsoincludedwhereapplicable.

Facade Class IoCBinding

App Illuminate\Foundation\Application app

Artisan Illuminate\Console\Application artisan

Auth Illuminate\Auth\AuthManager auth

Auth(Instance) Illuminate\Auth\Guard

Blade Illuminate\View\Compilers\BladeCompiler blade.compiler

Cache Illuminate\Cache\Repository cache

Config Illuminate\Config\Repository config

Cookie Illuminate\Cookie\CookieJar cookie

ANoteOnAuto-LoadingAliases

MockingFacades

FacadeClassReference

Page 84: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Crypt Illuminate\Encryption\Encrypter encrypter

DB Illuminate\Database\DatabaseManager db

DB(Instance) Illuminate\Database\Connection

Event Illuminate\Events\Dispatcher events

File Illuminate\Filesystem\Filesystem files

Form Illuminate\Html\FormBuilder form

Hash Illuminate\Hashing\HasherInterface hash

HTML Illuminate\Html\HtmlBuilder html

Input Illuminate\Http\Request request

Lang Illuminate\Translation\Translator translator

Log Illuminate\Log\Writer log

Mail Illuminate\Mail\Mailer mailer

Paginator Illuminate\Pagination\Factory paginator

Paginator(Instance) Illuminate\Pagination\Paginator

Password Illuminate\Auth\Passwords\PasswordBroker auth.reminder

Queue Illuminate\Queue\QueueManager queue

Queue(Instance) Illuminate\Queue\QueueInterface

Queue(BaseClass) Illuminate\Queue\Queue

Redirect Illuminate\Routing\Redirector redirect

Redis Illuminate\Redis\Database redis

Request Illuminate\Http\Request request

Response Illuminate\Support\Facades\Response

Route Illuminate\Routing\Router router

Schema Illuminate\Database\Schema\Blueprint

Session Illuminate\Session\SessionManager session

Session(Instance) Illuminate\Session\Store

SSH Illuminate\Remote\RemoteManager remote

SSH(Instance) Illuminate\Remote\Connection

URL Illuminate\Routing\UrlGenerator url

Validator Illuminate\Validation\Factory validator

Validator(Instance) Illuminate\Validation\Validator

View Illuminate\View\Factory view

View(Instance) Illuminate\View\View

Page 85: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionLifecycleOverviewFocusOnServiceProviders

Whenusinganytoolinthe"realworld",youfeelmoreconfidentifyouunderstandhowthattoolworks.Applicationdevelopmentisnodifferent.Whenyouunderstandhowyourdevelopmenttoolsfunction,youfeelmorecomfortableandconfidentusingthem.

Thegoalofthisdocumentistogiveyouagood,high-leveloverviewofhowtheLaravelframework"works".Bygettingtoknowtheoverallframeworkbetter,everythingfeelsless"magical"andyouwillbemoreconfidentbuildingyourapplications.

Ifyoudon'tunderstandallofthetermsrightaway,don'tloseheart!Justtrytogetabasicgraspofwhatisgoingon,andyourknowledgewillgrowasyouexploreothersectionsofthedocumentation.

TheentrypointforallrequeststoaLaravelapplicationisthepublic/index.phpfile.Allrequestsaredirectedtothisfilebyyourwebserver(Apache/Nginx)configuration.Theindex.phpfiledoesn'tcontainmuchcode.Rather,itissimplyastartingpointforloadingtherestoftheframework.

Theindex.phpfileloadstheComposergeneratedautoloaderdefinition,andthenretrievesaninstanceoftheLaravelapplicationfrombootstrap/app.phpscript.ThefirstactiontakenbyLaravelitselfistocreateaninstanceoftheapplication/servicecontainer.

Next,theincomingrequestissenttoeithertheHTTPkernelortheconsolekernel,dependingonthetypeofrequestthatisenteringtheapplication.Thesetwokernelsserveasthecentrallocationthatallrequestsflowthrough.Fornow,let'sjustfocusontheHTTPkernel,whichislocatedinapp/Http/Kernel.php.

TheHTTPkernelextendstheIlluminate\Foundation\Http\Kernelclass,whichdefinesanarrayofbootstrappersthatwillberunbeforetherequestisexecuted.Thesebootstrappersconfigureerrorhandling,configurelogging,detecttheapplicationenvironment,andperformothertasksthatneedtobedonebeforetherequestisactuallyhandled.

TheHTTPkernelalsodefinesalistofHTTPmiddlewarethatallrequestsmustpassthroughbeforebeinghandledbytheapplication.ThesemiddlewarehandlereadingandwritingtheHTTPsession,determineiftheapplicationisinmaintenancemode,verifyingtheCSRFtoken,andmore.

ThemethodsignaturefortheHTTPkernel'shandlemethodisquitesimple:receiveaRequestandreturnaResponse.ThinkoftheKernelasbeingabigblackboxthatrepresentsyourentireapplication.FeeditHTTPrequestsanditwillreturnHTTPresponses.

OneofthemostimportantKernelbootstrappingactionsisloadingtheserviceprovidersforyourapplication.Alloftheserviceprovidersfortheapplicationareconfiguredintheconfig/app.phpconfigurationfile'sprovidersarray.First,theregistermethodwillbecalledonallproviders,then,onceallprovidershavebeenregistered,thebootmethodwillbe

RequestLifecycle

Introduction

LifecycleOverview

FirstThings

HTTP/ConsoleKernels

ServiceProviders

Page 86: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

called.

Oncetheapplicationhasbeenbootstrappedandallserviceprovidershavebeenregistered,theRequestwillbehandedofftotherouterfordispatching.Therouterwilldispatchtherequesttoarouteorcontroller,aswellasrunanyroutespecificmiddleware.

ServiceprovidersaretrulythekeytobootstrappingaLaravelapplication.Theapplicationinstanceiscreated,theserviceprovidersareregistered,andtherequestishandedtothebootstrappedapplication.It'sreallythatsimple!

HavingafirmgraspofhowaLaravelapplicationisbuiltandbootstrappedviaserviceprovidersisveryvaluable.Ofcourse,yourapplication'sdefaultserviceprovidersarestoredintheapp/Providersdirectory.

Bydefault,theAppServiceProviderisfairlyempty.Thisproviderisagreatplacetoaddyourapplication'sownbootstrappingandservicecontainerbindings.Ofcourse,forlargeapplications,youmaywishtocreateseveralserviceproviders,eachwithamoregranulartypeofbootstrapping.

DispatchRequest

FocusOnServiceProviders

Page 87: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionTheRootDirectoryTheAppDirectoryNamespacingYourApplication

ThedefaultLaravelapplicationstructureisintendedtoprovideagreatstartingpointforbothlargeandsmallapplications.Ofcourse,youarefreetoorganizeyourapplicationhoweveryoulike.Laravelimposesalmostnorestrictionsonwhereanygivenclassislocated-aslongasComposercanautoloadtheclass.

TherootdirectoryofafreshLaravelinstallationcontainsavarietyoffolders:

Theappdirectory,asyoumightexpect,containsthecorecodeofyourapplication.We'llexplorethisfolderinmoredetailsoon.

Thebootstrapfoldercontainsafewfilesthatbootstraptheframeworkandconfigureautoloading.

Theconfigdirectory,asthenameimplies,containsallofyourapplication'sconfigurationfiles.

Thedatabasefoldercontainsyourdatabasemigrationandseeds.

Thepublicdirectorycontainsthefrontcontrollerandyourassets(images,JavaScript,CSS,etc.).

Theresourcesdirectorycontainsyourviews,rawassets(LESS,SASS,CoffeeScript),and"language"files.

ThestoragedirectorycontainscompiledBladetemplates,filebasedsessions,filecaches,andotherfilesgeneratedbytheframework.

Thetestsdirectorycontainsyourautomatedtests.

ThevendordirectorycontainsyourComposerdependencies.

The"meat"ofyourapplicationlivesintheappdirectory.Bydefault,thisdirectoryisnamespacedunderAppandisautoloadedbyComposerusingthePSR-4autoloadingstandard.Youmaychangethisnamespaceusingtheapp:nameArtisancommand.

TheappdirectoryshipswithavarietyofadditionaldirectoriessuchasConsole,Http,andProviders.ThinkoftheConsoleandHttpdirectoriesasprovidinganAPIintothe"core"ofyourapplication.TheHTTPprotocolandCLIarebothmechanismstointeractwithyourapplication,butdonotactuallycontainapplicationlogic.Inotherwords,theyaresimplytwowaysofissuingcommandstoyourapplication.TheConsoledirectorycontainsallofyourArtisancommands,whiletheHttpdirectorycontainsyourcontrollers,filters,andrequests.

TheCommandsdirectory,ofcourse,housesthecommandsforyourapplication.Commandsrepresentjobsthatcanbequeuedbyyourapplication,aswellastasksthatyoucanrunsynchronouslywithinthecurrentrequestlifecycle.

TheEventsdirectory,asyoumightexpect,houseseventclasses.Ofcourse,usingclassestorepresenteventsisnot

ApplicationStructure

Introduction

TheRootDirectory

TheAppDirectory

Page 88: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

required;however,ifyouchoosetousethem,thisdirectoryisthedefaultlocationtheywillbecreatedbytheArtisancommandline.

TheHandlersdirectorycontainsthehandlerclassesforbothcommandsandevents.Handlersreceiveacommandoreventandperformlogicinresponsetothatcommandoreventbeingfired.

TheServicesdirectorycontainsvarious"helper"servicesyourapplicationneedstofunction.Forexample,theRegistrarserviceincludedwithLaravelisresponsibleforvalidatingandcreatingnewusersofyourapplication.OtherexamplesmightbeservicestointeractwithexternalAPIs,metricssystems,orevenservicesthataggregatedatafromyourownapplication.

TheExceptionsdirectorycontainsyourapplication'sexceptionhandlerandisalsoagoodplacetostickanyexceptionsthrownbyyourapplication.

Note:ManyoftheclassesintheappdirectorycanbegeneratedbyArtisanviacommands.Toreviewtheavailablecommands,runthephpartisanlistmakecommandinyourterminal.

Asdiscussedabove,thedefaultapplicationnamespaceisApp;however,youmaychangethisnamespacetomatchthenameofyourapplication,whichiseasilydoneviatheapp:nameArtisancommand.Forexample,ifyourapplicationisnamed"SocialNet",youwouldrunthefollowingcommand:

phpartisanapp:nameSocialNet

NamespacingYourApplication

Page 89: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

AuthenticationIntroductionAuthenticatingUsersRetrievingTheAuthenticatedUserProtectingRoutesHTTPBasicAuthenticationPasswordReminders&ResetSocialAuthentication

BillingIntroductionConfigurationSubscribingToAPlanNoCardUpFrontSwappingSubscriptionsSubscriptionQuantityCancellingASubscriptionResumingASubscriptionCheckingSubscriptionStatusHandlingFailedPaymentsHandlingOtherStripeWebhooksInvoices

CacheConfigurationCacheUsageIncrements&DecrementsCacheTagsDatabaseCache

CollectionsIntroductionBasicUsage

CommandBusIntroductionCreatingCommandsDispatchingCommandsQueuedCommandsCommandPipeline

CoreExtensionManagers&FactoriesCacheSessionAuthenticationIoCBasedExtension

ElixirIntroductionInstallation&SetupUsageGulpExtensions

EncryptionIntroductionBasicUsage

Errors&Logging

Services

Page 90: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ConfigurationHandlingErrorsHTTPExceptionsLogging

EventsBasicUsageQueuedEventHandlersEventSubscribers

Filesystem/CloudStorageIntroductionConfigurationBasicUsage

HashingIntroductionBasicUsage

HelpersArraysPathsStringsURLsMiscellaneous

LocalizationIntroductionLanguageFilesBasicUsagePluralizationValidationLocalizationOverridingPackageLanguageFiles

MailConfigurationBasicUsageEmbeddingInlineAttachmentsQueueingMailMail&LocalDevelopment

PackageDevelopmentIntroductionViewsTranslationsConfigurationPublishingFileGroupsRouting

PaginationConfigurationUsageAppendingToPaginationLinksConvertingToJSON

QueuesConfigurationBasicUsageQueueingClosuresRunningTheQueueListenerDaemonQueueWorkerPushQueuesFailedJobs

SessionConfiguration

Page 91: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

SessionUsageFlashDataDatabaseSessionsSessionDrivers

TemplatesBladeTemplatingOtherBladeControlStructuresExtendingBlade

UnitTestingIntroductionDefining&RunningTestsTestEnvironmentCallingRoutesFromTestsMockingFacadesFrameworkAssertionsHelperMethodsRefreshingTheApplication

ValidationBasicUsageControllerValidationFormRequestValidationWorkingWithErrorMessagesErrorMessages&ViewsAvailableValidationRulesConditionallyAddingRulesCustomErrorMessagesCustomValidationRules

Page 92: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionAuthenticatingUsersRetrievingTheAuthenticatedUserProtectingRoutesHTTPBasicAuthenticationPasswordReminders&ResetSocialAuthentication

Laravelmakesimplementingauthenticationverysimple.Infact,almosteverythingisconfiguredforyououtofthebox.Theauthenticationconfigurationfileislocatedatconfig/auth.php,whichcontainsseveralwelldocumentedoptionsfortweakingthebehavioroftheauthenticationservices.

Bydefault,LaravelincludesanApp\Usermodelinyourappdirectory.ThismodelmaybeusedwiththedefaultEloquentauthenticationdriver.

Remember:whenbuildingthedatabaseschemaforthismodel,makethepasswordcolumnatleast60characters.Also,beforegettingstarted,makesurethatyourusers(orequivalent)tablecontainsanullable,stringremember_tokencolumnof100characters.Thiscolumnwillbeusedtostoreatokenfor"rememberme"sessionsbeingmaintainedbyyourapplication.Thiscanbedonebyusing$table->rememberToken();inamigration.Ofcourse,Laravel5shipsmigrationsforthesecolumnsoutofthebox!

IfyourapplicationisnotusingEloquent,youmayusethedatabaseauthenticationdriverwhichusestheLaravelquerybuilder.

Laravelshipswithtwoauthenticationrelatedcontrollersoutofthebox.TheAuthControllerhandlesnewuserregistrationand"loggingin",whilethePasswordControllercontainsthelogictohelpexistingusersresettheirforgottenpasswords.

Eachofthesecontrollersusesatraittoincludetheirnecessarymethods.Formanyapplications,youwillnotneedtomodifythesecontrollersatall.Theviewsthatthesecontrollersrenderarelocatedintheresources/views/authdirectory.Youarefreetocustomizetheseviewshoweveryouwish.

Tomodifytheformfieldsthatarerequiredwhenanewuserregisterswithyourapplication,youmaymodifytheApp\Services\Registrarclass.Thisclassisresponsibleforvalidatingandcreatingnewusersofyourapplication.

ThevalidatormethodoftheRegistrarcontainsthevalidationrulesfornewusersoftheapplication,whilethecreatemethodoftheRegistrarisresponsibleforcreatingnewUserrecordsinyourdatabase.Youarefreetomodifyeachofthesemethodsasyouwish.TheRegistrariscalledbytheAuthControllerviathemethodscontainedintheAuthenticatesAndRegistersUserstrait.

IfyouchoosenottousetheprovidedAuthControllerimplementation,youwillneedtomanagetheauthenticationofyourusersusingtheLaravelauthenticationclassesdirectly.Don'tworry,it'sstillacinch!First,let'scheckouttheattemptmethod:

Authentication

Introduction

AuthenticatingUsers

TheUserRegistrar

ManualAuthentication

Page 93: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

<?phpnamespaceApp\Http\Controllers;

useAuth;

useIlluminate\Routing\Controller;

classAuthControllerextendsController{

/**

*Handleanauthenticationattempt.

*

*@returnResponse

*/

publicfunctionauthenticate()

{

if(Auth::attempt(['email'=>$email,'password'=>$password]))

{

returnredirect()->intended('dashboard');

}

}

}

Theattemptmethodacceptsanarrayofkey/valuepairsasitsfirstargument.Thepasswordvaluewillbehashed.Theothervaluesinthearraywillbeusedtofindtheuserinyourdatabasetable.So,intheexampleabove,theuserwillberetrievedbythevalueoftheemailcolumn.Iftheuserisfound,thehashedpasswordstoredinthedatabasewillbecomparedwiththehashedpasswordvaluepassedtothemethodviathearray.Ifthetwohashedpasswordsmatch,anewauthenticatedsessionwillbestartedfortheuser.

Theattemptmethodwillreturntrueifauthenticationwassuccessful.Otherwise,falsewillbereturned.

Note:Inthisexample,emailisnotarequiredoption,itismerelyusedasanexample.Youshouldusewhatevercolumnnamecorrespondstoa"username"inyourdatabase.

TheintendedredirectfunctionwillredirecttheusertotheURLtheywereattemptingtoaccessbeforebeingcaughtbytheauthenticationfilter.AfallbackURImaybegiventothismethodincasetheintendeddestinationisnotavailable.

Youalsomayaddextraconditionstotheauthenticationquery:

if(Auth::attempt(['email'=>$email,'password'=>$password,'active'=>1]))

{

//Theuserisactive,notsuspended,andexists.

}

Todetermineiftheuserisalreadyloggedintoyourapplication,youmayusethecheckmethod:

if(Auth::check())

{

//Theuserisloggedin...

}

Ifyouwouldliketoprovide"rememberme"functionalityinyourapplication,youmaypassabooleanvalueasthesecondargumenttotheattemptmethod,whichwillkeeptheuserauthenticatedindefinitely,oruntiltheymanuallylogout.Ofcourse,youruserstablemustincludethestringremember_tokencolumn,whichwillbeusedtostorethe"rememberme"token.

if(Auth::attempt(['email'=>$email,'password'=>$password],$remember))

AuthenticatingAUserWithConditions

DeterminingIfAUserIsAuthenticated

AuthenticatingAUserAnd"Remembering"Them

Page 94: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

{

//Theuserisbeingremembered...

}

Ifyouare"remembering"users,youmayusetheviaRemembermethodtodetermineiftheuserwasauthenticatedusingthe"rememberme"cookie:

if(Auth::viaRemember())

{

//

}

TologauserintotheapplicationbytheirID,usetheloginUsingIdmethod:

Auth::loginUsingId(1);

Thevalidatemethodallowsyoutovalidateauser'scredentialswithoutactuallyloggingthemintotheapplication:

if(Auth::validate($credentials))

{

//

}

Youmayalsousetheoncemethodtologauserintotheapplicationforasinglerequest.Nosessionsorcookieswillbeutilized:

if(Auth::once($credentials))

{

//

}

Ifyouneedtologanexistinguserinstanceintoyourapplication,youmaycalltheloginmethodwiththeuserinstance:

Auth::login($user);

Thisisequivalenttologginginauserviacredentialsusingtheattemptmethod.

Auth::logout();

Ofcourse,ifyouareusingthebuilt-inLaravelauthenticationcontrollers,acontrollermethodthathandlesloggingusersoutoftheapplicationisprovidedoutofthebox.

AuthenticatingUsersByID

ValidatingUserCredentialsWithoutLogin

LoggingAUserInForASingleRequest

ManuallyLoggingInAUser

LoggingAUserOutOfTheApplication

Page 95: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Whentheattemptmethodiscalled,theauth.attempteventwillbefired.Iftheauthenticationattemptissuccessfulandtheuserisloggedin,theauth.logineventwillbefiredaswell.

Onceauserisauthenticated,thereareseveralwaystoobtainaninstanceoftheUser.

First,youmayaccesstheuserfromtheAuthfacade:

<?phpnamespaceApp\Http\Controllers;

useIlluminate\Routing\Controller;

classProfileControllerextendsController{

/**

*Updatetheuser'sprofile.

*

*@returnResponse

*/

publicfunctionupdateProfile()

{

if(Auth::user())

{

//Auth::user()returnsaninstanceoftheauthenticateduser...

}

}

}

Second,youmayaccesstheauthenticateduserviaanIlluminate\Http\Requestinstance:

<?phpnamespaceApp\Http\Controllers;

useIlluminate\Http\Request;

useIlluminate\Routing\Controller;

classProfileControllerextendsController{

/**

*Updatetheuser'sprofile.

*

*@returnResponse

*/

publicfunctionupdateProfile(Request$request)

{

if($request->user())

{

//$request->user()returnsaninstanceoftheauthenticateduser...

}

}

}

Thirdly,youmaytype-hinttheIlluminate\Contracts\Auth\Authenticatablecontract.Thistype-hintmaybeaddedtoacontrollerconstructor,controllermethod,oranyotherconstructorofaclassresolvedbytheservicecontainer:

<?phpnamespaceApp\Http\Controllers;

useIlluminate\Routing\Controller;

useIlluminate\Contracts\Auth\Authenticatable;

classProfileControllerextendsController{

/**

*Updatetheuser'sprofile.

AuthenticationEvents

RetrievingTheAuthenticatedUser

Page 96: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

*

*@returnResponse

*/

publicfunctionupdateProfile(Authenticatable$user)

{

//$userisaninstanceoftheauthenticateduser...

}

}

Routemiddlewarecanbeusedtoallowonlyauthenticateduserstoaccessagivenroute.Laravelprovidestheauthmiddlewarebydefault,anditisdefinedinapp\Http\Middleware\Authenticate.php.Allyouneedtodoisattachittoaroutedefinition:

//WithARouteClosure...

Route::get('profile',['middleware'=>'auth',function()

{

//Onlyauthenticatedusersmayenter...

}]);

//WithAController...

Route::get('profile',['middleware'=>'auth','uses'=>'ProfileController@show']);

HTTPBasicAuthenticationprovidesaquickwaytoauthenticateusersofyourapplicationwithoutsettingupadedicated"login"page.Togetstarted,attachtheauth.basicmiddlewaretoyourroute:

Route::get('profile',['middleware'=>'auth.basic',function()

{

//Onlyauthenticatedusersmayenter...

}]);

Bydefault,thebasicmiddlewarewillusetheemailcolumnontheuserrecordasthe"username".

YoumayalsouseHTTPBasicAuthenticationwithoutsettingauseridentifiercookieinthesession,whichisparticularlyusefulforAPIauthentication.Todoso,defineamiddlewarethatcallstheonceBasicmethod:

publicfunctionhandle($request,Closure$next)

{

returnAuth::onceBasic()?:$next($request);

}

IfyouareusingPHPFastCGI,HTTPBasicauthenticationmaynotworkcorrectlyoutofthebox.Thefollowinglinesshouldbeaddedtoyour.htaccessfile:

RewriteCond%{HTTP:Authorization}^(.+)$

RewriteRule.*-[E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

ProtectingRoutes

HTTPBasicAuthentication

ProtectingARouteWithHTTPBasic

SettingUpAStatelessHTTPBasicFilter

Page 97: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Mostwebapplicationsprovideawayforuserstoresettheirforgottenpasswords.Ratherthanforcingyoutore-implementthisoneachapplication,Laravelprovidesconvenientmethodsforsendingpasswordremindersandperformingpasswordresets.

Togetstarted,verifythatyourUsermodelimplementstheIlluminate\Contracts\Auth\CanResetPasswordcontract.Ofcourse,theUsermodelincludedwiththeframeworkalreadyimplementsthisinterface,andusestheIlluminate\Auth\Passwords\CanResetPasswordtraittoincludethemethodsneededtoimplementtheinterface.

Next,atablemustbecreatedtostorethepasswordresettokens.ThemigrationforthistableisincludedwithLaraveloutofthebox,andresidesinthedatabase/migrationsdirectory.Soallyouneedtodoismigrate:

phpartisanmigrate

LaravelalsoincludesanAuth\PasswordControllerthatcontainsthelogicnecessarytoresetuserpasswords.We'veevenprovidedviewstogetyoustarted!Theviewsarelocatedintheresources/views/authdirectory.Youarefreetomodifytheseviewsasyouwishtosuityourownapplication'sdesign.

Youruserwillreceiveane-mailwithalinkthatpointstothegetResetmethodofthePasswordController.Thismethodwillrenderthepasswordresetformandallowuserstoresettheirpasswords.Afterthepasswordisreset,theuserwillautomaticallybeloggedintotheapplicationandredirectedto/home.Youcancustomizethepost-resetredirectlocationbydefiningaredirectTopropertyonthePasswordController:

protected$redirectTo='/dashboard';

Note:Bydefault,passwordresettokensexpireafteronehour.Youmaychangethisviathereminder.expireoptionofyourconfig/auth.phpfile.

Inadditiontotypical,formbasedauthentication,Laravelalsoprovidesasimple,convenientwaytoauthenticatewithOAuthprovidersusingLaravelSocialite.SocialitecurrentlysupportsauthenticationwithFacebook,Twitter,Google,andGitHub.

TogetstartedwithSocialite,includethepackageinyourcomposer.jsonfile:

"laravel/socialite":"~2.0"

Next,registertheLaravel\Socialite\SocialiteServiceProviderinyourconfig/app.phpconfigurationfile.Youmayalsoregisterafacade:

'Socialize'=>'Laravel\Socialite\Facades\Socialite',

PasswordReminders&Reset

Model&Table

GeneratingTheReminderTableMigration

PasswordReminderController

SocialAuthentication

Page 98: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

YouwillneedtoaddcredentialsfortheOAuthservicesyourapplicationutilizes.Thesecredentialsshouldbeplacedinyourconfig/services.phpconfigurationfile,andshouldusethekeyfacebook,twitter,google,orgithub,dependingontheprovidersyourapplicationrequires.Forexample:

'github'=>[

'client_id'=>'your-github-app-id',

'client_secret'=>'your-github-app-secret',

'redirect'=>'http://your-callback-url',

],

Next,youarereadytoauthenticateusers!Youwillneedtworoutes:oneforredirectingtheusertotheOAuthprovider,andanotherforreceivingthecallbackfromtheproviderafterauthentication.Here'sanexampleusingtheSocializefacade:

publicfunctionredirectToProvider()

{

returnSocialize::with('github')->redirect();

}

publicfunctionhandleProviderCallback()

{

$user=Socialize::with('github')->user();

//$user->token;

}

TheredirectmethodtakescareofsendingtheusertotheOAuthprovider,whiletheusermethodwillreadtheincomingrequestandretrievetheuser'sinformationfromtheprovider.Beforeredirectingtheuser,youmayalsoset"scopes"ontherequest:

returnSocialize::with('github')->scopes(['scope1','scope2'])->redirect();

Onceyouhaveauserinstance,youcangrabafewmoredetailsabouttheuser:

$user=Socialize::with('github')->user();

//OAuthTwoProviders

$token=$user->token;

//OAuthOneProviders

$token=$user->token;

$tokenSecret=$user->tokenSecret;

//AllProviders

$user->getNickname();

$user->getName();

$user->getEmail();

$user->getAvatar();

RetrievingUserDetails

Page 99: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionConfigurationSubscribingToAPlanNoCardUpFrontSwappingSubscriptionsSubscriptionQuantityCancellingASubscriptionResumingASubscriptionCheckingSubscriptionStatusHandlingFailedPaymentsHandlingOtherStripeWebhooksInvoices

LaravelCashierprovidesanexpressive,fluentinterfacetoStripe'ssubscriptionbillingservices.Ithandlesalmostalloftheboilerplatesubscriptionbillingcodeyouaredreadingwriting.Inadditiontobasicsubscriptionmanagement,Cashiercanhandlecoupons,swappingsubscription,subscription"quantities",cancellationgraceperiods,andevengenerateinvoicePDFs.

First,addtheCashierpackagetoyourcomposer.jsonfile:

"laravel/cashier":"~3.0"

Next,registertheLaravel\Cashier\CashierServiceProviderinyourappconfigurationfile.

BeforeusingCashier,we'llneedtoaddseveralcolumnstoyourdatabase.Don'tworry,youcanusethecashier:tableArtisancommandtocreateamigrationtoaddthenecessarycolumn.Forexample,toaddthecolumntotheuserstableusephpartisancashier:tableusers.Oncethemigrationhasbeencreated,simplyrunthemigratecommand.

Next,addtheBillabletraitandappropriatedatemutatorstoyourmodeldefinition:

useLaravel\Cashier\Billable;

useLaravel\Cashier\Contracts\BillableasBillableContract;

classUserextendsEloquentimplementsBillableContract{

useBillable;

protected$dates=['trial_ends_at','subscription_ends_at'];

}

LaravelCashier

Introduction

Configuration

Composer

ServiceProvider

Migration

ModelSetup

Page 100: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Finally,setyourStripekeyinoneofyourbootstrapfilesorserviceproviders,suchastheAppServiceProvider:

User::setStripeKey('stripe-key');

Onceyouhaveamodelinstance,youcaneasilysubscribethatusertoagivenStripeplan:

$user=User::find(1);

$user->subscription('monthly')->create($creditCardToken);

Ifyouwouldliketoapplyacouponwhencreatingthesubscription,youmayusethewithCouponmethod:

$user->subscription('monthly')

->withCoupon('code')

->create($creditCardToken);

ThesubscriptionmethodwillautomaticallycreatetheStripesubscription,aswellasupdateyourdatabasewithStripecustomerIDandotherrelevantbillinginformation.IfyourplanhasatrialconfiguredinStripe,thetrialenddatewillalsoautomaticallybesetontheuserrecord.

IfyourplanhasatrialperiodthatisnotconfiguredinStripe,youmustsetthetrialenddatemanuallyaftersubscribing:

$user->trial_ends_at=Carbon::now()->addDays(14);

$user->save();

Ifyouwouldliketospecifyadditionalcustomerdetails,youmaydosobypassingthemassecondargumenttothecreatemethod:

$user->subscription('monthly')->create($creditCardToken,[

'email'=>$email,'description'=>'OurFirstCustomer'

]);

TolearnmoreabouttheadditionalfieldssupportedbyStripe,checkoutStripe'sdocumentationoncustomercreation.

Ifyourapplicationoffersafree-trialwithnocredit-cardupfront,setthecardUpFrontpropertyonyourmodeltofalse:

protected$cardUpFront=false;

Onaccountcreation,besuretosetthetrialenddateonthemodel:

StripeKey

SubscribingToAPlan

SpecifyingAdditionalUserDetails

NoCardUpFront

Page 101: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$user->trial_ends_at=Carbon::now()->addDays(14);

$user->save();

Toswapausertoanewsubscription,usetheswapmethod:

$user->subscription('premium')->swap();

Iftheuserisontrial,thetrialwillbemaintainedasnormal.Also,ifa"quantity"existsforthesubscription,thatquantitywillalsobemaintained.

Sometimessubscriptionsareaffectedby"quantity".Forexample,yourapplicationmightcharge$10permonthperuseronanaccount.Toeasilyincrementordecrementyoursubscriptionquantity,usetheincrementanddecrementmethods:

$user=User::find(1);

$user->subscription()->increment();

//Addfivetothesubscription'scurrentquantity...

$user->subscription()->increment(5);

$user->subscription->decrement();

//Subtractfivetothesubscription'scurrentquantity...

$user->subscription()->decrement(5);

Cancellingasubscriptionisawalkinthepark:

$user->subscription()->cancel();

Whenasubscriptioniscancelled,Cashierwillautomaticallysetthesubscription_ends_atcolumnonyourdatabase.Thiscolumnisusedtoknowwhenthesubscribedmethodshouldbeginreturningfalse.Forexample,ifacustomercancelsasubscriptiononMarch1st,butthesubscriptionwasnotscheduledtoenduntilMarch5th,thesubscribedmethodwillcontinuetoreturntrueuntilMarch5th.

Ifauserhascancelledtheirsubscriptionandyouwishtoresumeit,usetheresumemethod:

$user->subscription('monthly')->resume($creditCardToken);

Iftheusercancelsasubscriptionandthenresumesthatsubscriptionbeforethesubscriptionhasfullyexpired,theywillnotbebilledimmediately.Theirsubscriptionwillsimplybere-activated,andtheywillbebilledontheoriginalbillingcycle.

SwappingSubscriptions

SubscriptionQuantity

CancellingASubscription

ResumingASubscription

CheckingSubscriptionStatus

Page 102: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Toverifythatauserissubscribedtoyourapplication,usethesubscribedcommand:

if($user->subscribed())

{

//

}

Thesubscribedmethodmakesagreatcandidateforaroutemiddleware:

publicfunctionhandle($request,Closure$next)

{

if($request->user()&&!$request->user()->subscribed())

{

returnredirect('billing');

}

return$next($request);

}

Youmayalsodetermineiftheuserisstillwithintheirtrialperiod(ifapplicable)usingtheonTrialmethod:

if($user->onTrial())

{

//

}

Todetermineiftheuserwasonceanactivesubscriber,buthascancelledtheirsubscription,youmayusethecancelledmethod:

if($user->cancelled())

{

//

}

Youmayalsodetermineifauserhascancelledtheirsubscription,butarestillontheir"graceperiod"untilthesubscriptionfullyexpires.Forexample,ifausercancelsasubscriptiononMarch5ththatwasscheduledtoendonMarch10th,theuserisontheir"graceperiod"untilMarch10th.Notethatthesubscribedmethodstillreturnstrueduringthistime.

if($user->onGracePeriod())

{

//

}

TheeverSubscribedmethodmaybeusedtodetermineiftheuserhaseversubscribedtoaplaninyourapplication:

if($user->everSubscribed())

{

//

}

TheonPlanmethodmaybeusedtodetermineiftheuserissubscribedtoagivenplanbasedonitsID:

if($user->onPlan('monthly'))

{

//

}

Page 103: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Whatifacustomer'screditcardexpires?Noworries-CashierincludesaWebhookcontrollerthatcaneasilycancelthecustomer'ssubscriptionforyou.Justpointaroutetothecontroller:

Route::post('stripe/webhook','Laravel\Cashier\WebhookController@handleWebhook');

That'sit!Failedpaymentswillbecapturedandhandledbythecontroller.Thecontrollerwillcancelthecustomer'ssubscriptionafterthreefailedpaymentattempts.Thestripe/webhookURIinthisexampleisjustforexample.YouwillneedtoconfiguretheURIinyourStripesettings.

IfyouhaveadditionalStripewebhookeventsyouwouldliketohandle,simplyextendtheWebhookcontroller.YourmethodnamesshouldcorrespondtoCashier'sexpectedconvention,specifically,methodsshouldbeprefixedwithhandleandthenameoftheStripewebhookyouwishtohandle.Forexample,ifyouwishtohandletheinvoice.payment_succeededwebhook,youshouldaddahandleInvoicePaymentSucceededmethodtothecontroller.

classWebhookControllerextendsLaravel\Cashier\WebhookController{

publicfunctionhandleInvoicePaymentSucceeded($payload)

{

//HandleTheEvent

}

}

Note:Inadditiontoupdatingthesubscriptioninformationinyourdatabase,theWebhookcontrollerwillalsocancelthesubscriptionviatheStripeAPI.

Youcaneasilyretrieveanarrayofauser'sinvoicesusingtheinvoicesmethod:

$invoices=$user->invoices();

Whenlistingtheinvoicesforthecustomer,youmayusethesehelpermethodstodisplaytherelevantinvoiceinformation:

{{$invoice->id}}

{{$invoice->dateString()}}

{{$invoice->dollars()}}

UsethedownloadInvoicemethodtogenerateaPDFdownloadoftheinvoice.Yes,it'sreallythiseasy:

return$user->downloadInvoice($invoice->id,[

'vendor'=>'YourCompany',

'product'=>'YourProduct',

]);

HandlingFailedPayments

HandlingOtherStripeWebhooks

Invoices

Page 104: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ConfigurationCacheUsageIncrements&DecrementsCacheTagsDatabaseCache

LaravelprovidesaunifiedAPIforvariouscachingsystems.Thecacheconfigurationislocatedatconfig/cache.php.Inthisfileyoumayspecifywhichcachedriveryouwouldlikeusedbydefaultthroughoutyourapplication.LaravelsupportspopularcachingbackendslikeMemcachedandRedisoutofthebox.

Thecacheconfigurationfilealsocontainsvariousotheroptions,whicharedocumentedwithinthefile,somakesuretoreadovertheseoptions.Bydefault,Laravelisconfiguredtousethefilecachedriver,whichstorestheserialized,cachedobjectsinthefilesystem.Forlargerapplications,itisrecommendedthatyouuseanin-memorycachesuchasMemcachedorAPC.Youmayevenconfiguremultiplecacheconfigurationsforthesamedriver.

BeforeusingaRediscachewithLaravel,youwillneedtoinstallthepredis/predispackage(~1.0)viaComposer.

Cache::put('key','value',$minutes);

$expiresAt=Carbon::now()->addMinutes(10);

Cache::put('key','value',$expiresAt);

Cache::add('key','value',$minutes);

Theaddmethodwillreturntrueiftheitemisactuallyaddedtothecache.Otherwise,themethodwillreturnfalse.

if(Cache::has('key'))

{

//

}

Cache

Configuration

CacheUsage

StoringAnItemInTheCache

UsingCarbonObjectsToSetExpireTime

StoringAnItemInTheCacheIfItDoesn'tExist

CheckingForExistenceInCache

RetrievingAnItemFromTheCache

Page 105: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$value=Cache::get('key');

$value=Cache::get('key','default');

$value=Cache::get('key',function(){return'default';});

Cache::forever('key','value');

Sometimesyoumaywishtoretrieveanitemfromthecache,butalsostoreadefaultvalueiftherequesteditemdoesn'texist.YoumaydothisusingtheCache::remembermethod:

$value=Cache::remember('users',$minutes,function()

{

returnDB::table('users')->get();

});

Youmayalsocombinetherememberandforevermethods:

$value=Cache::rememberForever('users',function()

{

returnDB::table('users')->get();

});

Notethatallitemsstoredinthecacheareserialized,soyouarefreetostoreanytypeofdata.

Ifyouneedtoretrieveanitemfromthecacheandthendeleteit,youmayusethepullmethod:

$value=Cache::pull('key');

Cache::forget('key');

Alldriversexceptfileanddatabasesupporttheincrementanddecrementoperations:

Cache::increment('key');

Cache::increment('key',$amount);

RetrievingAnItemOrReturningADefaultValue

StoringAnItemInTheCachePermanently

PullingAnItemFromTheCache

RemovingAnItemFromTheCache

Increments&Decrements

IncrementingAValue

Page 106: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Cache::decrement('key');

Cache::decrement('key',$amount);

Note:Cachetagsarenotsupportedwhenusingthefileordatabasecachedrivers.Furthermore,whenusingmultipletagswithcachesthatarestored"forever",performancewillbebestwithadriversuchasmemcached,whichautomaticallypurgesstalerecords.

Cachetagsallowyoutotagrelateditemsinthecache,andthenflushallcachestaggedwithagivenname.Toaccessataggedcache,usethetagsmethod.

Youmaystoreataggedcachebypassinginanorderedlistoftagnamesasarguments,orasanorderedarrayoftagnames:

Cache::tags('people','authors')->put('John',$john,$minutes);

Cache::tags(array('people','artists'))->put('Anne',$anne,$minutes);

Youmayuseanycachestoragemethodincombinationwithtags,includingremember,forever,andrememberForever.Youmayalsoaccesscacheditemsfromthetaggedcache,aswellasusetheothercachemethodssuchasincrementanddecrement.

Toaccessataggedcache,passthesameorderedlistoftagsusedtosaveit.

$anne=Cache::tags('people','artists')->get('Anne');

$john=Cache::tags(array('people','authors'))->get('John');

Youmayflushallitemstaggedwithanameorlistofnames.Forexample,thisstatementwouldremoveallcachestaggedwitheitherpeople,authors,orboth.So,both"Anne"and"John"wouldberemovedfromthecache:

Cache::tags('people','authors')->flush();

Incontrast,thisstatementwouldremoveonlycachestaggedwithauthors,so"John"wouldberemoved,butnot"Anne".

Cache::tags('authors')->flush();

Whenusingthedatabasecachedriver,youwillneedtosetupatabletocontainthecacheitems.You'llfindanexampleSchemadeclarationforthetablebelow:

DecrementingAValue

CacheTags

AccessingATaggedCache

AccessingItemsInATaggedCache

DatabaseCache

Page 107: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Schema::create('cache',function($table)

{

$table->string('key')->unique();

$table->text('value');

$table->integer('expiration');

});

Page 108: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionBasicUsage

TheIlluminate\Support\Collectionclassprovidesafluent,convenientwrapperforworkingwitharraysofdata.Forexample,checkoutthefollowingcode.We'llusethecollecthelpertocreateanewcollectioninstancefromthearray:

$collection=collect(['taylor','abigail',null])->map(function($name)

{

returnstrtoupper($name);

})

->reject(function($name)

{

returnis_null($value);

});

Asyoucansee,theCollectionclassallowsyoutochainitsmethodstoperformfluentmappingandreducingoftheunderlyingarray.Ingeneral,everyCollectionmethodreturnsanentirelynewCollectioninstance.Todiginfurther,keepreading!

Asmentionedabove,thecollecthelperwillreturnanewIlluminate\Support\Collectioninstanceforthegivenarray.YoumayalsousethemakecommandontheCollectionclass:

$collection=collect([1,2,3]);

$collection=Collection::make([1,2,3]);

Ofcourse,collectionsofEloquentobjectsarealwaysreturnedasCollectioninstances;however,youshouldfeelfreetousetheCollectionclasswhereveritisconvenientforyourapplication.

Insteadoflistingallofthemethods(therearealot)theCollectionmakesavailable,checkouttheAPIdocumentationfortheclass!

Collections

Introduction

BasicUsage

CreatingCollections

ExploreTheCollection

Page 109: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionCreatingCommandsDispatchingCommandsQueuedCommandsCommandPipeline

TheLaravelcommandbusprovidesaconvenientmethodofencapsulatingtasksyourapplicationneedstoperformintosimple,easytounderstand"commands".Tohelpusunderstandthepurposeofcommands,let'spretendwearebuildinganapplicationthatallowsuserstopurchasepodcasts.

Whenauserpurchasesapodcast,thereareavarietyofthingsthatneedtohappen.Forexample,wemayneedtochargetheuser'screditcard,addarecordtoourdatabasethatrepresentsthepurchase,andsendaconfirmatione-mailofthepurchase.Perhapswealsoneedtoperformsomekindofvalidationastowhethertheuserisallowedtopurchasepodcasts.

Wecouldputallofthislogicinsideacontrollermethod;however,thishasseveraldisadvantages.ThefirstdisadvantageisthatourcontrollerprobablyhandlesseveralotherincomingHTTPactions,andincludingcomplicatedlogicineachcontrollermethodwillsoonbloatourcontrollerandmakeithardertoread.Secondly,itisdifficulttore-usethepurchasepodcastlogicoutsideofthecontrollercontext.Thirdly,itismoredifficulttounit-testthecommandaswemustalsogenerateastubHTTPrequestandmakeafullrequesttotheapplicationtotestthepurchasepodcastlogic.

Insteadofputtingthislogicinthecontroller,wemaychoosetoencapsulateitwithina"command"object,suchasaPurchasePodcastcommand.

TheArtisanCLIcangeneratenewcommandclassesusingthemake:commandcommand:

phpartisanmake:commandPurchasePodcast

Thenewlygeneratedclasswillbeplacedintheapp/Commandsdirectory.Bydefault,thecommandcontainstwomethods:theconstructorandthehandlemethod.Ofcourse,theconstructorallowsyoutopassanyrelevantobjectstothecommand,whilethehandlemethodexecutesthecommand.Forexample:

classPurchasePodcastextendsCommandimplementsSelfHandling{

protected$user,$podcast;

/**

*Createanewcommandinstance.

*

*@returnvoid

*/

publicfunction__construct(User$user,Podcast$podcast)

{

$this->user=$user;

$this->podcast=$podcast;

}

/**

*Executethecommand.

*

*@returnvoid

CommandBus

Introduction

CreatingCommands

Page 110: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

*/

publicfunctionhandle()

{

//Handlethelogictopurchasethepodcast...

event(newPodcastWasPurchased($this->user,$this->podcast));

}

}

Thehandlemethodmayalsotype-hintdependencies,andtheywillbeautomaticallyinjectedbytheIoCcontainer.Forexample:

/**

*Executethecommand.

*

*@returnvoid

*/

publicfunctionhandle(BillingGateway$billing)

{

//Handlethelogictopurchasethepodcast...

}

So,oncewehavecreatedacommand,howdowedispatchit?Ofcourse,wecouldcallthehandlemethoddirectly;however,dispatchingthecommandthroughtheLaravel"commandbus"hasseveraladvantageswhichwewilldiscusslater.

Ifyouglanceatyourapplication'sbasecontroller,youwillseetheDispatchesCommandstrait.Thistraitallowsustocallthedispatchmethodfromanyofourcontrollers.Forexample:

publicfunctionpurchasePodcast($podcastId)

{

$this->dispatch(

newPurchasePodcast(Auth::user(),Podcast::findOrFail($podcastId))

);

}

ThecommandbuswilltakecareofexecutingthecommandandcallingtheIoCcontainertoinjectanyneededdependenciesintothehandlemethod.

YoumayaddtheIlluminate\Foundation\Bus\DispatchesCommandstraittoanyclassyouwish.Ifyouwouldliketoreceiveacommandbusinstancethroughtheconstructorofanyofyourclasses,youmaytype-hinttheIlluminate\Contracts\Bus\Dispatcherinterface.Finally,youmayalsousetheBusfacadetoquicklydispatchcommands:

Bus::dispatch(

newPurchasePodcast(Auth::user(),Podcast::findOrFail($podcastId))

);

ItisverycommontomapHTTPrequestvariablesintocommands.So,insteadofforcingyoutodothismanuallyforeachrequest,Laravelprovidessomehelpermethodstomakeitacinch.Let'stakealookatthedispatchFrommethodavailableontheDispatchesCommandstrait:

$this->dispatchFrom('Command\Class\Name',$request);

DispatchingCommands

MappingCommandPropertiesFromRequests

Page 111: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Thismethodwillexaminetheconstructorofthecommandclassitisgiven,andthenextractvariablesfromtheHTTPrequest(oranyotherArrayAccessobject)tofilltheneededconstructorparametersofthecommand.So,ifourcommandclassacceptsafirstNamevariableinitsconstructor,thecommandbuswillattempttopullthefirstNameparameterfromtheHTTPrequest.

YoumayalsopassanarrayasthethirdargumenttothedispatchFrommethod.Thisarraywillbeusedtofillanyconstructorparametersthatarenotavailableontherequest:

$this->dispatchFrom('Command\Class\Name',$request,[

'firstName'=>'Taylor',

]);

Thecommandbusisnotjustforsynchronousjobsthatrunduringthecurrentrequestcycle,butalsoservesastheprimarywaytobuildqueuedjobsinLaravel.So,howdoweinstructcommandbustoqueueourjobforbackgroundprocessinginsteadofrunningitsynchronously?It'seasy.Firstly,whengeneratinganewcommand,justaddthe--queuedflagtothecommand:

phpartisanmake:commandPurchasePodcast--queued

Asyouwillsee,thisaddsafewmorefeaturestothecommand,namelytheIlluminate\Contracts\Queue\ShouldBeQueuedinterfaceandtheSerializesModelstrait.Theseinstructthecommandbustoqueuethecommand,aswellasgracefullyserializeanddeserializeanyEloquentmodelsyourcommandstoresasproperties.

Ifyouwouldliketoconvertanexistingcommandintoaqueuedcommand,simplyimplementtheIlluminate\Contracts\Queue\ShouldBeQueuedinterfaceontheclassmanually.Itcontainsnomethods,andmerelyservesasa"markerinterface"forthedispatcher.

Then,justwriteyourcommandnormally.Whenyoudispatchittothebusthatbuswillautomaticallyqueuethecommandforbackgroundprocessing.Itdoesn'tgetanyeasierthanthat.

Formoreinformationoninteractingwithqueuedcommands,viewthefullqueuedocumentation.

Beforeacommandisdispatchedtoahandler,youmaypassitthroughotherclassesina"pipeline".CommandpipesworkjustlikeHTTPmiddleware,exceptforyourcommands!Forexample,acommandpipecouldwraptheentirecommandoperationwithinadatabasetransaction,orsimplylogitsexecution.

Toaddapipetoyourbus,callthepipeThroughmethodofthedispatcherfromyourApp\Providers\BusServiceProvider::bootmethod:

$dispatcher->pipeThrough(['UseDatabaseTransactions','LogCommand']);

Acommandpipeisdefinedwithahandlemethod,justlikeamiddleware:

classUseDatabaseTransactions{

publicfunctionhandle($command,$next)

{

returnDB::transaction(function()use($command,$next)

{

return$next($command);

QueuedCommands

CommandPipeline

Page 112: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

}

}

}

CommandpipeclassesareresolvedthroughtheIoCcontainer,sofeelfreetotype-hintanydependenciesyouneedwithintheirconstructors.

YoumayevendefineaClosureasacommandpipe:

$dispatcher->pipeThrough([function($command,$next)

{

returnDB::transaction(function()use($command,$next)

{

return$next($command);

}

}]);

Page 113: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Managers&FactoriesCacheSessionAuthenticationIoCBasedExtension

LaravelhasseveralManagerclassesthatmanagethecreationofdriver-basedcomponents.Theseincludethecache,session,authentication,andqueuecomponents.Themanagerclassisresponsibleforcreatingaparticulardriverimplementationbasedontheapplication'sconfiguration.Forexample,theCacheManagerclasscancreateAPC,Memcached,File,andvariousotherimplementationsofcachedrivers.

Eachofthesemanagersincludesanextendmethodwhichmaybeusedtoeasilyinjectnewdriverresolutionfunctionalityintothemanager.We'llcovereachofthesemanagersbelow,withexamplesofhowtoinjectcustomdriversupportintoeachofthem.

Note:TakeamomenttoexplorethevariousManagerclassesthatshipwithLaravel,suchastheCacheManagerandSessionManager.ReadingthroughtheseclasseswillgiveyouamorethoroughunderstandingofhowLaravelworksunderthehood.AllmanagerclassesextendtheIlluminate\Support\Managerbaseclass,whichprovidessomehelpful,commonfunctionalityforeachmanager.

ToextendtheLaravelcachefacility,wewillusetheextendmethodontheCacheManager,whichisusedtobindacustomdriverresolvertothemanager,andiscommonacrossallmanagerclasses.Forexample,toregisteranewcachedrivernamed"mongo",wewoulddothefollowing:

Cache::extend('mongo',function($app)

{

returnCache::repository(newMongoStore);

});

Thefirstargumentpassedtotheextendmethodisthenameofthedriver.Thiswillcorrespondtoyourdriveroptionintheconfig/cache.phpconfigurationfile.ThesecondargumentisaClosurethatshouldreturnanIlluminate\Cache\Repositoryinstance.TheClosurewillbepassedan$appinstance,whichisaninstanceofIlluminate\Foundation\ApplicationandanIoCcontainer.

ThecalltoCache::extendcouldbedoneinthebootmethodofthedefaultApp\Providers\AppServiceProviderthatshipswithfreshLaravelapplications,oryoumaycreateyourownserviceprovidertohousetheextension-justdon'tforgettoregistertheproviderintheconfig/app.phpproviderarray.

Tocreateourcustomcachedriver,wefirstneedtoimplementtheIlluminate\Contracts\Cache\Storecontract.So,ourMongoDBcacheimplementationwouldlooksomethinglikethis:

classMongoStoreimplementsIlluminate\Contracts\Cache\Store{

publicfunctionget($key){}

publicfunctionput($key,$value,$minutes){}

publicfunctionincrement($key,$value=1){}

publicfunctiondecrement($key,$value=1){}

publicfunctionforever($key,$value){}

publicfunctionforget($key){}

ExtendingTheFramework

Managers&Factories

Cache

Page 114: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

publicfunctionflush(){}

}

WejustneedtoimplementeachofthesemethodsusingaMongoDBconnection.Onceourimplementationiscomplete,wecanfinishourcustomdriverregistration:

Cache::extend('mongo',function($app)

{

returnCache::repository(newMongoStore);

});

Ifyou'rewonderingwheretoputyourcustomcachedrivercode,considermakingitavailableonPackagist!Or,youcouldcreateanExtensionsnamespacewithinyourappdirectory.However,keepinmindthatLaraveldoesnothavearigidapplicationstructureandyouarefreetoorganizeyourapplicationaccordingtoyourpreferences.

ExtendingLaravelwithacustomsessiondriverisjustaseasyasextendingthecachesystem.Again,wewillusetheextendmethodtoregisterourcustomcode:

Session::extend('mongo',function($app)

{

//ReturnimplementationofSessionHandlerInterface

});

YoushouldplaceyoursessionextensioncodeinthebootmethodofyourAppServiceProvider.

NotethatourcustomsessiondrivershouldimplementtheSessionHandlerInterface.Thisinterfacecontainsjustafewsimplemethodsweneedtoimplement.AstubbedMongoDBimplementationwouldlooksomethinglikethis:

classMongoHandlerimplementsSessionHandlerInterface{

publicfunctionopen($savePath,$sessionName){}

publicfunctionclose(){}

publicfunctionread($sessionId){}

publicfunctionwrite($sessionId,$data){}

publicfunctiondestroy($sessionId){}

publicfunctiongc($lifetime){}

}

SincethesemethodsarenotasreadilyunderstandableasthecacheStoreInterface,let'squicklycoverwhateachofthemethodsdo:

Theopenmethodwouldtypicallybeusedinfilebasedsessionstoresystems.SinceLaravelshipswithafilesessiondriver,youwillalmostneverneedtoputanythinginthismethod.Youcanleaveitasanemptystub.Itissimplyafactofpoorinterfacedesign(whichwe'lldiscusslater)thatPHPrequiresustoimplementthismethod.Theclosemethod,liketheopenmethod,canalsousuallybedisregarded.Formostdrivers,itisnotneeded.Thereadmethodshouldreturnthestringversionofthesessiondataassociatedwiththegiven$sessionId.Thereisnoneedtodoanyserializationorotherencodingwhenretrievingorstoringsessiondatainyourdriver,asLaravelwillperformtheserializationforyou.Thewritemethodshouldwritethegiven$datastringassociatedwiththe$sessionIdtosomepersistentstorage

Session

WhereToExtendTheSession

WritingTheSessionExtension

Page 115: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

system,suchasMongoDB,Dynamo,etc.Thedestroymethodshouldremovethedataassociatedwiththe$sessionIdfrompersistentstorage.Thegcmethodshoulddestroyallsessiondatathatisolderthanthegiven$lifetime,whichisaUNIXtimestamp.Forself-expiringsystemslikeMemcachedandRedis,thismethodmaybeleftempty.

OncetheSessionHandlerInterfacehasbeenimplemented,wearereadytoregisteritwiththeSessionmanager:

Session::extend('mongo',function($app)

{

returnnewMongoHandler;

});

Oncethesessiondriverhasbeenregistered,wemayusethemongodriverinourconfig/session.phpconfigurationfile.

Note:Remember,ifyouwriteacustomsessionhandler,shareitonPackagist!

Authenticationmaybeextendedthesamewayasthecacheandsessionfacilities.Again,wewillusetheextendmethodwehavebecomefamiliarwith:

Auth::extend('riak',function($app)

{

//ReturnimplementationofIlluminate\Contracts\Auth\UserProvider

});

TheUserProviderimplementationsareonlyresponsibleforfetchingaIlluminate\Contracts\Auth\Authenticatableimplementationoutofapersistentstoragesystem,suchasMySQL,Riak,etc.ThesetwointerfacesallowtheLaravelauthenticationmechanismstocontinuefunctioningregardlessofhowtheuserdataisstoredorwhattypeofclassisusedtorepresentit.

Let'stakealookattheUserProvidercontract:

interfaceUserProvider{

publicfunctionretrieveById($identifier);

publicfunctionretrieveByToken($identifier,$token);

publicfunctionupdateRememberToken(Authenticatable$user,$token);

publicfunctionretrieveByCredentials(array$credentials);

publicfunctionvalidateCredentials(Authenticatable$user,array$credentials);

}

TheretrieveByIdfunctiontypicallyreceivesanumerickeyrepresentingtheuser,suchasanauto-incrementingIDfromaMySQLdatabase.TheAuthenticatableimplementationmatchingtheIDshouldberetrievedandreturnedbythemethod.

TheretrieveByTokenfunctionretrievesauserbytheirunique$identifierand"rememberme"$token,storedinafieldremember_token.Aswithwithpreviousmethod,theAuthenticatableimplementationshouldbereturned.

TheupdateRememberTokenmethodupdatesthe$userfieldremember_tokenwiththenew$token.Thenewtokencanbeeitherafreshtoken,assignedonsuccessfull"rememberme"loginattempt,oranullwhenuserisloggedout.

TheretrieveByCredentialsmethodreceivesthearrayofcredentialspassedtotheAuth::attemptmethodwhenattemptingtosignintoanapplication.Themethodshouldthen"query"theunderlyingpersistentstoragefortheusermatchingthosecredentials.Typically,thismethodwillrunaquerywitha"where"conditionon$credentials['username'].Thismethodshouldnotattempttodoanypasswordvalidationorauthentication.

Authentication

Page 116: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ThevalidateCredentialsmethodshouldcomparethegiven$userwiththe$credentialstoauthenticatetheuser.Forexample,thismethodmightcomparethe$user->getAuthPassword()stringtoaHash::makeof$credentials['password'].

NowthatwehaveexploredeachofthemethodsontheUserProvider,let'stakealookattheAuthenticatable.Remember,theprovidershouldreturnimplementationsofthisinterfacefromtheretrieveByIdandretrieveByCredentialsmethods:

interfaceAuthenticatable{

publicfunctiongetAuthIdentifier();

publicfunctiongetAuthPassword();

publicfunctiongetRememberToken();

publicfunctionsetRememberToken($value);

publicfunctiongetRememberTokenName();

}

Thisinterfaceissimple.ThegetAuthIdentifiermethodshouldreturnthe"primarykey"oftheuser.InaMySQLback-end,again,thiswouldbetheauto-incrementingprimarykey.ThegetAuthPasswordshouldreturntheuser'shashedpassword.ThisinterfaceallowstheauthenticationsystemtoworkwithanyUserclass,regardlessofwhatORMorstorageabstractionlayeryouareusing.Bydefault,LaravelincludesaUserclassintheappdirectorywhichimplementsthisinterface,soyoumayconsultthisclassforanimplementationexample.

Finally,oncewehaveimplementedtheUserProvider,wearereadytoregisterourextensionwiththeAuthfacade:

Auth::extend('riak',function($app)

{

returnnewRiakUserProvider($app['riak.connection']);

});

Afteryouhaveregisteredthedriverwiththeextendmethod,youswitchtothenewdriverinyourconfig/auth.phpconfigurationfile.

AlmosteveryserviceproviderincludedwiththeLaravelframeworkbindsobjectsintotheIoCcontainer.Youcanfindalistofyourapplication'sserviceprovidersintheconfig/app.phpconfigurationfile.Asyouhavetime,youshouldskimthrougheachoftheseprovider'ssourcecode.Bydoingso,youwillgainamuchbetterunderstandingofwhateachprovideraddstotheframework,aswellaswhatkeysareusedtobindvariousservicesintotheIoCcontainer.

Forexample,theHashServiceProviderbindsahashkeyintotheIoCcontainer,whichresolvesintoaIlluminate\Hashing\BcryptHasherinstance.YoucaneasilyextendandoverridethisclasswithinyourownapplicationbyoverridingthisIoCbinding.Forexample:

<?phpnamespaceApp\Providers;

classSnappyHashProviderextends\Illuminate\Hashing\HashServiceProvider{

publicfunctionboot()

{

$this->app->bindShared('hash',function()

{

returnnew\Snappy\Hashing\ScryptHasher;

});

parent::boot();

}

}

NotethatthisclassextendstheHashServiceProvider,notthedefaultServiceProviderbaseclass.Onceyouhave

IoCBasedExtension

Page 117: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

extendedtheserviceprovider,swapouttheHashServiceProviderinyourconfig/app.phpconfigurationfilewiththenameofyourextendedprovider.

Thisisthegeneralmethodofextendinganycoreclassthatisboundinthecontainer.Essentiallyeverycoreclassisboundinthecontainerinthisfashion,andcanbeoverridden.Again,readingthroughtheincludedframeworkserviceproviderswillfamiliarizeyouwithwherevariousclassesareboundintothecontainer,andwhatkeystheyareboundby.ThisisagreatwaytolearnmoreabouthowLaravelisputtogether.

Page 118: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionInstallation&SetupUsageGulpExtensions

LaravelElixirprovidesaclean,fluentAPIfordefiningbasicGulptasksforyourLaravelapplication.ElixirsupportsseveralcommonCSSandJavaScriptpre-processors,andeventestingtools.

Ifyou'veeverbeenconfusedabouthowtogetstartedwithGulpandassetcompilation,youwillloveLaravelElixir!

BeforetriggeringElixir,youmustfirstensurethatNode.jsisinstalledonyourmachine.

node-v

Bydefault,LaravelHomesteadincludeseverythingyouneed;however,ifyouaren'tusingVagrant,thenyoucaneasilyinstallNodebyvisitingtheirdownloadpage.Don'tworry,it'squickandeasy!

Next,you'llwanttopullinGulpasaglobalNPMpackagelikeso:

npminstall--globalgulp

TheonlyremainingstepistoinstallElixir!WithanewinstallofLaravel,you'llfindapackage.jsonfileintheroot.Thinkofthislikeyourcomposer.jsonfile,exceptitdefinesNodedependenciesinsteadofPHP.Youmayinstallthedependenciesitreferencesbyrunning:

npminstall

Nowthatyou'veinstalledElixir,you'llbecompilingandconcatenatinginnotime!

elixir(function(mix){

mix.less("app.less");

LaravelElixir

Introduction

Installation&Setup

InstallingNode

Gulp

LaravelElixir

Usage

CompileLess

Page 119: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

});

Intheexampleabove,ElixirassumesthatyourLessfilesarestoredinresources/assets/less.

elixir(function(mix){

mix.sass("app.sass");

});

ThisassumesthatyourSassfilesarestoredinresources/assets/sass.

elixir(function(mix){

mix.coffee();

});

ThisassumesthatyourCoffeeScriptfilesarestoredinresources/assets/coffee.

elixir(function(mix){

mix.less()

.coffee();

});

elixir(function(mix){

mix.phpUnit();

});

elixir(function(mix){

mix.phpSpec();

});

elixir(function(mix){

mix.styles([

"normalize.css",

"main.css"

]);

});

Pathspassedtothismethodarerelativetotheresources/cssdirectory.

elixir(function(mix){

CompileSass

CompileCoffeeScript

CompileAllLessandCoffeeScript

TriggerPHPUnitTests

TriggerPHPSpecTests

CombineStylesheets

CombineStylesheetsandSavetoaCustomDirectory

Page 120: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

mix.styles([

"normalize.css",

"main.css"

],'public/build/css/everything.css');

});

elixir(function(mix){

mix.styles([

"normalize.css",

"main.css"

],'public/build/css/everything.css','public/css');

});

Thethirdargumenttoboththestylesandscriptsmethodsdeterminestherelativedirectoryforallpathspassedtothemethods.

elixir(function(mix){

mix.stylesIn("public/css");

});

elixir(function(mix){

mix.scripts([

"jquery.js",

"app.js"

]);

});

Again,thisassumesallpathsarerelativetotheresources/jsdirectory.

elixir(function(mix){

mix.scriptsIn("public/js/some/directory");

});

elixir(function(mix){

mix.scripts(['jquery.js','main.js'],'public/js/main.js')

.scripts(['forum.js','threads.js'],'public/js/forum.js');

});

elixir(function(mix){

mix.version("css/all.css");

});

Thiswillappendauniquehashtothefilename,allowingforcache-busting.Forexample,thegeneratedfilenamewilllook

CombineStylesheetsFromACustomBaseDirectory

CombineAllStylesinaDirectory

CombineScripts

CombineAllScriptsinaDirectory

CombineMultipleSetsofScripts

Version/HashAFile

Page 121: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

somethinglike:all-16d570a7.css.

Withinyourviews,youmayusetheelixir()functiontoloadtheappropriatelyhashedasset.Here'sanexample:

<linkrel="stylesheet"href="{{elixir("css/all.css")}}">

Behindthescenes,theelixir()functionwilldeterminethenameofthehashedfilethatshouldbeincluded.Don'tyoufeeltheweightliftingoffyourshouldersalready?

elixir(function(mix){

mix.copy('vendor/foo/bar.css','public/css/bar.css');

});

elixir(function(mix){

mix.copy('vendor/package/views','resources/views');

});

Ofcourse,youmaychainalmostallofElixir'smethodstogethertobuildyourrecipe:

elixir(function(mix){

mix.less("app.less")

.coffee()

.phpUnit()

.version("css/bootstrap.css");

});

Nowthatyou'vetoldElixirwhichtaskstoexecute,youonlyneedtotriggerGulpfromthecommandline.

gulp

gulpwatch

gulptdd

Note:Alltaskswillassumeadevelopmentenvironment,andwillexcludeminification.Forproduction,usegulp--

CopyaFiletoaNewLocation

CopyanEntireDirectorytoaNewLocation

MethodChaining

Gulp

ExecuteAllRegisteredTasksOnce

WatchAssetsForChanges

WatchTestsAndPHPClassesforChanges

Page 122: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

production.

YoucanevencreateyourownGulptasks,andhookthemintoElixir.ImaginethatyouwanttoaddafuntaskthatusestheTerminaltoverballynotifyyouwithsomemessage.Here'swhatthatmightlooklike:

vargulp=require("gulp");

varshell=require("gulp-shell");

varelixir=require("laravel-elixir");

elixir.extend("message",function(message){

gulp.task("say",function(){

gulp.src("").pipe(shell("say"+message));

});

returnthis.queueTask("say");

});

NoticethatweextendElixir'sAPIbypassingthekeythatwewillusewithinourGulpfile,aswellasacallbackfunctionthatwillcreatetheGulptask.

Ifyouwantyourcustomtasktobemonitored,thenregisterawatcheraswell.

this.registerWatcher("message","**/*.php");

Thislinesdesignatesthatwhenanyfilethatmatchestheregex,**/*.phpismodified,wewanttotriggerthemessagetask.

That'sit!YoumayeitherplacethisatthetopofyourGulpfile,orinsteadextractittoacustomtasksfile.Ifyouchoosethelatterapproach,simplyrequireitintoyourGulpfile,likeso:

require("./custom-tasks")

You'redone!Now,youcanmixitin.

elixir(function(mix){

mix.message("Tea,EarlGrey,Hot");

});

Withthisaddition,eachtimeyoutriggerGulp,Picardwillrequestsometea.

Extensions

Page 123: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionBasicUsage

LaravelprovidesfacilitiesforstrongAESencryptionviatheMcryptPHPextension.

$encrypted=Crypt::encrypt('secret');

Note:Besuretoseta16,24,or32characterrandomstringinthekeyoptionoftheconfig/app.phpfile.Otherwise,encryptedvalueswillnotbesecure.

$decrypted=Crypt::decrypt($encryptedValue);

Youmayalsosetthecipherandmodeusedbytheencrypter:

Crypt::setMode('ctr');

Crypt::setCipher($cipher);

Encryption

Introduction

BasicUsage

EncryptingAValue

DecryptingAValue

SettingTheCipher&Mode

Page 124: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ConfigurationHandlingErrorsHTTPExceptionsLogging

TheloggingfacilitiesforyourapplicationareconfiguredintheIlluminate\Foundation\Bootstrap\ConfigureLoggingbootstrapperclass.Thisclassutilizesthelogconfigurationoptionfromyourconfig/app.phpconfigurationfile.

Bydefault,theloggerisconfiguredtousedailylogfiles;however,youmaycustomizethisbehaviorasneeded.SinceLaravelusesthepopularMonologlogginglibrary,youcantakeadvantageofthevarietyofhandlersthatMonologoffers.

Forexample,ifyouwishtouseasinglelogfileinsteadofdailyfiles,youcanmakethefollowingchangetoyourconfig/app.phpconfigurationfile:

'log'=>'single'

Outofthebox,Laravelsupportedsingle,daily,andsyslogloggingmodes.However,youarefreetocustomizetheloggingforyourapplicationasyouwishbyoverridingtheConfigureLoggingbootstrapperclass.

Theamountoferrordetailyourapplicationdisplaysthroughthebrowseriscontrolledbytheapp.debugconfigurationoptioninyourconfig/app.phpconfigurationfile.Bydefault,thisconfigurationoptionissettorespecttheAPP_DEBUGenvironmentvariable,whichisstoredinyour.envfile.

Forlocaldevelopment,youshouldsettheAPP_DEBUGenvironmentvariabletotrue.Inyourproductionenvironment,thisvalueshouldalwaysbefalse.

AllexceptionsarehandledbytheApp\Exceptions\Handlerclass.Thisclasscontainstwomethods:reportandrender.

ThereportmethodisusedtologexceptionsorsendthemtoanexternalservicelikeBugSnag.Bydefault,thereportmethodsimplypassestheexceptiontothebaseimplementationontheparentclasswheretheexceptionislogged.However,youarefreetologexceptionshoweveryouwish.Ifyouneedtoreportdifferenttypesofexceptionsindifferentways,youmayusethePHPinstanceofcomparisonoperator:

/**

*Reportorloganexception.

*

*ThisisagreatspottosendexceptionstoSentry,Bugsnag,etc.

*

*@param\Exception$e

*@returnvoid

*/

publicfunctionreport(Exception$e)

{

if($einstanceofCustomException)

{

//

}

Errors&Logging

Configuration

ErrorDetail

HandlingErrors

Page 125: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

returnparent::report($e);

}

TherendermethodisresponsibleforconvertingtheexceptionintoanHTTPresponsethatshouldbesentbacktothebrowser.Bydefault,theexceptionispassedtothebaseclasswhichgeneratesaresponseforyou.However,youarefreetochecktheexceptiontypeorreturnyourowncustomresponse.

ThedontReportpropertyoftheexceptionhandlercontainsanarrayofexceptiontypesthatwillnotbelogged.Bydefault,exceptionsresultingfrom404errorsarenotwrittentoyourlogfiles.Youmayaddotherexceptiontypestothisarrayasneeded.

SomeexceptionsdescribeHTTPerrorcodesfromtheserver.Forexample,thismaybea"pagenotfound"error(404),an"unauthorizederror"(401)orevenadevelopergenerated500error.Inordertoreturnsucharesponse,usethefollowing:

abort(404);

Optionally,youmayprovidearesponse:

abort(403,'Unauthorizedaction.');

Thismethodmaybeusedatanytimeduringtherequest'slifecycle.

Toreturnacustomviewforall404errors,createaresources/views/errors/404.blade.phpfile.Thisviewwillbeservedonall404errorsgeneratedbyyourapplication.

TheLaravelloggingfacilitiesprovideasimplelayerontopofthepowerfulMonologlibrary.Bydefault,Laravelisconfiguredtocreatedailylogfilesforyourapplicationwhicharestoredinthestorage/logsdirectory.Youmaywriteinformationtotheloglikeso:

Log::info('Thisissomeusefulinformation.');

Log::warning('Somethingcouldbegoingwrong.');

Log::error('Somethingisreallygoingwrong.');

TheloggerprovidesthesevenlogginglevelsdefinedinRFC5424:debug,info,notice,warning,error,critical,andalert.

Anarrayofcontextualdatamayalsobepassedtothelogmethods:

Log::info('Logmessage',['context'=>'Otherhelpfulinformation']);

Monologhasavarietyofadditionalhandlersyoumayuseforlogging.Ifneeded,youmayaccesstheunderlyingMonologinstancebeingusedbyLaravel:

HTTPExceptions

Custom404ErrorPage

Logging

Page 126: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$monolog=Log::getMonolog();

Youmayalsoregisteraneventtocatchallmessagespassedtothelog:

Log::listen(function($level,$message,$context)

{

//

});

RegisteringALogEventListener

Page 127: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

BasicUsageQueuedEventHandlersEventSubscribers

TheLaraveleventfacilitiesprovidesasimpleobserverimplementation,allowingyoutosubscribeandlistenforeventsinyourapplication.Eventclassesaretypicallystoredintheapp/Eventsdirectory,whiletheirhandlersarestoredinapp/Handlers/Events.

YoucangenerateaneweventclassusingtheArtisanCLItool:

phpartisanmake:eventPodcastWasPurchased

TheEventServiceProviderincludedwithyourLaravelapplicationprovidesaconvenientplacetoregisteralleventhandlers.Thelistenpropertycontainsanarrayofallevents(keys)andtheirhandlers(values).Ofcourse,youmayaddasmanyeventstothisarrayasyourapplicationrequires.Forexample,let'saddourPodcastWasPurchasedevent:

/**

*Theeventhandlermappingsfortheapplication.

*

*@vararray

*/

protected$listen=[

'App\Events\PodcastWasPurchased'=>[

'App\Handlers\Events\EmailPurchaseConfirmation@handle',

],

];

Togenerateahandlerforanevent,usethehandler:eventArtisanCLIcommand:

phpartisanhandler:eventEmailPurchaseConfirmation--event=PodcastWasPurchased

Ofcourse,manuallyrunningthemake:eventandhandler:eventcommandseachtimeyouneedahandleroreventiscumbersome.Instead,simplyaddhandlersandeventstoyourEventServiceProviderandusetheevent:generatecommand.ThiscommandwillgenerateanyeventsorhandlersthatarelistedinyourEventServiceProvider:

phpartisanevent:generate

NowwearereadytofireoureventusingtheEventfacade:

$response=Event::fire(newPodcastWasPurchased($podcast));

Thefiremethodreturnsanarrayofresponsesthatyoucanusetocontrolwhathappensnextinyourapplication.

Events

BasicUsage

SubscribingToAnEvent

FiringAnEvent

Page 128: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Youmayalsousetheeventhelpertofireanevent:

event(newPodcastWasPurchased($podcast));

Youcanevenlistentoeventswithoutcreatingaseparatehandlerclassatall.Forexample,inthebootmethodofyourEventServiceProvider,youcoulddothefollowing:

Event::listen('App\Events\PodcastWasPurchased',function($event)

{

//Handletheevent...

});

Sometimes,youmaywishtostopthepropagationofaneventtootherlisteners.Youmaydosousingbyreturningfalsefromyourhandler:

Event::listen('App\Events\PodcastWasPurchased',function($event)

{

//Handletheevent...

returnfalse;

});

Needtoqueueaneventhandler?Itcouldn'tbeanyeasier.Whengeneratingthehandler,simplyusethe--queuedflag:

phpartisanhandler:eventSendPurchaseConfirmation--event=PodcastWasPurchased--queued

ThiswillgenerateahandlerclassthatimplementstheIlluminate\Contracts\Queue\ShouldBeQueuedinterface.That'sit!Nowwhenthishandleriscalledforanevent,itwillbequeuedautomaticallybytheeventdispatcher.

Ifnoexceptionsarethrownwhenthehandlerisexecutedbythequeue,thequeuedjobwillbedeletedautomaticallyafterithasprocessed.Ifyouneedtoaccessthequeuedjob'sdeleteandreleasemethodsmanually,youmaydoso.TheIlluminate\Queue\InteractsWithQueuetrait,whichisincludedbydefaultonqueuedhandlers,givesyouaccesstothesemethods:

publicfunctionhandle(PodcastWasPurchased$event)

{

if(true)

{

$this->release(30);

}

}

Ifyouhaveanexistinghandlerthatyouwouldliketoconverttoaqueuedhandler,simplyaddtheShouldBeQueuedinterfacetotheclassmanually.

ClosureListeners

StoppingThePropagationOfAnEvent

QueuedEventHandlers

EventSubscribers

Page 129: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Eventsubscribersareclassesthatmaysubscribetomultipleeventsfromwithintheclassitself.Subscribersshoulddefineasubscribemethod,whichwillbepassedaneventdispatcherinstance:

classUserEventHandler{

/**

*Handleuserloginevents.

*/

publicfunctiononUserLogin($event)

{

//

}

/**

*Handleuserlogoutevents.

*/

publicfunctiononUserLogout($event)

{

//

}

/**

*Registerthelistenersforthesubscriber.

*

*@paramIlluminate\Events\Dispatcher$events

*@returnarray

*/

publicfunctionsubscribe($events)

{

$events->listen('App\Events\UserLoggedIn','UserEventHandler@onUserLogin');

$events->listen('App\Events\UserLoggedOut','UserEventHandler@onUserLogout');

}

}

Oncethesubscriberhasbeendefined,itmayberegisteredwiththeEventclass.

$subscriber=newUserEventHandler;

Event::subscribe($subscriber);

YoumayalsousetheLaravelIoCcontainertoresolveyoursubscriber.Todoso,simplypassthenameofyoursubscribertothesubscribemethod:

Event::subscribe('UserEventHandler');

DefiningAnEventSubscriber

RegisteringAnEventSubscriber

Page 130: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionConfigurationBasicUsage

LaravelprovidesawonderfulfilesystemabstractionthankstotheFlysystemPHPpackagebyFrankdeJonge.TheLaravelFlysystemintegrationprovidessimpletousedriversforworkingwithlocalfilesystems,AmazonS3,andRackspaceCloudStorage.Evenbetter,it'samazinglysimpletoswitchbetweenthesestorageoptionsastheAPIremainsthesameforeachsystem!

Thefilesystemconfigurationfileislocatedatconfig/filesystems.php.Withinthisfileyoumayconfigureallofyour"disks".Eachdiskrepresentsaparticularstoragedriverandstoragelocation.Exampleconfigurationsforeachsupporteddriverisincludedintheconfigurationfile.So,simplymodifytheconfigurationtoreflectyourstoragepreferencesandcredentials!

BeforeusingtheS3orRackspacedrivers,youwillneedtoinstalltheappropriatepackageviaComposer:

AmazonS3:league/flysystem-aws-s3-v2~1.0Rackspace:league/flysystem-rackspace~1.0

Ofcourse,youmayconfigureasmanydisksasyoulike,andmayevenhavemultipledisksthatusethesamedriver.

Whenusingthelocaldriver,notethatallfileoperationsarerelativetotherootdirectorydefinedinyourconfigurationfile.Bydefault,thisvalueissettothestorage/appdirectory.Therefore,thefollowingmethodwouldstoreafileinstorage/app/file.txt:

Storage::disk('local')->put('file.txt','Contents');

TheStoragefacademaybeusedtointeractwithanyofyourconfigureddisks.Alternatively,youmaytype-hinttheIlluminate\Contracts\Filesystem\FactorycontractonanyclassthatisresolvedviatheIoCcontainer.

$disk=Storage::disk('s3');

$disk=Storage::disk('local');

$exists=Storage::disk('s3')->exists('file.jpg');

Filesystem/CloudStorage

Introduction

Configuration

BasicUsage

RetrievingAParticularDisk

DeterminingIfAFileExists

CallingMethodsOnTheDefaultDisk

Page 131: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

if(Storage::exists('file.jpg'))

{

//

}

$contents=Storage::get('file.jpg');

Storage::put('file.jpg',$contents);

Storage::prepend('file.log','PrependedText');

Storage::append('file.log','AppendedText');

Storage::delete('file.jpg');

Storage::delete(['file1.jpg','file2.jpg']);

Storage::copy('old/file1.jpg','new/file1.jpg');

Storage::move('old/file1.jpg','new/file1.jpg');

$size=Storage::size('file1.jpg');

$time=Storage::lastModified('file1.jpg');

RetrievingAFile'sContents

SettingAFile'sContents

PrependToAFile

AppendToAFile

DeleteAFile

CopyAFileToANewLocation

MoveAFileToANewLocation

GetFileSize

GetTheLastModificationTime(UNIX)

GetAllFilesWithinADirectory

Page 132: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$files=Storage::files($directory);

//Recursive...

$files=Storage::allFiles($directory);

$directories=Storage::directories($directory);

//Recursive...

$directories=Storage::allDirectories($directory);

Storage::makeDirectory($directory);

Storage::deleteDirectory($directory);

GetAllDirectoriesWithinADirectory

CreateADirectory

DeleteADirectory

Page 133: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionBasicUsage

TheLaravelHashfacadeprovidessecureBcrypthashingforstoringuserpasswords.IfyouareusingtheAuthControllercontrollerthatisincludedwithyourLaravelapplication,itwillbetakecareofverifyingtheBcryptpasswordagainsttheun-hashedversionprovidedbytheuser.

Likewise,theuserRegistrarservicethatshipswithLaravelmakestheproperbcryptfunctioncalltohashstoredpasswords.

$password=Hash::make('secret');

Youmayalsousethebcrypthelperfunction:

$password=bcrypt('secret');

if(Hash::check('secret',$hashedPassword))

{

//Thepasswordsmatch...

}

if(Hash::needsRehash($hashed))

{

$hashed=Hash::make('secret');

}

Hashing

Introduction

BasicUsage

HashingAPasswordUsingBcrypt

VerifyingAPasswordAgainstAHash

CheckingIfAPasswordNeedsToBeRehashed

Page 134: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ArraysPathsStringsURLsMiscellaneous

Thearray_addfunctionaddsagivenkey/valuepairtothearrayifthegivenkeydoesn'talreadyexistinthearray.

$array=array('foo'=>'bar');

$array=array_add($array,'key','value');

Thearray_dividefunctionreturnstwoarrays,onecontainingthekeys,andtheothercontainingthevaluesoftheoriginalarray.

$array=array('foo'=>'bar');

list($keys,$values)=array_divide($array);

Thearray_dotfunctionflattensamulti-dimensionalarrayintoasinglelevelarraythatuses"dot"notationtoindicatedepth.

$array=array('foo'=>array('bar'=>'baz'));

$array=array_dot($array);

//array('foo.bar'=>'baz');

Thearray_exceptmethodremovesthegivenkey/valuepairsfromthearray.

$array=array_except($array,array('keys','to','remove'));

Thearray_fetchmethodreturnsaflattenedarraycontainingtheselectednestedelement.

$array=array(

array('developer'=>array('name'=>'Taylor')),

array('developer'=>array('name'=>'Dayle')),

);

HelperFunctions

Arrays

array_add

array_divide

array_dot

array_except

array_fetch

Page 135: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$array=array_fetch($array,'developer.name');

//array('Taylor','Dayle');

Thearray_firstmethodreturnsthefirstelementofanarraypassingagiventruthtest.

$array=array(100,200,300);

$value=array_first($array,function($key,$value)

{

return$value>=150;

});

Adefaultvaluemayalsobepassedasthethirdparameter:

$value=array_first($array,$callback,$default);

Thearray_lastmethodreturnsthelastelementofanarraypassingagiventruthtest.

$array=array(350,400,500,300,200,100);

$value=array_last($array,function($key,$value)

{

return$value>350;

});

//500

Adefaultvaluemayalsobepassedasthethirdparameter:

$value=array_last($array,$callback,$default);

Thearray_flattenmethodwillflattenamulti-dimensionalarrayintoasinglelevel.

$array=array('name'=>'Joe','languages'=>array('PHP','Ruby'));

$array=array_flatten($array);

//array('Joe','PHP','Ruby');

Thearray_forgetmethodwillremoveagivenkey/valuepairfromadeeplynestedarrayusing"dot"notation.

$array=array('names'=>array('joe'=>array('programmer')));

array_forget($array,'names.joe');

array_first

array_last

array_flatten

array_forget

array_get

Page 136: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Thearray_getmethodwillretrieveagivenvaluefromadeeplynestedarrayusing"dot"notation.

$array=array('names'=>array('joe'=>array('programmer')));

$value=array_get($array,'names.joe');

$value=array_get($array,'names.john','default');

Note:Wantsomethinglikearray_getbutforobjectsinstead?Useobject_get.

Thearray_onlymethodwillreturnonlythespecifiedkey/valuepairsfromthearray.

$array=array('name'=>'Joe','age'=>27,'votes'=>1);

$array=array_only($array,array('name','votes'));

Thearray_pluckmethodwillpluckalistofthegivenkey/valuepairsfromthearray.

$array=array(array('name'=>'Taylor'),array('name'=>'Dayle'));

$array=array_pluck($array,'name');

//array('Taylor','Dayle');

Thearray_pullmethodwillreturnagivenkey/valuepairfromthearray,aswellasremoveit.

$array=array('name'=>'Taylor','age'=>27);

$name=array_pull($array,'name');

Thearray_setmethodwillsetavaluewithinadeeplynestedarrayusing"dot"notation.

$array=array('names'=>array('programmer'=>'Joe'));

array_set($array,'names.editor','Taylor');

Thearray_sortmethodsortsthearraybytheresultsofthegivenClosure.

$array=array(

array('name'=>'Jill'),

array('name'=>'Barry'),

);

$array=array_values(array_sort($array,function($value)

{

return$value['name'];

}));

array_only

array_pluck

array_pull

array_set

array_sort

Page 137: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

FilterthearrayusingthegivenClosure.

$array=array(100,'200',300,'400',500);

$array=array_where($array,function($key,$value)

{

returnis_string($value);

});

//Array([1]=>200[3]=>400)

Returnthefirstelementinthearray.UsefulformethodchaininginPHP5.3.x.

$first=head($this->returnsArray('foo'));

Returnthelastelementinthearray.Usefulformethodchaining.

$last=last($this->returnsArray('foo'));

Getthefullyqualifiedpathtotheappdirectory.

$path=app_path();

Getthefullyqualifiedpathtotherootoftheapplicationinstall.

Getthefullyqualifiedpathtothepublicdirectory.

Getthefullyqualifiedpathtothestoragedirectory.

ConvertthegivenstringtocamelCase.

array_where

head

last

Paths

app_path

base_path

public_path

storage_path

Strings

camel_case

Page 138: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$camel=camel_case('foo_bar');

//fooBar

Gettheclassnameofthegivenclass,withoutanynamespacenames.

$class=class_basename('Foo\Bar\Baz');

//Baz

Runhtmlentitiesoverthegivenstring,withUTF-8support.

$entities=e('<html>foo</html>');

Determineifthegivenhaystackendswithagivenneedle.

$value=ends_with('Thisismyname','name');

Convertthegivenstringtosnake_case.

$snake=snake_case('fooBar');

//foo_bar

Limitthenumberofcharactersinastring.

str_limit($value,$limit=100,$end='...')

Example:

$value=str_limit('ThePHPframeworkforwebartisans.',7);

//ThePHP...

Determineifthegivenhaystackbeginswiththegivenneedle.

$value=starts_with('Thisismyname','This');

class_basename

e

ends_with

snake_case

str_limit

starts_with

Page 139: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Determineifthegivenhaystackcontainsthegivenneedle.

$value=str_contains('Thisismyname','my');

Addasingleinstanceofthegivenneedletothehaystack.Removeanyextrainstances.

$string=str_finish('this/string','/');

//this/string/

Determineifagivenstringmatchesagivenpattern.Asterisksmaybeusedtoindicatewildcards.

$value=str_is('foo*','foobar');

Convertastringtoitspluralform(Englishonly).

$plural=str_plural('car');

Generatearandomstringofthegivenlength.

$string=str_random(40);

Convertastringtoitssingularform(Englishonly).

$singular=str_singular('cars');

GenerateaURLfriendly"slug"fromagivenstring.

str_slug($title,$separator);

Example:

$title=str_slug("Laravel5Framework","-");

str_contains

str_finish

str_is

str_plural

str_random

str_singular

str_slug

Page 140: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

//laravel-5-framework

ConvertthegivenstringtoStudlyCase.

$value=studly_case('foo_bar');

//FooBar

Translateagivenlanguageline.AliasofLang::get.

$value=trans('validation.required'):

Translateagivenlanguagelinewithinflection.AliasofLang::choice.

$value=trans_choice('foo.bar',$count);

GenerateaURLforagivencontrolleraction.

$url=action('HomeController@getIndex',$params);

GenerateaURLforagivennamedroute.

$url=route('routeName',$params);

GenerateaURLforanasset.

$url=asset('img/photo.jpg');

GenerateaHTMLlinktothegivenURL.

echolink_to('foo/bar',$title,$attributes=array(),$secure=null);

studly_case

trans

trans_choice

URLs

action

route

asset

link_to

Page 141: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

GenerateaHTMLlinktothegivenasset.

echolink_to_asset('foo/bar.zip',$title,$attributes=array(),$secure=null);

GenerateaHTMLlinktothegivenroute.

echolink_to_route('route.name',$title,$parameters=array(),$attributes=array());

GenerateaHTMLlinktothegivencontrolleraction.

echolink_to_action('HomeController@getIndex',$title,$parameters=array(),$attributes=array());

GenerateaHTMLlinktothegivenassetusingHTTPS.

echosecure_asset('foo/bar.zip',$title,$attributes=array());

GenerateafullyqualifiedURLtoagivenpathusingHTTPS.

echosecure_url('foo/bar',$parameters=array());

GenerateafullyqualifiedURLtothegivenpath.

echourl('foo/bar',$parameters=array(),$secure=null);

GetthevalueofthecurrentCSRFtoken.

$token=csrf_token();

link_to_asset

link_to_route

link_to_action

secure_asset

secure_url

url

Miscellaneous

csrf_token

dd

Page 142: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Dumpthegivenvariableandendexecutionofthescript.

dd($value);

IfthegivenvalueisaClosure,returnthevaluereturnedbytheClosure.Otherwise,returnthevalue.

$value=value(function(){return'bar';});

Returnthegivenobject.UsefulformethodchainingconstructorsinPHP5.3.x.

$value=with(newFoo)->doWork();

value

with

Page 143: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionLanguageFilesBasicUsagePluralizationValidationLocalizationOverridingPackageLanguageFiles

TheLaravelLangfacadeprovidesaconvenientwayofretrievingstringsinvariouslanguages,allowingyoutoeasilysupportmultiplelanguageswithinyourapplication.

Languagestringsarestoredinfileswithintheresources/langdirectory.Withinthisdirectorythereshouldbeasubdirectoryforeachlanguagesupportedbytheapplication.

/resources

/lang

/en

messages.php

/es

messages.php

Languagefilessimplyreturnanarrayofkeyedstrings.Forexample:

<?php

returnarray(

'welcome'=>'Welcometoourapplication'

);

Thedefaultlanguageforyourapplicationisstoredintheconfig/app.phpconfigurationfile.YoumaychangetheactivelanguageatanytimeusingtheApp::setLocalemethod:

App::setLocale('es');

Youmayalsoconfigurea"fallbacklanguage",whichwillbeusedwhentheactivelanguagedoesnotcontainagivenlanguageline.Likethedefaultlanguage,thefallbacklanguageisalsoconfiguredintheconfig/app.phpconfigurationfile:

'fallback_locale'=>'en',

Localization

Introduction

LanguageFiles

ExampleLanguageFile

ChangingTheDefaultLanguageAtRuntime

SettingTheFallbackLanguage

Page 144: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

echoLang::get('messages.welcome');

Thefirstsegmentofthestringpassedtothegetmethodisthenameofthelanguagefile,andthesecondisthenameofthelinethatshouldberetrieved.

Note:Ifalanguagelinedoesnotexist,thekeywillbereturnedbythegetmethod.

Youmayalsousethetranshelperfunction,whichisanaliasfortheLang::getmethod.

echotrans('messages.welcome');

Youmayalsodefineplace-holdersinyourlanguagelines:

'welcome'=>'Welcome,:name',

Then,passasecondargumentofreplacementstotheLang::getmethod:

echoLang::get('messages.welcome',array('name'=>'Dayle'));

if(Lang::has('messages.welcome'))

{

//

}

Pluralizationisacomplexproblem,asdifferentlanguageshaveavarietyofcomplexrulesforpluralization.Youmayeasilymanagethisinyourlanguagefiles.Byusinga"pipe"character,youmayseparatethesingularandpluralformsofastring:

'apples'=>'Thereisoneapple|Therearemanyapples',

YoumaythenusetheLang::choicemethodtoretrievetheline:

echoLang::choice('messages.apples',10);

Youmayalsosupplyalocaleargumenttospecifythelanguage.Forexample,ifyouwanttousetheRussian(ru)language:

echoLang::choice('товар|товара|товаров',$count,array(),'ru');

BasicUsage

RetrievingLinesFromALanguageFile

MakingReplacementsInLines

DetermineIfALanguageFileContainsALine

Pluralization

Page 145: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

SincetheLaraveltranslatorispoweredbytheSymfonyTranslationcomponent,youmayalsocreatemoreexplicitpluralizationruleseasily:

'apples'=>'{0}Therearenone|[1,19]Therearesome|[20,Inf]Therearemany',

Forlocalizationforvalidationerrorsandmessages,takealookatthedocumentationonValidation.

Manypackagesshipwiththeirownlanguagelines.Insteadofhackingthepackage'scorefilestotweaktheselines,youmayoverridethembyplacingfilesintheresources/lang/packages/{locale}/{package}directory.So,forexample,ifyouneedtooverridetheEnglishlanguagelinesinmessages.phpforapackagenamedskyrim/hearthfire,youwouldplacealanguagefileat:resources/lang/packages/en/hearthfire/messages.php.Inthisfileyouwoulddefineonlythelanguagelinesyouwishtooverride.Anylanguagelinesyoudon'toverridewillstillbeloadedfromthepackage'slanguagefiles.

Validation

OverridingPackageLanguageFiles

Page 146: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ConfigurationBasicUsageEmbeddingInlineAttachmentsQueueingMailMail&LocalDevelopment

Laravelprovidesaclean,simpleAPIoverthepopularSwiftMailerlibrary.Themailconfigurationfileisconfig/mail.php,andcontainsoptionsallowingyoutochangeyourSMTPhost,port,andcredentials,aswellassetaglobalfromaddressforallmessagesdeliveredbythelibrary.YoumayuseanySMTPserveryouwish.IfyouwishtousethePHPmailfunctiontosendmail,youmaychangethedrivertomailintheconfigurationfile.Asendmaildriverisalsoavailable.

LaravelalsoincludesdriversfortheMailgunandMandrillHTTPAPIs.TheseAPIsareoftensimplerandquickerthantheSMTPservers.BothofthesedriversrequirethattheGuzzle4HTTPlibrarybeinstalledintoyourapplication.YoucanaddGuzzle4toyourprojectbyaddingthefollowinglinetoyourcomposer.jsonfile:

"guzzlehttp/guzzle":"~4.0"

TousetheMailgundriver,setthedriveroptiontomailguninyourconfig/mail.phpconfigurationfile.Next,createanconfig/services.phpconfigurationfileifonedoesnotalreadyexistforyourproject.Verifythatitcontainsthefollowingoptions:

'mailgun'=>array(

'domain'=>'your-mailgun-domain',

'secret'=>'your-mailgun-key',

),

TousetheMandrilldriver,setthedriveroptiontomandrillinyourconfig/mail.phpconfigurationfile.Next,createanconfig/services.phpconfigurationfileifonedoesnotalreadyexistforyourproject.Verifythatitcontainsthefollowingoptions:

'mandrill'=>array(

'secret'=>'your-mandrill-key',

),

Ifthedriveroptionofyourconfig/mail.phpconfigurationfileissettolog,alle-mailswillbewrittentoyourlogfiles,andwillnotactuallybesenttoanyoftherecipients.Thisisprimarilyusefulforquick,localdebuggingandcontentverification.

Mail

Configuration

APIDrivers

MailgunDriver

MandrillDriver

LogDriver

BasicUsage

Page 147: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

TheMail::sendmethodmaybeusedtosendane-mailmessage:

Mail::send('emails.welcome',array('key'=>'value'),function($message)

{

$message->to('[email protected]','JohnSmith')->subject('Welcome!');

});

Thefirstargumentpassedtothesendmethodisthenameoftheviewthatshouldbeusedasthee-mailbody.Thesecondisthedatatobepassedtotheview,oftenasanassociativearraywherethedataitemsareavailabletotheviewby$key.ThethirdisaClosureallowingyoutospecifyvariousoptionsonthee-mailmessage.

Note:A$messagevariableisalwayspassedtoe-mailviews,andallowstheinlineembeddingofattachments.So,itisbesttoavoidpassingamessagevariableinyourviewpayload.

YoumayalsospecifyaplaintextviewtouseinadditiontoanHTMLview:

Mail::send(array('html.view','text.view'),$data,$callback);

Or,youmayspecifyonlyonetypeofviewusingthehtmlortextkeys:

Mail::send(array('text'=>'view'),$data,$callback);

Youmayspecifyotheroptionsonthee-mailmessagesuchasanycarboncopiesorattachmentsaswell:

Mail::send('emails.welcome',$data,function($message)

{

$message->from('[email protected]','Laravel');

$message->to('[email protected]')->cc('[email protected]');

$message->attach($pathToFile);

});

Whenattachingfilestoamessage,youmayalsospecifyaMIMEtypeand/oradisplayname:

$message->attach($pathToFile,array('as'=>$display,'mime'=>$mime));

Ifyoujustneedtoe-mailasimplestringinsteadofanentireview,usetherawmethod:

Mail::raw('Texttoe-mail',function($message)

{

$message->from('[email protected]','Laravel');

$message->to('[email protected]')->cc('[email protected]');

});

Note:ThemessageinstancepassedtoaMail::sendClosureextendstheSwiftMailermessageclass,allowingyoutocallanymethodonthatclasstobuildyoure-mailmessages.

Embeddinginlineimagesintoyoure-mailsistypicallycumbersome;however,Laravelprovidesaconvenientwaytoattachimagestoyoure-mailsandretrievingtheappropriateCID.

EmbeddingInlineAttachments

Page 148: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

<body>

Hereisanimage:

<imgsrc="<?phpecho$message->embed($pathToFile);?>">

</body>

<body>

Hereisanimagefromrawdata:

<imgsrc="<?phpecho$message->embedData($data,$name);?>">

</body>

Notethatthe$messagevariableisalwayspassedtoe-mailviewsbytheMailfacade.

Sincesendinge-mailmessagescandrasticallylengthentheresponsetimeofyourapplication,manydeveloperschoosetoqueuee-mailmessagesforbackgroundsending.Laravelmakesthiseasyusingitsbuilt-inunifiedqueueAPI.Toqueueamailmessage,simplyusethequeuemethodontheMailfacade:

Mail::queue('emails.welcome',$data,function($message)

{

$message->to('[email protected]','JohnSmith')->subject('Welcome!');

});

Youmayalsospecifythenumberofsecondsyouwishtodelaythesendingofthemailmessageusingthelatermethod:

Mail::later(5,'emails.welcome',$data,function($message)

{

$message->to('[email protected]','JohnSmith')->subject('Welcome!');

});

Ifyouwishtospecifyaspecificqueueor"tube"onwhichtopushthemessage,youmaydosousingthequeueOnandlaterOnmethods:

Mail::queueOn('queue-name','emails.welcome',$data,function($message)

{

$message->to('[email protected]','JohnSmith')->subject('Welcome!');

});

Whendevelopinganapplicationthatsendse-mail,it'susuallydesirabletodisablethesendingofmessagesfromyourlocalordevelopmentenvironment.Todoso,youmayeithercalltheMail::pretendmethod,orsetthepretendoptionintheconfig/mail.phpconfigurationfiletotrue.Whenthemailerisinpretendmode,messageswillbewrittentoyourapplication'slogfilesinsteadofbeingsenttotherecipient.

Ifyouwouldliketoactuallyviewtheteste-mails,considerusingaservicelikeMailTrap.

EmbeddingAnImageInAnE-MailView

EmbeddingRawDataInAnE-MailView

QueueingMail

QueueingAMailMessage

Mail&LocalDevelopment

Page 149: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better
Page 150: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionViewsTranslationsConfigurationPublishingFileGroupsRouting

PackagesaretheprimarywayofaddingfunctionalitytoLaravel.PackagesmightbeanythingfromagreatwaytoworkwithdateslikeCarbon,oranentireBDDtestingframeworklikeBehat.

Ofcourse,therearedifferenttypesofpackages.Somepackagesarestand-alone,meaningtheyworkwithanyframework,notjustLaravel.BothCarbonandBehatareexamplesofstand-alonepackages.AnyofthesepackagesmaybeusedwithLaravelbysimplyrequestingtheminyourcomposer.jsonfile.

Ontheotherhand,otherpackagesarespecificallyintendedforusewithLaravel.Thesepackagesmayhaveroutes,controllers,views,andconfigurationspecificallyintendedtoenhanceaLaravelapplication.ThisguideprimarilycoversthedevelopmentofthosethatareLaravelspecific.

AllLaravelpackagesaredistributedviaPackagistandComposer,solearningaboutthesewonderfulPHPpackagedistributiontoolsisessential.

Yourpackage'sinternalstructureisentirelyuptoyou;however,typicallyeachpackagewillcontainoneormoreserviceproviders.TheserviceprovidercontainsanyIoCbindings,aswellasinstructionsastowherepackageconfiguration,views,andtranslationfilesarelocated.

Packageviewsaretypicallyreferencedusingadouble-colon"namespace"syntax:

returnview('package::view.name');

AllyouneedtodoistellLaravelwheretheviewsforagivennamespacearelocated.Forexample,ifyourpackageisnamed"courier",youmightaddthefollowingtoyourserviceprovider'sbootmethod:

publicfunctionboot()

{

$this->loadViewsFrom(__DIR__.'/path/to/views','courier');

}

Nowyoumayloadyourpackageviewsusingthefollowingsyntax:

returnview('courier::view.name');

WhenyouusetheloadViewsFrommethod,Laravelactuallyregisterstwolocationsforyourviews:oneintheapplication'sresources/views/vendordirectoryandoneinthedirectoryyouspecify.So,usingourcourierexample:whenrequestinga

PackageDevelopment

Introduction

Views

Views

Page 151: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

packageview,Laravelwillfirstcheckifacustomversionoftheviewhasbeenprovidedbythedeveloperinresources/views/vendor/courier.Then,iftheviewhasnotbeencustomized,LaravelwillsearchthepackageviewdirectoryyouspecifiedinyourcalltoloadViewsFrom.Thismakesiteasyforend-userstocustomize/overrideyourpackage'sviews.

Topublishyourpackage'sviewstotheresources/views/vendordirectory,youshouldusethepublishesmethodfromthebootmethodofyourserviceprovider:

publicfunctionboot()

{

$this->loadViewsFrom(__DIR__.'/path/to/views','courier');

$this->publishes([

__DIR__.'/path/to/views'=>base_path('resources/views/vendor/courier'),

]);

}

Now,whenusersofyourpackageexecuteLaravel'svendor:publishcommand,yourviewsdirectorywillbecopiedtothespecifiedlocation.

Ifyouwouldliketooverwriteexistingfiles,usethe--forceswitch:

phpartisanvendor:publish--force

Note:Youmayusethepublishesmethodtopublishanytypeoffiletoanylocationyouwish.

Packagetranslationfilesaretypicallyreferencedusingadouble-colonsyntax:

returntrans('package::file.line');

AllyouneedtodoistellLaravelwherethetranslationsforagivennamespacearelocated.Forexample,ifyourpackageisnamed"courier",youmightaddthefollowingtoyourserviceprovider'sbootmethod:

publicfunctionboot()

{

$this->loadTranslationsFrom(__DIR__.'/path/to/translations','courier');

}

Notethatwithinyourtranslationsfolder,youwouldhavefurtherdirectoriesforeachlanguage,suchasen,es,ru,etc.

Nowyoumayloadyourpackagetranslationsusingthefollowingsyntax:

returntrans('courier::file.line');

Typically,youwillwanttopublishyourpackage'sconfigurationfiletotheapplication'sownconfigdirectory.Thiswillallowusersofyourpackagetoeasilyoverrideyourdefaultconfigurationoptions.

Topublishaconfigurationfile,justusethepublishesmethodfromthebootmethodofyourserviceprovider:

PublishingViews

Translations

Configuration

Page 152: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$this->publishes([

__DIR__.'/path/to/config/courier.php'=>config_path('courier.php'),

]);

Now,whenusersofyourpackageexecuteLaravel'svendor:publishcommand,yourfilewillbecopiedtothespecifiedlocation.Ofcourse,onceyourconfigurationhasbeenpublished,itcanbeaccessedlikeanyotherconfigurationfile:

$value=config('courier.option');

Youmayalsochoosetomergeyourownpackageconfigurationfilewiththeapplication'scopy.Thisallowsyouruserstoincludeonlytheoptionstheyactuallywanttooverrideinthepublishedcopyoftheconfiguration.Tomergetheconfigurations,usethemergeConfigFrommethodwithinyourserviceprovider'sregistermethod:

$this->mergeConfigFrom(

__DIR__.'/path/to/config/courier.php','courier'

);

Youmaywanttopublishgroupsoffilesseparately.Forinstance,youmightwantyouruserstobeabletopublishyourpackage'sconfigurationfilesandassetfilesseparately.Youcandothisby'tagging'them:

//Publishaconfigfile

$this->publishes([

__DIR__.'/../config/package.php',config_path('package.php')

],'config');

//Publishyourmigrations

$this->publishes([

__DIR__.'/../database/migrations/'=>base_path('/database/migrations')

],'migrations');

Youcanthenpublishthesefilesseparatelybyreferencingtheirtaglikeso:

phpartisanvendor:publish--provider="Vendor\Providers\PackageServiceProvider"--tag="config"

Toloadaroutesfileforyourpackage,simplyincludeitfromwithinyourserviceprovider'sbootmethod.

publicfunctionboot()

{

include__DIR__.'/../../routes.php';

}

Note:Ifyourpackageisusingcontrollers,youwillneedtomakesuretheyareproperlyconfiguredinyourcomposer.jsonfile'sauto-loadsection.

PublishingFileGroups

Routing

IncludingARoutesFileFromAServiceProvider

Page 153: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ConfigurationUsageAppendingToPaginationLinksConvertingToJSON

Inotherframeworks,paginationcanbeverypainful.Laravelmakesitabreeze.Laravelcangenerateanintelligent"range"oflinksbasedonthecurrentpage.ThegeneratedHTMLiscompatiblewiththeBootstrapCSSframework.

Thereareseveralwaystopaginateitems.ThesimplestisbyusingthepaginatemethodonthequerybuilderoranEloquentmodel.

$users=DB::table('users')->paginate(15);

Note:Currently,paginationoperationsthatuseagroupBystatementcannotbeexecutedefficientlybyLaravel.IfyouneedtouseagroupBywithapaginatedresultset,itisrecommendedthatyouquerythedatabaseandcreateapaginatormanually.

Sometimesyoumaywishtocreateapaginationinstancemanually,passingitanarrayofitems.YoumaydosobycreatingeitheranIlluminate\Pagination\PaginatororIlluminate\Pagination\LengthAwarePaginatorinstance,dependingonyourneeds.

YoumayalsopaginateEloquentmodels:

$allUsers=User::paginate(15);

$someUsers=User::where('votes','>',100)->paginate(15);

Theargumentpassedtothepaginatemethodisthenumberofitemsyouwishtodisplayperpage.Onceyouhaveretrievedtheresults,youmaydisplaythemonyourview,andcreatethepaginationlinksusingtherendermethod:

<divclass="container">

<?phpforeach($usersas$user):?>

<?phpecho$user->name;?>

<?phpendforeach;?>

</div>

<?phpecho$users->render();?>

Thisisallittakestocreateapaginationsystem!Notethatwedidnothavetoinformtheframeworkofthecurrentpage.Laravelwilldeterminethisforyouautomatically.

Pagination

Configuration

Usage

PaginatingDatabaseResults

CreatingAPaginatorManually

PaginatingAnEloquentModel

Page 154: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Youmayalsoaccessadditionalpaginationinformationviathefollowingmethods:

currentPage

lastPage

perPage

total

count

Ifyouareonlyshowing"Next"and"Previous"linksinyourpaginationview,youhavetheoptionofusingthesimplePaginatemethodtoperformamoreefficientquery.Thisisusefulforlargerdatasetswhenyoudonotrequirethedisplayofexactpagenumbersonyourview:

$someUsers=User::where('votes','>',100)->simplePaginate(15);

YoumayalsocustomizetheURIusedbythepaginatorviathesetPathmethod:

$users=User::paginate();

$users->setPath('custom/url');

TheexampleabovewillcreateURLslikethefollowing:http://example.com/custom/url?page=2

YoucanaddtothequerystringofpaginationlinksusingtheappendsmethodonthePaginator:

<?phpecho$users->appends(['sort'=>'votes'])->render();?>

ThiswillgenerateURLsthatlooksomethinglikethis:

http://example.com/something?page=2&sort=votes

Ifyouwishtoappenda"hashfragment"tothepaginator'sURLs,youmayusethefragmentmethod:

<?phpecho$users->fragment('foo')->render();?>

ThismethodcallwillgenerateURLsthatlooksomethinglikethis:

http://example.com/something?page=2#foo

ThePaginatorclassimplementstheIlluminate\Contracts\Support\JsonableInterfacecontractandexposesthetoJsonmethod.YoumayalsoconvertaPaginatorinstancetoJSONbyreturningitfromaroute.TheJSON'dformoftheinstancewillincludesome"meta"informationsuchastotal,current_page,andlast_page.Theinstance'sdatawillbeavailable

"SimplePagination"

CustomizingThePaginatorURI

AppendingToPaginationLinks

ConvertingToJSON

Page 155: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

viathedatakeyintheJSONarray.

Page 156: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ConfigurationBasicUsageQueueingClosuresRunningTheQueueListenerDaemonQueueWorkerPushQueuesFailedJobs

TheLaravelQueuecomponentprovidesaunifiedAPIacrossavarietyofdifferentqueueservices.Queuesallowyoutodefertheprocessingofatimeconsumingtask,suchassendingane-mail,untilalatertime,thusdrasticallyspeedingupthewebrequeststoyourapplication.

Thequeueconfigurationfileisstoredinconfig/queue.php.Inthisfileyouwillfindconnectionconfigurationsforeachofthequeuedriversthatareincludedwiththeframework,whichincludesadatabase,Beanstalkd,IronMQ,AmazonSQS,Redis,null,andsynchronous(forlocaluse)driver.Thenullqueuedriversimplydiscardsqueuedjobssotheyareneverrun.

Inordertousethedatabasequeuedriver,youwillneedadatabasetabletoholdthejobs.Togenerateamigrationtocreatethistable,runthequeue:tableArtisancommand:

phpartisanqueue:table

Thefollowingdependenciesareneededforthelistedqueuedrivers:

AmazonSQS:aws/aws-sdk-phpBeanstalkd:pda/pheanstalk~3.0IronMQ:iron-io/iron_mqRedis:predis/predis~1.0

AllofthequeueablejobsforyourapplicationarestoredintheApp\Commandsdirectory.YoumaygenerateanewqueuedcommandusingtheArtisanCLI:

phpartisanmake:commandSendEmail--queued

Topushanewjobontothequeue,usetheQueue::pushmethod:

Queue::push(newSendEmail($message));

Queues

Configuration

QueueDatabaseTable

OtherQueueDependencies

BasicUsage

PushingAJobOntoTheQueue

Page 157: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Note:Inthisexample,weareusingtheQueuefacadedirectly;however,typicallyyouwoulddispatchqueuedcommandviatheCommandBus.WewillcontinuetousetheQueuefacadethroughoutthispage;however,familiarizewiththecommandbusaswell,sinceitisusedtodispatchbothqueuedandsynchronouscommandsforyourapplication.

Bydefault,themake:commandArtisancommandgeneratesa"self-handling"command,meaningahandlemethodisaddedtothecommanditself.Thismethodwillbecalledwhenthejobisexecutedbythequeue.Youmaytype-hintanydependenciesyouneedonthehandlemethodandtheIoCcontainerwillautomaticallyinjectthem:

publicfunctionhandle(UserRepository$users)

{

//

}

Ifyouwouldlikeyourcommandtohaveaseparatehandlerclass,youshouldaddthe--handlerflagtothemake:commandcommand:

phpartisanmake:commandSendEmail--queued--handler

ThegeneratedhandlerwillbeplacedinApp\Handlers\CommandsandwillberesolvedoutoftheIoCcontainer.

Youmayalsospecifythequeue/tubeajobshouldbesentto:

Queue::pushOn('emails',newSendEmail($message));

Ifyouneedtopassthesamedatatoseveralqueuejobs,youmayusetheQueue::bulkmethod:

Queue::bulk(array(newSendEmail($message),newAnotherCommand));

Sometimesyoumaywishtodelaytheexecutionofaqueuedjob.Forinstance,youmaywishtoqueueajobthatsendsacustomerane-mail15minutesaftersign-up.YoucanaccomplishthisusingtheQueue::latermethod:

$date=Carbon::now()->addMinutes(15);

Queue::later($date,newSendEmail($message));

Inthisexample,we'reusingtheCarbondatelibrarytospecifythedelaywewishtoassigntothejob.Alternatively,youmaypassthenumberofsecondsyouwishtodelayasaninteger.

Note:TheAmazonSQSservicehasadelaylimitof900seconds(15minutes).

IfyourqueuedjobacceptsanEloquentmodelinitsconstructor,onlytheidentifierforthemodelwillbeserializedontothequeue.Whenthejobisactuallyhandled,thequeuesystemwillautomaticallyre-retrievethefullmodelinstancefromthedatabase.It'salltotallytransparenttoyourapplicationandpreventsissuesthatcanarisefromserializingfullEloquent

SpecifyingTheQueue/TubeForAJob

PassingTheSamePayloadToMultipleJobs

DelayingTheExecutionOfAJob

QueuesAndEloquentModels

Page 158: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

modelinstances.

Onceyouhaveprocessedajob,itmustbedeletedfromthequeue.Ifnoexceptionisthrownduringtheexecutionofyourjob,thiswillbedoneautomatically.

Ifyouwouldliketodeleteorreleasethejobmanually,theIlluminate\Queue\InteractsWithQueuetraitprovidesaccesstothequeuejobreleaseanddeletemethods.Thereleasemethodacceptsasinglevalue:thenumberofsecondsyouwishtowaituntilthejobismadeavailableagain.

publicfunctionhandle(SendEmail$command)

{

if(true)

{

$this->release(30);

}

}

IFanexceptionisthrownwhilethejobisbeingprocessed,itwillautomaticallybereleasedbackontothequeuesoitmaybeattemptedagain.Thejobwillcontinuetobereleaseduntilithasbeenattemptedthemaximumnumberoftimesallowedbyyourapplication.Thenumberofmaximumattemptsisdefinedbythe--triesswitchusedonthequeue:listenorqueue:workArtisancommands.

Ifanexceptionoccurswhilethejobisbeingprocessed,itwillautomaticallybereleasedbackontothequeue.Youmaycheckthenumberofattemptsthathavebeenmadetorunthejobusingtheattemptsmethod:

if($this->attempts()>3)

{

//

}

Note:Yourcommand/handlermustusetheIlluminate\Queue\InteractsWithQueuetraitinordertocallthismethod.

YoumayalsopushaClosureontothequeue.Thisisveryconvenientforquick,simpletasksthatneedtobequeued:

Queue::push(function($job)use($id)

{

Account::delete($id);

$job->delete();

});

Note:InsteadofmakingobjectsavailabletoqueuedClosuresviatheusedirective,considerpassingprimarykeysandre-pullingtheassociatedmodelsfromwithinyourqueuejob.Thisoftenavoidsunexpectedserializationbehavior.

WhenusingIron.iopushqueues,youshouldtakeextraprecautionqueueingClosures.Theend-pointthatreceivesyourqueuemessagesshouldcheckforatokentoverifythattherequestisactuallyfromIron.io.Forexample,yourpushqueueend-pointshouldbesomethinglike:https://yourapp.com/queue/receive?token=SecretToken.Youmaythencheckthevalue

DeletingAProcessedJob

ReleasingAJobBackOntoTheQueue

CheckingTheNumberOfRunAttempts

QueueingClosures

PushingAClosureOntoTheQueue

Page 159: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ofthesecrettokeninyourapplicationbeforemarshallingthequeuerequest.

LaravelincludesanArtisantaskthatwillrunnewjobsastheyarepushedontothequeue.Youmayrunthistaskusingthequeue:listencommand:

phpartisanqueue:listen

Youmayalsospecifywhichqueueconnectionthelistenershouldutilize:

phpartisanqueue:listenconnection

Notethatoncethistaskhasstarted,itwillcontinuetorununtilitismanuallystopped.YoumayuseaprocessmonitorsuchasSupervisortoensurethatthequeuelistenerdoesnotstoprunning.

Youmaypassacomma-delimitedlistofqueueconnectionstothelistencommandtosetqueuepriorities:

phpartisanqueue:listen--queue=high,low

Inthisexample,jobsonthehigh-connectionwillalwaysbeprocessedbeforemovingontojobsfromthelow-connection.

Youmayalsosetthelengthoftime(inseconds)eachjobshouldbeallowedtorun:

phpartisanqueue:listen--timeout=60

Inaddition,youmayspecifythenumberofsecondstowaitbeforepollingfornewjobs:

phpartisanqueue:listen--sleep=5

Notethatthequeueonly"sleeps"ifnojobsareonthequeue.Ifmorejobsareavailable,thequeuewillcontinuetoworkthemwithoutsleeping.

Toprocessonlythefirstjobonthequeue,youmayusethequeue:workcommand:

phpartisanqueue:work

Thequeue:workalsoincludesa--daemonoptionforforcingthequeueworkertocontinueprocessingjobswithouteverre-

RunningTheQueueListener

StartingTheQueueListener

SpecifyingTheJobTimeoutParameter

SpecifyingQueueSleepDuration

ProcessingTheFirstJobOnTheQueue

DaemonQueueWorker

Page 160: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

bootingtheframework.ThisresultsinasignificantreductionofCPUusagewhencomparedtothequeue:listencommand,butattheaddedcomplexityofneedingtodrainthequeuesofcurrentlyexecutingjobsduringyourdeployments.

Tostartaqueueworkerindaemonmode,usethe--daemonflag:

phpartisanqueue:workconnection--daemon

phpartisanqueue:workconnection--daemon--sleep=3

phpartisanqueue:workconnection--daemon--sleep=3--tries=3

Asyoucansee,thequeue:workcommandsupportsmostofthesameoptionsavailabletoqueue:listen.Youmayusethephpartisanhelpqueue:workcommandtoviewalloftheavailableoptions.

Thesimplestwaytodeployanapplicationusingdaemonqueueworkersistoputtheapplicationinmaintenancemodeatthebeginningofyourdeployment.Thiscanbedoneusingthephpartisandowncommand.Oncetheapplicationisinmaintenancemode,Laravelwillnotacceptanynewjobsoffofthequeue,butwillcontinuetoprocessexistingjobs.

Theeasiestwaytorestartyourworkersistoincludethefollowingcommandinyourdeploymentscript:

phpartisanqueue:restart

Thiscommandwillinstructallqueueworkerstorestartaftertheyfinishprocessingtheircurrentjob.

Note:Thiscommandreliesonthecachesystemtoscheduletherestart.Bydefault,APCudoesnotworkforCLIcommands.IfyouareusingAPCu,addapc.enable_cli=1toyourAPCuconfiguration.

Daemonqueueworkersdonotrestarttheframeworkbeforeprocessingeachjob.Therefore,youshouldbecarefultofreeanyheavyresourcesbeforeyourjobfinishes.Forexample,ifyouaredoingimagemanipulationwiththeGDlibrary,youshouldfreethememorywithimagedestroywhenyouaredone.

Similarly,yourdatabaseconnectionmaydisconnectwhenbeingusedbylong-runningdaemon.YoumayusetheDB::reconnectmethodtoensureyouhaveafreshconnection.

PushqueuesallowyoutoutilizethepowerfulLaravel4queuefacilitieswithoutrunninganydaemonsorbackgroundlisteners.Currently,pushqueuesareonlysupportedbytheIron.iodriver.Beforegettingstarted,createanIron.ioaccount,andaddyourIroncredentialstotheconfig/queue.phpconfigurationfile.

Next,youmayusethequeue:subscribeArtisancommandtoregisteraURLend-pointthatwillreceivenewlypushedqueuejobs:

phpartisanqueue:subscribequeue_namehttp://foo.com/queue/receive

Now,whenyoulogintoyourIrondashboard,youwillseeyournewpushqueue,aswellasthesubscribedURL.YoumaysubscribeasmanyURLsasyouwishtoagivenqueue.Next,createarouteforyourqueue/receiveend-pointandreturntheresponsefromtheQueue::marshalmethod:

DeployingWithDaemonQueueWorkers

CodingForDaemonQueueWorkers

PushQueues

RegisteringAPushQueueSubscriber

Page 161: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Route::post('queue/receive',function()

{

returnQueue::marshal();

});

Themarshalmethodwilltakecareoffiringthecorrectjobhandlerclass.Tofirejobsontothepushqueue,justusethesameQueue::pushmethodusedforconventionalqueues.

Sincethingsdon'talwaysgoasplanned,sometimesyourqueuedjobswillfail.Don'tworry,ithappenstothebestofus!Laravelincludesaconvenientwaytospecifythemaximumnumberoftimesajobshouldbeattempted.Afterajobhasexceededthisamountofattempts,itwillbeinsertedintoafailed_jobstable.Thefailedjobstablenamecanbeconfiguredviatheconfig/queue.phpconfigurationfile.

Tocreateamigrationforthefailed_jobstable,youmayusethequeue:failed-tablecommand:

phpartisanqueue:failed-table

Youcanspecifythemaximumnumberoftimesajobshouldbeattemptedusingthe--triesswitchonthequeue:listencommand:

phpartisanqueue:listenconnection-name--tries=3

Ifyouwouldliketoregisteraneventthatwillbecalledwhenaqueuejobfails,youmayusetheQueue::failingmethod.Thiseventisagreatopportunitytonotifyyourteamviae-mailorHipChat.

Queue::failing(function($connection,$job,$data)

{

//

});

Youmayalsodefineafailedmethoddirectlyonaqueuejobclass,allowingyoutoperformjobspecificactionswhenafailureoccurs:

publicfunctionfailed()

{

//Calledwhenthejobisfailing...

}

Toviewallofyourfailedjobs,youmayusethequeue:failedArtisancommand:

phpartisanqueue:failed

Thequeue:failedcommandwilllistthejobID,connection,queue,andfailuretime.ThejobIDmaybeusedtoretrythefailedjob.Forinstance,toretryafailedjobthathasanIDof5,thefollowingcommandshouldbeissued:

phpartisanqueue:retry5

FailedJobs

RetryingFailedJobs

Page 162: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Ifyouwouldliketodeleteafailedjob,youmayusethequeue:forgetcommand:

phpartisanqueue:forget5

Todeleteallofyourfailedjobs,youmayusethequeue:flushcommand:

phpartisanqueue:flush

Page 163: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ConfigurationSessionUsageFlashDataDatabaseSessionsSessionDrivers

SinceHTTPdrivenapplicationsarestateless,sessionsprovideawaytostoreinformationabouttheuseracrossrequests.Laravelshipswithavarietyofsessionback-endsavailableforusethroughaclean,unifiedAPI.Supportforpopularback-endssuchasMemcached,Redis,anddatabasesisincludedoutofthebox.

Thesessionconfigurationisstoredinconfig/session.php.Besuretoreviewthewelldocumentedoptionsavailabletoyouinthisfile.Bydefault,Laravelisconfiguredtousethefilesessiondriver,whichwillworkwellforthemajorityofapplications.

BeforeusingRedissessionswithLaravel,youwillneedtoinstallthepredis/predispackage(~1.0)viaComposer.

Note:Ifyouneedallstoredsessiondatatobeencrypted,settheencryptconfigurationoptiontotrue.

TheLaravelframeworkusestheflashsessionkeyinternally,soyoushouldnotaddanitemtothesessionbythatname.

Session::put('key','value');

Session::push('user.teams','developers');

$value=Session::get('key');

$value=Session::get('key','default');

$value=Session::get('key',function(){return'default';});

Session

Configuration

ReservedKeys

SessionUsage

StoringAnItemInTheSession

PushAValueOntoAnArraySessionValue

RetrievingAnItemFromTheSession

RetrievingAnItemOrReturningADefaultValue

RetrievingAnItemAndForgettingIt

Page 164: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$value=Session::pull('key','default');

$data=Session::all();

if(Session::has('users'))

{

//

}

Session::forget('key');

Session::flush();

Session::regenerate();

Sometimesyoumaywishtostoreitemsinthesessiononlyforthenextrequest.YoumaydosousingtheSession::flashmethod:

Session::flash('key','value');

Session::reflash();

Session::keep(array('username','email'));

Whenusingthedatabasesessiondriver,youwillneedtosetupatabletocontainthesessionitems.BelowisanexampleSchemadeclarationforthetable:

RetrievingAllDataFromTheSession

DeterminingIfAnItemExistsInTheSession

RemovingAnItemFromTheSession

RemovingAllItemsFromTheSession

RegeneratingTheSessionID

FlashData

ReflashingTheCurrentFlashDataForAnotherRequest

ReflashingOnlyASubsetOfFlashData

DatabaseSessions

Page 165: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Schema::create('sessions',function($table)

{

$table->string('id')->unique();

$table->text('payload');

$table->integer('last_activity');

});

Ofcourse,youmayusethesession:tableArtisancommandtogeneratethismigrationforyou!

phpartisansession:table

composerdump-autoload

phpartisanmigrate

Thesession"driver"defineswheresessiondatawillbestoredforeachrequest.Laravelshipswithseveralgreatdriversoutofthebox:

file-sessionswillbestoredinapp/storage/sessions.cookie-sessionswillbestoredinsecure,encryptedcookies.database-sessionswillbestoredinadatabaseusedbyyourapplication.memcached/redis-sessionswillbestoredinoneofthesefast,cachedbasedstores.array-sessionswillbestoredinasimplePHParrayandwillnotbepersistedacrossrequests.

Note:Thearraydriveristypicallyusedforrunningunittests,sonosessiondatawillbepersisted.

SessionDrivers

Page 166: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

BladeTemplatingOtherBladeControlStructuresExtendingBlade

Bladeisasimple,yetpowerfultemplatingengineprovidedwithLaravel.Unlikecontrollerlayouts,Bladeisdrivenbytemplateinheritanceandsections.AllBladetemplatesshouldusethe.blade.phpextension.

<!--Storedinresources/views/layouts/master.blade.php-->

<html>

<body>

@section('sidebar')

Thisisthemastersidebar.

@show

<divclass="container">

@yield('content')

</div>

</body>

</html>

@extends('layouts.master')

@section('sidebar')

@@parent

<p>Thisisappendedtothemastersidebar.</p>

@stop

@section('content')

<p>Thisismybodycontent.</p>

@stop

NotethatviewswhichextendaBladelayoutsimplyoverridesectionsfromthelayout.Contentofthelayoutcanbeincludedinachildviewusingthe@@parentdirectiveinasection,allowingyoutoappendtothecontentsofalayoutsectionsuchasasidebarorfooter.

Sometimes,suchaswhenyouarenotsureifasectionhasbeendefined,youmaywishtopassadefaultvaluetothe@yielddirective.Youmaypassthedefaultvalueasthesecondargument:

@yield('section','DefaultContent')

Hello,{{$name}}.

Templates

BladeTemplating

DefiningABladeLayout

UsingABladeLayout

OtherBladeControlStructures

EchoingData

Page 167: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ThecurrentUNIXtimestampis{{time()}}.

Sometimesyoumaywishtoechoavariable,butyouaren'tsureifthevariablehasbeenset.Basically,youwanttodothis:

{{isset($name)?$name:'Default'}}

However,insteadofwritingaternarystatement,Bladeallowsyoutousethefollowingconvenientshort-cut:

{{$nameor'Default'}}

Ifyouneedtodisplayastringthatiswrappedincurlybraces,youmayescapetheBladebehaviorbyprefixingyourtextwithan@symbol:

@{{ThiswillnotbeprocessedbyBlade}}

Ifyoudon'twantthedatatobeescaped,youmayusethefollowingsyntax:

Hello,{!!$name!!}.

Note:Beverycarefulwhenechoingcontentthatissuppliedbyusersofyourapplication.AlwaysusethedoublecurlybracesyntaxtoescapeanyHTMLentitiesinthecontent.

@if(count($records)===1)

Ihaveonerecord!

@elseif(count($records)>1)

Ihavemultiplerecords!

@else

Idon'thaveanyrecords!

@endif

@unless(Auth::check())

Youarenotsignedin.

@endunless

@for($i=0;$i<10;$i++)

Thecurrentvalueis{{$i}}

@endfor

@foreach($usersas$user)

<p>Thisisuser{{$user->id}}</p>

@endforeach

@forelse($usersas$user)

<li>{{$user->name}}</li>

@empty

<p>Nousers</p>

@endforelse

EchoingDataAfterCheckingForExistence

DisplayingRawTextWithCurlyBraces

IfStatements

Loops

Page 168: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

@while(true)

<p>I'mloopingforever.</p>

@endwhile

@include('view.name')

Youmayalsopassanarrayofdatatotheincludedview:

@include('view.name',['some'=>'data'])

Tooverwriteasectionentirely,youmayusetheoverwritestatement:

@extends('list.item.container')

@section('list.item.content')

<p>Thisisanitemoftype{{$item->type}}</p>

@overwrite

@lang('language.line')

@choice('language.line',1)

{{--ThiscommentwillnotbeintherenderedHTML--}}

Bladeevenallowsyoutodefineyourowncustomcontrolstructures.WhenaBladefileiscompiled,eachcustomextensioniscalledwiththeviewcontents,allowingyoutodoanythingfromsimplestr_replacemanipulationstomorecomplexregularexpressions.

TheBladecompilercomeswiththehelpermethodscreateMatcherandcreatePlainMatcher,whichgeneratetheexpressionyouneedtobuildyourowncustomdirectives.

ThecreatePlainMatchermethodisusedfordirectiveswithnoargumentslike@endifand@stop,whilecreateMatcherisusedfordirectiveswitharguments.

Thefollowingexamplecreatesa@datetime($var)directivewhichsimplycalls->format()on$var:

Blade::extend(function($view,$compiler)

{

$pattern=$compiler->createMatcher('datetime');

returnpreg_replace($pattern,'$1<?phpecho$2->format(\'m/d/YH:i\');?>',$view);

});

IncludingSub-Views

OverwritingSections

DisplayingLanguageLines

Comments

ExtendingBlade

Page 169: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better
Page 170: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionDefining&RunningTestsTestEnvironmentCallingRoutesFromTestsMockingFacadesFrameworkAssertionsHelperMethodsRefreshingTheApplication

Laravelisbuiltwithunittestinginmind.Infact,supportfortestingwithPHPUnitisincludedoutofthebox,andaphpunit.xmlfileisalreadysetupforyourapplication.

Anexampletestfileisprovidedinthetestsdirectory.AfterinstallinganewLaravelapplication,simplyrunphpunitonthecommandlinetorunyourtests.

Tocreateatestcase,simplycreateanewtestfileinthetestsdirectory.ThetestclassshouldextendTestCase.YoumaythendefinetestmethodsasyounormallywouldwhenusingPHPUnit.

classFooTestextendsTestCase{

publicfunctiontestSomethingIsTrue()

{

$this->assertTrue(true);

}

}

Youmayrunallofthetestsforyourapplicationbyexecutingthephpunitcommandfromyourterminal.

Note:IfyoudefineyourownsetUpmethod,besuretocallparent::setUp.

Whenrunningunittests,Laravelwillautomaticallysettheconfigurationenvironmenttotesting.Also,Laravelincludesconfigurationfilesforsessionandcacheinthetestenvironment.Bothofthesedriversaresettoarraywhileinthetestenvironment,meaningnosessionorcachedatawillbepersistedwhiletesting.Youarefreetocreateothertestingenvironmentconfigurationsasnecessary.

Thetestingenvironmentvariablesmaybeconfiguredinthephpunit.xmlfile.

Testing

Introduction

Defining&RunningTests

AnExampleTestClass

TestEnvironment

CallingRoutesFromTests

CallingARouteFromATest

Page 171: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Youmayeasilycalloneofyourroutesforatestusingthecallmethod:

$response=$this->call('GET','user/profile');

$response=$this->call($method,$uri,$parameters,$files,$server,$content);

YoumaytheninspecttheIlluminate\Http\Responseobject:

$this->assertEquals('HelloWorld',$response->getContent());

Youmayalsocallacontrollerfromatest:

$response=$this->action('GET','HomeController@index');

$response=$this->action('GET','UserController@profile',array('user'=>1));

Note:Youdonotneedtospecifythefullcontrollernamespacewhenusingtheactionmethod.OnlyspecifytheportionoftheclassnamethatfollowstheApp\Http\Controllersnamespace.

ThegetContentmethodwillreturntheevaluatedstringcontentsoftheresponse.IfyourroutereturnsaView,youmayaccessitusingtheoriginalproperty:

$view=$response->original;

$this->assertEquals('John',$view['name']);

TocallaHTTPSroute,youmayusethecallSecuremethod:

$response=$this->callSecure('GET','foo/bar');

Whentesting,youmayoftenwanttomockacalltoaLaravelstaticfacade.Forexample,considerthefollowingcontrolleraction:

publicfunctiongetIndex()

{

Event::fire('foo',['name'=>'Dayle']);

return'Alldone!';

}

WecanmockthecalltotheEventclassbyusingtheshouldReceivemethodonthefacade,whichwillreturnaninstanceofaMockerymock.

publicfunctiontestGetIndex()

{

Event::shouldReceive('fire')->once()->with('foo',['name'=>'Dayle']);

CallingAControllerFromATest

MockingFacades

MockingAFacade

Page 172: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$this->call('GET','/');

}

Note:YoushouldnotmocktheRequestfacade.Instead,passtheinputyoudesireintothecallmethodwhenrunningyourtest.

Laravelshipswithseveralassertmethodstomaketestingalittleeasier:

publicfunctiontestMethod()

{

$this->call('GET','/');

$this->assertResponseOk();

}

$this->assertResponseStatus(403);

$this->assertRedirectedTo('foo');

$this->assertRedirectedToRoute('route.name');

$this->assertRedirectedToAction('Controller@method');

publicfunctiontestMethod()

{

$this->call('GET','/');

$this->assertViewHas('name');

$this->assertViewHas('age',$value);

}

publicfunctiontestMethod()

{

$this->call('GET','/');

$this->assertSessionHas('name');

$this->assertSessionHas('age',$value);

}

publicfunctiontestMethod()

{

FrameworkAssertions

AssertingResponsesAreOK

AssertingResponseStatuses

AssertingResponsesAreRedirects

AssertingAViewHasSomeData

AssertingTheSessionHasSomeData

AssertingTheSessionHasErrors

Page 173: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$this->call('GET','/');

$this->assertSessionHasErrors();

//Assertingthesessionhaserrorsforagivenkey...

$this->assertSessionHasErrors('name');

//Assertingthesessionhaserrorsforseveralkeys...

$this->assertSessionHasErrors(array('name','age'));

}

publicfunctiontestMethod()

{

$this->call('GET','/');

$this->assertHasOldInput();

}

TheTestCaseclasscontainsseveralhelpermethodstomaketestingyourapplicationeasier.

$this->session(['foo'=>'bar']);

$this->flushSession();

Youmaysetthecurrentlyauthenticateduserusingthebemethod:

$user=newUser(array('name'=>'John'));

$this->be($user);

Youmayre-seedyourdatabasefromatestusingtheseedmethod:

$this->seed();

$this->seed($connection);

Moreinformationoncreatingseedsmaybefoundinthemigrationsandseedingsectionofthedocumentation.

Asyoumayalreadyknow,youcanaccessyourLaravelApplication/IoCContainervia$this->appfromanytestmethod.ThisApplicationinstanceisrefreshedforeachtestclass.IfyouwishtomanuallyforcetheApplicationtoberefreshedforagivenmethod,youmayusetherefreshApplicationmethodfromyourtestmethod.Thiswillresetanyextrabindings,suchasmocks,thathavebeenplacedintheIoCcontainersincethetestcasestartedrunning.

AssertingOldInputHasSomeData

HelperMethods

SettingAndFlushingSessionsFromTests

SettingTheCurrentlyAuthenticatedUser

Re-SeedingDatabaseFromTests

RefreshingTheApplication

Page 174: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

BasicUsageControllerValidationFormRequestValidationWorkingWithErrorMessagesErrorMessages&ViewsAvailableValidationRulesConditionallyAddingRulesCustomErrorMessagesCustomValidationRules

Laravelshipswithasimple,convenientfacilityforvalidatingdataandretrievingvalidationerrormessagesviatheValidationclass.

$validator=Validator::make(

array('name'=>'Dayle'),

array('name'=>'required|min:5')

);

Thefirstargumentpassedtothemakemethodisthedataundervalidation.Thesecondargumentisthevalidationrulesthatshouldbeappliedtothedata.

Multiplerulesmaybedelimitedusingeithera"pipe"character,orasseparateelementsofanarray.

$validator=Validator::make(

array('name'=>'Dayle'),

array('name'=>array('required','min:5'))

);

$validator=Validator::make(

array(

'name'=>'Dayle',

'password'=>'lamepassword',

'email'=>'[email protected]'

),

array(

'name'=>'required',

'password'=>'required|min:8',

'email'=>'required|email|unique:users'

)

);

OnceaValidatorinstancehasbeencreated,thefails(orpasses)methodmaybeusedtoperformthevalidation.

if($validator->fails())

{

Validation

BasicUsage

BasicValidationExample

UsingArraysToSpecifyRules

ValidatingMultipleFields

Page 175: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

//Thegivendatadidnotpassvalidation

}

Ifvalidationhasfailed,youmayretrievetheerrormessagesfromthevalidator.

$messages=$validator->messages();

Youmayalsoaccessanarrayofthefailedvalidationrules,withoutmessages.Todoso,usethefailedmethod:

$failed=$validator->failed();

TheValidatorclassprovidesseveralrulesforvalidatingfiles,suchassize,mimes,andothers.Whenvalidatingfiles,youmaysimplypassthemintothevalidatorwithyourotherdata.

Thevalidatoralsoallowsyoutoattachcallbackstoberunaftervalidationiscompleted.Thisallowsyoutoeasilyperformfurthervalidation,andevenaddmoreerrormessagestothemessagecollection.Togetstarted,usetheaftermethodonavalidatorinstance:

$validator=Validator::make(...);

$validator->after(function($validator)

{

if($this->somethingElseIsInvalid())

{

$validator->errors()->add('field','Somethingiswrongwiththisfield!');

}

});

if($validator->fails())

{

//

}

Youmayaddasmanyaftercallbackstoavalidatorasneeded.

Ofcourse,manuallycreatingandcheckingaValidatorinstanceeachtimeyoudovalidationisaheadache.Don'tworry,youhaveotheroptions!ThebaseApp\Http\Controllers\ControllerclassincludedwithLaravelusesaValidatesRequeststrait.Thistraitprovidesasingle,convenientmethodforvalidatingincomingHTTPrequests.Here'swhatitlookslike:

/**

*Storetheincomingblogpost.

*

*@paramRequest$request

*@returnResponse

*/

publicfunctionstore(Request$request)

{

$this->validate($request,[

'title'=>'required|unique|max:255',

'body'=>'required',

]);

//

}

ValidatingFiles

AfterValidationHook

ControllerValidation

Page 176: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Ifvalidationpasses,yourcodewillkeepexecutingnormally.However,ifvalidationfails,anIlluminate\Contracts\Validation\ValidationExceptionwillbethrown.Thisexceptionisautomaticallycaughtandaredirectisgeneratedtotheuser'spreviouslocation.Thevalidationerrorsareevenautomaticallyflashedtothesession!

IftheincomingrequestwasanAJAXrequest,noredirectwillbegenerated.Instead,anHTTPresponsewitha422statuscodewillbereturnedtothebrowsercontainingaJSONrepresentationofthevalidationerrors.

Forexample,hereistheequivalentcodewrittenmanually:

/**

*Storetheincomingblogpost.

*

*@paramRequest$request

*@returnResponse

*/

publicfunctionstore(Request$request)

{

$v=Validator::make($request->all(),[

'title'=>'required|unique|max:255',

'body'=>'required',

]);

if($v->fails())

{

returnredirect()->back()->withErrors($v->errors());

}

//

}

Ifyouwishtocustomizetheformatofthevalidationerrorsthatareflashedtothesessionwhenvalidationfails,overridetheformatValidationErrorsonyourbasecontroller.Don'tforgettoimporttheIlluminate\Validation\Validatorclassatthetopofthefile:

/**

*{@inheritdoc}

*/

protectedfunctionformatValidationErrors(Validator$validator)

{

return$validator->errors()->all();

}

Formorecomplexvalidationscenarios,youmaywishtocreatea"formrequest".Formrequestsarecustomrequestclassesthatcontainvalidationlogic.Tocreateaformrequestclass,usethemake:requestArtisanCLIcommand:

phpartisanmake:requestStoreBlogPostRequest

Thegeneratedclasswillbeplacedintheapp/Http/Requestsdirectory.Let'saddafewvalidationrulestotherulesmethod:

/**

*Getthevalidationrulesthatapplytotherequest.

*

*@returnarray

*/

publicfunctionrules()

CustomizingTheFlashedErrorFormat

FormRequestValidation

Page 177: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

{

return[

'title'=>'required|unique|max:255',

'body'=>'required',

];

}

So,howarethevalidationrulesexecuted?Allyouneedtodoistype-hinttherequestonyourcontrollermethod:

/**

*Storetheincomingblogpost.

*

*@paramStoreBlogPostRequest$request

*@returnResponse

*/

publicfunctionstore(StoreBlogPostRequest$request)

{

//Theincomingrequestisvalid...

}

Theincomingformrequestisvalidatedbeforethecontrollermethodiscalled,meaningyoudonotneedtoclutteryourcontrollerwithanyvalidationlogic.Ithasalreadybeenvalidated!

Ifvalidationfails,aredirectresponsewillbegeneratedtosendtheuserbacktotheirpreviouslocation.Theerrorswillalsobeflashedtothesessionsotheyareavailablefordisplay.IftherequestwasanAJAXrequest,aHTTPresponsewitha422statuscodewillbereturnedtotheuserincludingaJSONrepresentationofthevalidationerrors.

Theformrequestclassalsocontainsanauthorizemethod.Withinthismethod,youmaycheckiftheauthenticateduseractuallyhastheauthoritytoupdateagivenresource.Forexample,ifauserisattemptingtoupdateablogpostcomment,dotheyactuallyownthatcomment?Forexample:

/**

*Determineiftheuserisauthorizedtomakethisrequest.

*

*@returnbool

*/

publicfunctionauthorize()

{

$commentId=$this->route('comment');

returnComment::where('id',$commentId)

->where('user_id',Auth::id())->exists();

}

Notethecalltotheroutemethodintheexampleabove.ThismethodgrantsyouaccesstotheURIparametersdefinedontheroutebeingcalled,suchasthe{comment}parameterintheexamplebelow:

Route::post('comment/{comment}');

Iftheauthorizemethodreturnsfalse,aHTTPresponsewitha403statuscodewillautomaticallybereturnedandyourcontrollermethodwillnotexecute.

Ifyouplantohaveauthorizationlogicinanotherpartofyourapplication,simplyreturntruefromtheauthorizemethod:

/**

*Determineiftheuserisauthorizedtomakethisrequest.

*

*@returnbool

*/

publicfunctionauthorize()

AuthorizingFormRequests

Page 178: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

{

returntrue;

}

Ifyouwishtocustomizetheformatofthevalidationerrorsthatareflashedtothesessionwhenvalidationfails,overridetheformatValidationErrorsonyourbaserequest(App\Http\Requests\Request).Don'tforgettoimporttheIlluminate\Validation\Validatorclassatthetopofthefile:

/**

*{@inheritdoc}

*/

protectedfunctionformatErrors(Validator$validator)

{

return$validator->errors()->all();

}

AftercallingthemessagesmethodonaValidatorinstance,youwillreceiveaMessageBaginstance,whichhasavarietyofconvenientmethodsforworkingwitherrormessages.

echo$messages->first('email');

foreach($messages->get('email')as$message)

{

//

}

foreach($messages->all()as$message)

{

//

}

if($messages->has('email'))

{

//

}

echo$messages->first('email','<p>:message</p>');

CustomizingTheFlashedErrorFormat

WorkingWithErrorMessages

RetrievingTheFirstErrorMessageForAField

RetrievingAllErrorMessagesForAField

RetrievingAllErrorMessagesForAllFields

DeterminingIfMessagesExistForAField

RetrievingAnErrorMessageWithAFormat

Page 179: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Note:Bydefault,messagesareformattedusingBootstrapcompatiblesyntax.

foreach($messages->all('<li>:message</li>')as$message)

{

//

}

Onceyouhaveperformedvalidation,youwillneedaneasywaytogettheerrormessagesbacktoyourviews.ThisisconvenientlyhandledbyLaravel.Considerthefollowingroutesasanexample:

Route::get('register',function()

{

returnView::make('user.register');

});

Route::post('register',function()

{

$rules=array(...);

$validator=Validator::make(Input::all(),$rules);

if($validator->fails())

{

returnredirect('register')->withErrors($validator);

}

});

Notethatwhenvalidationfails,wepasstheValidatorinstancetotheRedirectusingthewithErrorsmethod.Thismethodwillflashtheerrormessagestothesessionsothattheyareavailableonthenextrequest.

However,noticethatwedonothavetoexplicitlybindtheerrormessagestotheviewinourGETroute.ThisisbecauseLaravelwillalwayscheckforerrorsinthesessiondata,andautomaticallybindthemtotheviewiftheyareavailable.So,itisimportanttonotethatan$errorsvariablewillalwaysbeavailableinallofyourviews,oneveryrequest,allowingyoutoconvenientlyassumethe$errorsvariableisalwaysdefinedandcanbesafelyused.The$errorsvariablewillbeaninstanceofMessageBag.

So,afterredirection,youmayutilizetheautomaticallybound$errorsvariableinyourview:

<?phpecho$errors->first('email');?>

Ifyouhavemultipleformsonasinglepage,youmaywishtonametheMessageBagoferrors.Thiswillallowyoutoretrievetheerrormessagesforaspecificform.SimplypassanameasthesecondargumenttowithErrors:

returnredirect('register')->withErrors($validator,'login');

YoumaythenaccessthenamedMessageBaginstancefromthe$errorsvariable:

<?phpecho$errors->login->first('email');?>

RetrievingAllErrorMessagesWithAFormat

ErrorMessages&Views

NamedErrorBags

Page 180: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Belowisalistofallavailablevalidationrulesandtheirfunction:

AcceptedActiveURLAfter(Date)AlphaAlphaDashAlphaNumericArrayBefore(Date)BetweenBooleanConfirmedDateDateFormatDifferentDigitsDigitsBetweenE-MailExists(Database)Image(File)InIntegerIPAddressMaxMIMETypesMinNotInNumericRegularExpressionRequiredRequiredIfRequiredWithRequiredWithAllRequiredWithoutRequiredWithoutAllSameSizeStringTimezoneUnique(Database)URL

Thefieldundervalidationmustbeyes,on,or1.Thisisusefulforvalidating"TermsofService"acceptance.

ThefieldundervalidationmustbeavalidURLaccordingtothecheckdnsrrPHPfunction.

Thefieldundervalidationmustbeavalueafteragivendate.ThedateswillbepassedintothePHPstrtotimefunction.

AvailableValidationRules

accepted

active_url

after:date

Page 181: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Thefieldundervalidationmustbeentirelyalphabeticcharacters.

Thefieldundervalidationmayhavealpha-numericcharacters,aswellasdashesandunderscores.

Thefieldundervalidationmustbeentirelyalpha-numericcharacters.

Thefieldundervalidationmustbeoftypearray.

Thefieldundervalidationmustbeavalueprecedingthegivendate.ThedateswillbepassedintothePHPstrtotimefunction.

Thefieldundervalidationmusthaveasizebetweenthegivenminandmax.Strings,numerics,andfilesareevaluatedinthesamefashionasthesizerule.

Thefieldundervalidationmustbeabletobecastasaboolean.Acceptedinputaretrue,false,1,0,"1"and"0".

Thefieldundervalidationmusthaveamatchingfieldoffoo_confirmation.Forexample,ifthefieldundervalidationispassword,amatchingpassword_confirmationfieldmustbepresentintheinput.

ThefieldundervalidationmustbeavaliddateaccordingtothestrtotimePHPfunction.

Thefieldundervalidationmustmatchtheformatdefinedaccordingtothedate_parse_from_formatPHPfunction.

Thegivenfieldmustbedifferentthanthefieldundervalidation.

Thefieldundervalidationmustbenumericandmusthaveanexactlengthofvalue.

Thefieldundervalidationmusthavealengthbetweenthegivenminandmax.

alpha

alpha_dash

alpha_num

array

before:date

between:min,max

boolean

confirmed

date

dateformat:_format

different:field

digits:value

digitsbetween:_min,max

email

Page 182: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Thefieldundervalidationmustbeformattedasane-mailaddress.

Thefieldundervalidationmustexistonagivendatabasetable.

'state'=>'exists:states'

'state'=>'exists:states,abbreviation'

Youmayalsospecifymoreconditionsthatwillbeaddedas"where"clausestothequery:

'email'=>'exists:staff,email,account_id,1'

PassingNULLasa"where"clausevaluewilladdacheckforaNULLdatabasevalue:

'email'=>'exists:staff,email,deleted_at,NULL'

Thefileundervalidationmustbeanimage(jpeg,png,bmp,gif,orsvg)

Thefieldundervalidationmustbeincludedinthegivenlistofvalues.

Thefieldundervalidationmusthaveanintegervalue.

ThefieldundervalidationmustbeformattedasanIPaddress.

Thefieldundervalidationmustbelessthanorequaltoamaximumvalue.Strings,numerics,andfilesareevaluatedinthesamefashionasthesizerule.

ThefileundervalidationmusthaveaMIMEtypecorrespondingtooneofthelistedextensions.

'photo'=>'mimes:jpeg,bmp,png'

exists:table,column

BasicUsageOfExistsRule

SpecifyingACustomColumnName

image

in:foo,bar,...

integer

ip

max:value

mimes:foo,bar,...

BasicUsageOfMIMERule

Page 183: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Thefieldundervalidationmusthaveaminimumvalue.Strings,numerics,andfilesareevaluatedinthesamefashionasthesizerule.

Thefieldundervalidationmustnotbeincludedinthegivenlistofvalues.

Thefieldundervalidationmusthaveanumericvalue.

Thefieldundervalidationmustmatchthegivenregularexpression.

Note:Whenusingtheregexpattern,itmaybenecessarytospecifyrulesinanarrayinsteadofusingpipedelimiters,especiallyiftheregularexpressioncontainsapipecharacter.

Thefieldundervalidationmustbepresentintheinputdata.

Thefieldundervalidationmustbepresentifthefieldfieldisequaltoanyvalue.

Thefieldundervalidationmustbepresentonlyifanyoftheotherspecifiedfieldsarepresent.

Thefieldundervalidationmustbepresentonlyifalloftheotherspecifiedfieldsarepresent.

Thefieldundervalidationmustbepresentonlywhenanyoftheotherspecifiedfieldsarenotpresent.

Thefieldundervalidationmustbepresentonlywhenalloftheotherspecifiedfieldsarenotpresent.

Thegivenfieldmustmatchthefieldundervalidation.

Thefieldundervalidationmusthaveasizematchingthegivenvalue.Forstringdata,valuecorrespondstothenumberofcharacters.Fornumericdata,valuecorrespondstoagivenintegervalue.Forfiles,sizecorrespondstothefilesizeinkilobytes.

Thefieldundervalidationmustbeastringtype.

min:value

notin:_foo,bar,...

numeric

regex:pattern

required

requiredif:_field,value,...

requiredwith:_foo,bar,...

requiredwith_all:_foo,bar,...

requiredwithout:_foo,bar,...

requiredwithout_all:_foo,bar,...

same:field

size:value

string:value

Page 184: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Thefieldundervalidationmustbeavalidtimezoneidentifieraccordingtothetimezone_identifiers_listPHPfunction.

Thefieldundervalidationmustbeuniqueonagivendatabasetable.Ifthecolumnoptionisnotspecified,thefieldnamewillbeused.

'email'=>'unique:users'

'email'=>'unique:users,email_address'

'email'=>'unique:users,email_address,10'

Youmayalsospecifymoreconditionsthatwillbeaddedas"where"clausestothequery:

'email'=>'unique:users,email_address,NULL,id,account_id,1'

Intheruleabove,onlyrowswithanaccount_idof1wouldbeincludedintheuniquecheck.

ThefieldundervalidationmustbeformattedasanURL.

Note:ThisfunctionusesPHP'sfilter_varmethod.

Insomesituations,youmaywishtorunvalidationchecksagainstafieldonlyifthatfieldispresentintheinputarray.Toquicklyaccomplishthis,addthesometimesruletoyourrulelist:

$v=Validator::make($data,array(

'email'=>'sometimes|required|email',

));

Intheexampleabove,theemailfieldwillonlybevalidatedifitispresentinthe$dataarray.

Sometimesyoumaywishtorequireagivenfieldonlyifanotherfieldhasagreatervaluethan100.Oryoumayneedtwofieldstohaveagivenvalueonlywhenanotherfieldispresent.Addingthesevalidationrulesdoesn'thavetobeapain.

timezone

unique:table,column,except,idColumn

BasicUsageOfUniqueRule

SpecifyingACustomColumnName

ForcingAUniqueRuleToIgnoreAGivenID

AddingAdditionalWhereClauses

url

ConditionallyAddingRules

ComplexConditionalValidation

Page 185: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

First,createaValidatorinstancewithyourstaticrulesthatneverchange:

$v=Validator::make($data,array(

'email'=>'required|email',

'games'=>'required|numeric',

));

Let'sassumeourwebapplicationisforgamecollectors.Ifagamecollectorregisterswithourapplicationandtheyownmorethan100games,wewantthemtoexplainwhytheyownsomanygames.Forexample,perhapstheyrunagamere-sellshop,ormaybetheyjustenjoycollecting.Toconditionallyaddthisrequirement,wecanusethesometimesmethodontheValidatorinstance.

$v->sometimes('reason','required|max:500',function($input)

{

return$input->games>=100;

});

Thefirstargumentpassedtothesometimesmethodisthenameofthefieldweareconditionallyvalidating.Thesecondargumentistheruleswewanttoadd.IftheClosurepassedasthethirdargumentreturnstrue,theruleswillbeadded.Thismethodmakesitabreezetobuildcomplexconditionalvalidations.Youmayevenaddconditionalvalidationsforseveralfieldsatonce:

$v->sometimes(array('reason','cost'),'required',function($input)

{

return$input->games>=100;

});

Note:The$inputparameterpassedtoyourClosurewillbeaninstanceofIlluminate\Support\Fluentandmaybeusedasanobjecttoaccessyourinputandfiles.

Ifneeded,youmayusecustomerrormessagesforvalidationinsteadofthedefaults.Thereareseveralwaystospecifycustommessages.

$messages=array(

'required'=>'The:attributefieldisrequired.',

);

$validator=Validator::make($input,$rules,$messages);

Note:The:attributeplace-holderwillbereplacedbytheactualnameofthefieldundervalidation.Youmayalsoutilizeotherplace-holdersinvalidationmessages.

$messages=array(

'same'=>'The:attributeand:othermustmatch.',

'size'=>'The:attributemustbeexactly:size.',

'between'=>'The:attributemustbebetween:min-:max.',

'in'=>'The:attributemustbeoneofthefollowingtypes::values',

);

CustomErrorMessages

PassingCustomMessagesIntoValidator

OtherValidationPlace-Holders

Page 186: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Sometimesyoumaywishtospecifyacustomerrormessagesonlyforaspecificfield:

$messages=array(

'email.required'=>'Weneedtoknowyoure-mailaddress!',

);

Insomecases,youmaywishtospecifyyourcustommessagesinalanguagefileinsteadofpassingthemdirectlytotheValidator.Todoso,addyourmessagestocustomarrayintheresources/lang/xx/validation.phplanguagefile.

'custom'=>array(

'email'=>array(

'required'=>'Weneedtoknowyoure-mailaddress!',

),

),

Laravelprovidesavarietyofhelpfulvalidationrules;however,youmaywishtospecifysomeofyourown.OnemethodofregisteringcustomvalidationrulesisusingtheValidator::extendmethod:

Validator::extend('foo',function($attribute,$value,$parameters)

{

return$value=='foo';

});

ThecustomvalidatorClosurereceivesthreearguments:thenameofthe$attributebeingvalidated,the$valueoftheattribute,andanarrayof$parameterspassedtotherule.

YoumayalsopassaclassandmethodtotheextendmethodinsteadofaClosure:

Validator::extend('foo','FooValidator@validate');

Notethatyouwillalsoneedtodefineanerrormessageforyourcustomrules.Youcandosoeitherusinganinlinecustommessagearrayorbyaddinganentryinthevalidationlanguagefile.

InsteadofusingClosurecallbackstoextendtheValidator,youmayalsoextendtheValidatorclassitself.Todoso,writeaValidatorclassthatextendsIlluminate\Validation\Validator.Youmayaddvalidationmethodstotheclassbyprefixingthemwithvalidate:

<?php

classCustomValidatorextendsIlluminate\Validation\Validator{

publicfunctionvalidateFoo($attribute,$value,$parameters)

{

return$value=='foo';

}

SpecifyingACustomMessageForAGivenAttribute

SpecifyingCustomMessagesInLanguageFiles

CustomValidationRules

RegisteringACustomValidationRule

ExtendingTheValidatorClass

Page 187: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

}

Next,youneedtoregisteryourcustomValidatorextension:

Validator::resolver(function($translator,$data,$rules,$messages)

{

returnnewCustomValidator($translator,$data,$rules,$messages);

});

Whencreatingacustomvalidationrule,youmaysometimesneedtodefinecustomplace-holderreplacementsforerrormessages.YoumaydosobycreatingacustomValidatorasdescribedabove,andaddingareplaceXXXfunctiontothevalidator.

protectedfunctionreplaceFoo($message,$attribute,$rule,$parameters)

{

returnstr_replace(':foo',$parameters[0],$message);

}

Ifyouwouldliketoaddacustommessage"replacer"withoutextendingtheValidatorclass,youmayusetheValidator::replacermethod:

Validator::replacer('rule',function($message,$attribute,$rule,$parameters)

{

//

});

RegisteringACustomValidatorResolver

Page 188: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

BasicUsageConfigurationRead/WriteConnectionsRunningQueriesDatabaseTransactionsAccessingConnectionsQueryLogging

QueryBuilderIntroductionSelectsJoinsAdvancedWheresAggregatesRawExpressionsInsertsUpdatesDeletesUnionsPessimisticLocking

EloquentORMIntroductionBasicUsageMassAssignmentInsert,Update,DeleteSoftDeletingTimestampsQueryScopesGlobalScopesRelationshipsQueryingRelationsEagerLoadingInsertingRelatedModelsTouchingParentTimestampsWorkingWithPivotTablesCollectionsAccessors&MutatorsDateMutatorsAttributeCastingModelEventsModelObserversConvertingToArrays/JSON

SchemaBuilderIntroductionCreating&DroppingTablesAddingColumnsChangingColumnsRenamingColumnsDroppingColumnsCheckingExistenceAddingIndexesForeignKeysDroppingIndexes

Database

Page 189: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

DroppingTimestamps&SoftDeletesStorageEngines

Migrations&SeedingIntroductionCreatingMigrationsRunningMigrationsRollingBackMigrationsDatabaseSeeding

RedisIntroductionConfigurationUsagePipelining

Page 190: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

ConfigurationRead/WriteConnectionsRunningQueriesDatabaseTransactionsAccessingConnectionsQueryLogging

Laravelmakesconnectingwithdatabasesandrunningqueriesextremelysimple.Thedatabaseconfigurationfileisconfig/database.php.Inthisfileyoumaydefineallofyourdatabaseconnections,aswellasspecifywhichconnectionshouldbeusedbydefault.Examplesforallofthesupporteddatabasesystemsareprovidedinthisfile.

CurrentlyLaravelsupportsfourdatabasesystems:MySQL,Postgres,SQLite,andSQLServer.

SometimesyoumaywishtouseonedatabaseconnectionforSELECTstatements,andanotherforINSERT,UPDATE,andDELETEstatements.Laravelmakesthisabreeze,andtheproperconnectionswillalwaysbeusedwhetheryouareusingrawqueries,thequerybuilder,ortheEloquentORM.

Toseehowread/writeconnectionsshouldbeconfigured,let'slookatthisexample:

'mysql'=>[

'read'=>[

'host'=>'192.168.1.1',

],

'write'=>[

'host'=>'196.168.1.2'

],

'driver'=>'mysql',

'database'=>'database',

'username'=>'root',

'password'=>'',

'charset'=>'utf8',

'collation'=>'utf8_unicode_ci',

'prefix'=>'',

],

Notethattwokeyshavebeenaddedtotheconfigurationarray:readandwrite.Bothofthesekeyshavearrayvaluescontainingasinglekey:host.Therestofthedatabaseoptionsforthereadandwriteconnectionswillbemergedfromthemainmysqlarray.So,weonlyneedtoplaceitemsinthereadandwritearraysifwewishtooverridethevaluesinthemainarray.So,inthiscase,192.168.1.1willbeusedasthe"read"connection,while192.168.1.2willbeusedasthe"write"connection.Thedatabasecredentials,prefix,characterset,andallotheroptionsinthemainmysqlarraywillbesharedacrossbothconnections.

Onceyouhaveconfiguredyourdatabaseconnection,youmayrunqueriesusingtheDBfacade.

$results=DB::select('select*fromuserswhereid=?',[1]);

BasicDatabaseUsage

Configuration

Read/WriteConnections

RunningQueries

RunningASelectQuery

Page 191: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Theselectmethodwillalwaysreturnanarrayofresults.

DB::insert('insertintousers(id,name)values(?,?)',[1,'Dayle']);

DB::update('updateuserssetvotes=100wherename=?',['John']);

DB::delete('deletefromusers');

Note:Theupdateanddeletestatementsreturnthenumberofrowsaffectedbytheoperation.

DB::statement('droptableusers');

YoumaylistenforqueryeventsusingtheDB::listenmethod:

DB::listen(function($sql,$bindings,$time)

{

//

});

Torunasetofoperationswithinadatabasetransaction,youmayusethetransactionmethod:

DB::transaction(function()

{

DB::table('users')->update(['votes'=>1]);

DB::table('posts')->delete();

});

Note:Anyexceptionthrownwithinthetransactionclosurewillcausethetransactiontoberolledbackautomatically.

Sometimesyoumayneedtobeginatransactionyourself:

DB::beginTransaction();

Youcanrollbackatransactionviatherollbackmethod:

RunningAnInsertStatement

RunningAnUpdateStatement

RunningADeleteStatement

RunningAGeneralStatement

ListeningForQueryEvents

DatabaseTransactions

Page 192: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

DB::rollback();

Lastly,youcancommitatransactionviathecommitmethod:

DB::commit();

Whenusingmultipleconnections,youmayaccessthemviatheDB::connectionmethod:

$users=DB::connection('foo')->select(...);

Youmayalsoaccesstheraw,underlyingPDOinstance:

$pdo=DB::connection()->getPdo();

Sometimesyoumayneedtoreconnecttoagivendatabase:

DB::reconnect('foo');

IfyouneedtodisconnectfromthegivendatabaseduetoexceedingtheunderlyingPDOinstance'smax_connectionslimit,usethedisconnectmethod:

DB::disconnect('foo');

Bydefault,Laravelkeepsaloginmemoryofallqueriesthathavebeenrunforthecurrentrequest.However,insomecases,suchaswheninsertingalargenumberofrows,thiscancausetheapplicationtouseexcessmemory.Todisablethelog,youmayusethedisableQueryLogmethod:

DB::connection()->disableQueryLog();

Togetanarrayoftheexecutedqueries,youmayusethegetQueryLogmethod:

$queries=DB::getQueryLog();

AccessingConnections

QueryLogging

Page 193: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionSelectsJoinsAdvancedWheresAggregatesRawExpressionsInsertsUpdatesDeletesUnionsPessimisticLocking

Thedatabasequerybuilderprovidesaconvenient,fluentinterfacetocreatingandrunningdatabasequeries.Itcanbeusedtoperformmostdatabaseoperationsinyourapplication,andworksonallsupporteddatabasesystems.

Note:TheLaravelquerybuilderusesPDOparameterbindingthroughouttoprotectyourapplicationagainstSQLinjectionattacks.Thereisnoneedtocleanstringsbeingpassedasbindings.

$users=DB::table('users')->get();

foreach($usersas$user)

{

var_dump($user->name);

}

DB::table('users')->chunk(100,function($users)

{

foreach($usersas$user)

{

//

}

});

YoumaystopfurtherchunksfrombeingprocessedbyreturningfalsefromtheClosure:

DB::table('users')->chunk(100,function($users)

{

//

returnfalse;

});

QueryBuilder

Introduction

Selects

RetrievingAllRowsFromATable

ChunkingResultsFromATable

RetrievingASingleRowFromATable

Page 194: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$user=DB::table('users')->where('name','John')->first();

var_dump($user->name);

$name=DB::table('users')->where('name','John')->pluck('name');

$roles=DB::table('roles')->lists('title');

Thismethodwillreturnanarrayofroletitles.Youmayalsospecifyacustomkeycolumnforthereturnedarray:

$roles=DB::table('roles')->lists('title','name');

$users=DB::table('users')->select('name','email')->get();

$users=DB::table('users')->distinct()->get();

$users=DB::table('users')->select('nameasuser_name')->get();

$query=DB::table('users')->select('name');

$users=$query->addSelect('age')->get();

$users=DB::table('users')->where('votes','>',100)->get();

$users=DB::table('users')

->where('votes','>',100)

->orWhere('name','John')

->get();

$users=DB::table('users')

->whereBetween('votes',array(1,100))->get();

RetrievingASingleColumnFromARow

RetrievingAListOfColumnValues

SpecifyingASelectClause

AddingASelectClauseToAnExistingQuery

UsingWhereOperators

OrStatements

UsingWhereBetween

UsingWhereNotBetween

Page 195: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$users=DB::table('users')

->whereNotBetween('votes',array(1,100))->get();

$users=DB::table('users')

->whereIn('id',array(1,2,3))->get();

$users=DB::table('users')

->whereNotIn('id',array(1,2,3))->get();

$users=DB::table('users')

->whereNull('updated_at')->get();

$users=DB::table('users')

->orderBy('name','desc')

->groupBy('count')

->having('count','>',100)

->get();

$users=DB::table('users')->skip(10)->take(5)->get();

Thequerybuildermayalsobeusedtowritejoinstatements.Takealookatthefollowingexamples:

DB::table('users')

->join('contacts','users.id','=','contacts.user_id')

->join('orders','users.id','=','orders.user_id')

->select('users.id','contacts.phone','orders.price')

->get();

DB::table('users')

->leftJoin('posts','users.id','=','posts.user_id')

->get();

Youmayalsospecifymoreadvancedjoinclauses:

DB::table('users')

->join('contacts',function($join)

{

$join->on('users.id','=','contacts.user_id')->orOn(...);

})

UsingWhereInWithAnArray

UsingWhereNullToFindRecordsWithUnsetValues

OrderBy,GroupBy,AndHaving

Offset&Limit

Joins

BasicJoinStatement

LeftJoinStatement

Page 196: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

->get();

Ifyouwouldliketousea"where"styleclauseonyourjoins,youmayusethewhereandorWheremethodsonajoin.Insteadofcomparingtwocolumns,thesemethodswillcomparethecolumnagainstavalue:

DB::table('users')

->join('contacts',function($join)

{

$join->on('users.id','=','contacts.user_id')

->where('contacts.user_id','>',5);

})

->get();

Sometimesyoumayneedtocreatemoreadvancedwhereclausessuchas"whereexists"ornestedparametergroupings.TheLaravelquerybuildercanhandletheseaswell:

DB::table('users')

->where('name','=','John')

->orWhere(function($query)

{

$query->where('votes','>',100)

->where('title','<>','Admin');

})

->get();

ThequeryabovewillproducethefollowingSQL:

select*fromuserswherename='John'or(votes>100andtitle<>'Admin')

DB::table('users')

->whereExists(function($query)

{

$query->select(DB::raw(1))

->from('orders')

->whereRaw('orders.user_id=users.id');

})

->get();

ThequeryabovewillproducethefollowingSQL:

select*fromusers

whereexists(

select1fromorderswhereorders.user_id=users.id

)

Thequerybuilderalsoprovidesavarietyofaggregatemethods,suchascount,max,min,avg,andsum.

AdvancedWheres

ParameterGrouping

ExistsStatements

Aggregates

Page 197: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$users=DB::table('users')->count();

$price=DB::table('orders')->max('price');

$price=DB::table('orders')->min('price');

$price=DB::table('orders')->avg('price');

$total=DB::table('users')->sum('votes');

Sometimesyoumayneedtousearawexpressioninaquery.Theseexpressionswillbeinjectedintothequeryasstrings,sobecarefulnottocreateanySQLinjectionpoints!Tocreatearawexpression,youmayusetheDB::rawmethod:

$users=DB::table('users')

->select(DB::raw('count(*)asuser_count,status'))

->where('status','<>',1)

->groupBy('status')

->get();

DB::table('users')->insert(

array('email'=>'[email protected]','votes'=>0)

);

Ifthetablehasanauto-incrementingid,useinsertGetIdtoinsertarecordandretrievetheid:

$id=DB::table('users')->insertGetId(

array('email'=>'[email protected]','votes'=>0)

);

Note:WhenusingPostgreSQLtheinsertGetIdmethodexpectstheauto-incrementingcolumntobenamed"id".

DB::table('users')->insert(array(

array('email'=>'[email protected]','votes'=>0),

array('email'=>'[email protected]','votes'=>0),

));

UsingAggregateMethods

RawExpressions

UsingARawExpression

Inserts

InsertingRecordsIntoATable

InsertingRecordsIntoATableWithAnAuto-IncrementingID

InsertingMultipleRecordsIntoATable

Updates

UpdatingRecordsInATable

Page 198: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

DB::table('users')

->where('id',1)

->update(array('votes'=>1));

DB::table('users')->increment('votes');

DB::table('users')->increment('votes',5);

DB::table('users')->decrement('votes');

DB::table('users')->decrement('votes',5);

Youmayalsospecifyadditionalcolumnstoupdate:

DB::table('users')->increment('votes',1,array('name'=>'John'));

DB::table('users')->where('votes','<',100)->delete();

DB::table('users')->delete();

DB::table('users')->truncate();

Thequerybuilderalsoprovidesaquickwayto"union"twoqueriestogether:

$first=DB::table('users')->whereNull('first_name');

$users=DB::table('users')->whereNull('last_name')->union($first)->get();

TheunionAllmethodisalsoavailable,andhasthesamemethodsignatureasunion.

Thequerybuilderincludesafewfunctionstohelpyoudo"pessimisticlocking"onyourSELECTstatements.

ToruntheSELECTstatementwitha"sharedlock",youmayusethesharedLockmethodonaquery:

Incrementingordecrementingavalueofacolumn

Deletes

DeletingRecordsInATable

DeletingAllRecordsFromATable

TruncatingATable

Unions

PessimisticLocking

Page 199: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

DB::table('users')->where('votes','>',100)->sharedLock()->get();

To"lockforupdate"onaSELECTstatement,youmayusethelockForUpdatemethodonaquery:

DB::table('users')->where('votes','>',100)->lockForUpdate()->get();

Page 200: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionBasicUsageMassAssignmentInsert,Update,DeleteSoftDeletingTimestampsQueryScopesGlobalScopesRelationshipsQueryingRelationsEagerLoadingInsertingRelatedModelsTouchingParentTimestampsWorkingWithPivotTablesCollectionsAccessors&MutatorsDateMutatorsAttributeCastingModelEventsModelObserversConvertingToArrays/JSON

TheEloquentORMincludedwithLaravelprovidesabeautiful,simpleActiveRecordimplementationforworkingwithyourdatabase.Eachdatabasetablehasacorresponding"Model"whichisusedtointeractwiththattable.

Beforegettingstarted,besuretoconfigureadatabaseconnectioninconfig/database.php.

Togetstarted,createanEloquentmodel.Modelstypicallyliveintheappdirectory,butyouarefreetoplacethemanywherethatcanbeauto-loadedaccordingtoyourcomposer.jsonfile.AllEloquentmodelsextendIlluminate\Database\Eloquent\Model.

classUserextendsModel{}

YoumayalsogenerateEloquentmodelsusingthemake:modelcommand:

phpartisanmake:modelUser

NotethatwedidnottellEloquentwhichtabletouseforourUsermodel.Thelower-case,pluralnameoftheclasswillbeusedasthetablenameunlessanothernameisexplicitlyspecified.So,inthiscase,EloquentwillassumetheUsermodelstoresrecordsintheuserstable.Youmayspecifyacustomtablebydefiningatablepropertyonyourmodel:

classUserextendsModel{

EloquentORM

Introduction

BasicUsage

DefiningAnEloquentModel

Page 201: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

protected$table='my_users';

}

Note:Eloquentwillalsoassumethateachtablehasaprimarykeycolumnnamedid.YoumaydefineaprimaryKeypropertytooverridethisconvention.Likewise,youmaydefineaconnectionpropertytooverridethenameofthedatabaseconnectionthatshouldbeusedwhenutilizingthemodel.

Onceamodelisdefined,youarereadytostartretrievingandcreatingrecordsinyourtable.Notethatyouwillneedtoplaceupdated_atandcreated_atcolumnsonyourtablebydefault.Ifyoudonotwishtohavethesecolumnsautomaticallymaintained,setthe$timestampspropertyonyourmodeltofalse.

$users=User::all();

$user=User::find(1);

var_dump($user->name);

Note:AllmethodsavailableonthequerybuilderarealsoavailablewhenqueryingEloquentmodels.

Sometimesyoumaywishtothrowanexceptionifamodelisnotfound,allowingyoutocatchtheexceptionsusinganApp::errorhandleranddisplaya404page.

$model=User::findOrFail(1);

$model=User::where('votes','>',100)->firstOrFail();

Toregistertheerrorhandler,listenfortheModelNotFoundException

useIlluminate\Database\Eloquent\ModelNotFoundException;

App::error(function(ModelNotFoundException$e)

{

returnResponse::make('NotFound',404);

});

$users=User::where('votes','>',100)->take(10)->get();

foreach($usersas$user)

{

var_dump($user->name);

}

Ofcourse,youmayalsousethequerybuilderaggregatefunctions.

RetrievingAllModels

RetrievingARecordByPrimaryKey

RetrievingAModelByPrimaryKeyOrThrowAnException

QueryingUsingEloquentModels

EloquentAggregates

Page 202: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$count=User::where('votes','>',100)->count();

Ifyouareunabletogeneratethequeryyouneedviathefluentinterface,feelfreetousewhereRaw:

$users=User::whereRaw('age>?andvotes=100',array(25))->get();

Ifyouneedtoprocessalot(thousands)ofEloquentrecords,usingthechunkcommandwillallowyoutodowithouteatingallofyourRAM:

User::chunk(200,function($users)

{

foreach($usersas$user)

{

//

}

});

Thefirstargumentpassedtothemethodisthenumberofrecordsyouwishtoreceiveper"chunk".TheClosurepassedasthesecondargumentwillbecalledforeachchunkthatispulledfromthedatabase.

YoumayalsospecifywhichdatabaseconnectionshouldbeusedwhenrunninganEloquentquery.Simplyusetheonmethod:

$user=User::on('connection-name')->find(1);

Ifyouareusingread/writeconnections,youmayforcethequerytousethe"write"connectionwiththefollowingmethod:

$user=User::onWriteConnection()->find(1);

Whencreatinganewmodel,youpassanarrayofattributestothemodelconstructor.Theseattributesarethenassignedtothemodelviamass-assignment.Thisisconvenient;however,canbeaserioussecurityconcernwhenblindlypassinguserinputintoamodel.Ifuserinputisblindlypassedintoamodel,theuserisfreetomodifyanyandallofthemodel'sattributes.Forthisreason,allEloquentmodelsprotectagainstmass-assignmentbydefault.

Togetstarted,setthefillableorguardedpropertiesonyourmodel.

Thefillablepropertyspecifieswhichattributesshouldbemass-assignable.Thiscanbesetattheclassorinstancelevel.

classUserextendsModel{

protected$fillable=array('first_name','last_name','email');

}

ChunkingResults

SpecifyingTheQueryConnection

MassAssignment

DefiningFillableAttributesOnAModel

Page 203: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Inthisexample,onlythethreelistedattributeswillbemass-assignable.

Theinverseoffillableisguarded,andservesasa"black-list"insteadofa"white-list":

classUserextendsModel{

protected$guarded=array('id','password');

}

Note:Whenusingguarded,youshouldstillneverpassInput::get()oranyrawarrayofusercontrolledinputintoasaveorupdatemethod,asanycolumnthatisnotguardedmaybeupdated.

Intheexampleabove,theidandpasswordattributesmaynotbemassassigned.Allotherattributeswillbemassassignable.Youmayalsoblockallattributesfrommassassignmentusingtheguardproperty:

protected$guarded=array('*');

Tocreateanewrecordinthedatabasefromamodel,simplycreateanewmodelinstanceandcallthesavemethod.

$user=newUser;

$user->name='John';

$user->save();

Note:Typically,yourEloquentmodelswillhaveauto-incrementingkeys.However,ifyouwishtospecifyyourownkeys,settheincrementingpropertyonyourmodeltofalse.

Youmayalsousethecreatemethodtosaveanewmodelinasingleline.Theinsertedmodelinstancewillbereturnedtoyoufromthemethod.However,beforedoingso,youwillneedtospecifyeitherafillableorguardedattributeonthemodel,asallEloquentmodelsprotectagainstmass-assignment.

Aftersavingorcreatinganewmodelthatusesauto-incrementingIDs,youmayretrievetheIDbyaccessingtheobject'sidattribute:

$insertedId=$user->id;

classUserextendsModel{

protected$guarded=array('id','account_id');

}

DefiningGuardedAttributesOnAModel

BlockingAllAttributesFromMassAssignment

Insert,Update,Delete

SavingANewModel

SettingTheGuardedAttributesOnTheModel

Page 204: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

//Createanewuserinthedatabase...

$user=User::create(array('name'=>'John'));

//Retrievetheuserbytheattributes,orcreateitifitdoesn'texist...

$user=User::firstOrCreate(array('name'=>'John'));

//Retrievetheuserbytheattributes,orinstantiateanewinstance...

$user=User::firstOrNew(array('name'=>'John'));

Toupdateamodel,youmayretrieveit,changeanattribute,andusethesavemethod:

$user=User::find(1);

$user->email='[email protected]';

$user->save();

Sometimesyoumaywishtosavenotonlyamodel,butalsoallofitsrelationships.Todoso,youmayusethepushmethod:

$user->push();

Youmayalsorunupdatesasqueriesagainstasetofmodels:

$affectedRows=User::where('votes','>',100)->update(array('status'=>2));

Note:NomodeleventsarefiredwhenupdatingasetofmodelsviatheEloquentquerybuilder.

Todeleteamodel,simplycallthedeletemethodontheinstance:

$user=User::find(1);

$user->delete();

User::destroy(1);

User::destroy(array(1,2,3));

User::destroy(1,2,3);

Ofcourse,youmayalsorunadeletequeryonasetofmodels:

$affectedRows=User::where('votes','>',100)->delete();

UsingTheModelCreateMethod

UpdatingARetrievedModel

SavingAModelAndRelationships

DeletingAnExistingModel

DeletingAnExistingModelByKey

Page 205: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Ifyouwishtosimplyupdatethetimestampsonamodel,youmayusethetouchmethod:

$user->touch();

Whensoftdeletingamodel,itisnotactuallyremovedfromyourdatabase.Instead,adeleted_attimestampissetontherecord.Toenablesoftdeletesforamodel,applytheSoftDeletestothemodel:

useIlluminate\Database\Eloquent\SoftDeletes;

classUserextendsModel{

useSoftDeletes;

protected$dates=['deleted_at'];

}

Toaddadeleted_atcolumntoyourtable,youmayusethesoftDeletesmethodfromamigration:

$table->softDeletes();

Now,whenyoucallthedeletemethodonthemodel,thedeleted_atcolumnwillbesettothecurrenttimestamp.Whenqueryingamodelthatusessoftdeletes,the"deleted"modelswillnotbeincludedinqueryresults.

Toforcesoftdeletedmodelstoappearinaresultset,usethewithTrashedmethodonthequery:

$users=User::withTrashed()->where('account_id',1)->get();

ThewithTrashedmethodmaybeusedonadefinedrelationship:

$user->posts()->withTrashed()->get();

Ifyouwishtoonlyreceivesoftdeletedmodelsinyourresults,youmayusetheonlyTrashedmethod:

$users=User::onlyTrashed()->where('account_id',1)->get();

Torestoreasoftdeletedmodelintoanactivestate,usetherestoremethod:

$user->restore();

Youmayalsousetherestoremethodonaquery:

User::withTrashed()->where('account_id',1)->restore();

UpdatingOnlyTheModel'sTimestamps

SoftDeleting

ForcingSoftDeletedModelsIntoResults

Page 206: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

LikewithwithTrashed,therestoremethodmayalsobeusedonrelationships:

$user->posts()->restore();

Ifyouwishtotrulyremoveamodelfromthedatabase,youmayusetheforceDeletemethod:

$user->forceDelete();

TheforceDeletemethodalsoworksonrelationships:

$user->posts()->forceDelete();

Todetermineifagivenmodelinstancehasbeensoftdeleted,youmayusethetrashedmethod:

if($user->trashed())

{

//

}

Bydefault,Eloquentwillmaintainthecreated_atandupdated_atcolumnsonyourdatabasetableautomatically.SimplyaddthesetimestampcolumnstoyourtableandEloquentwilltakecareoftherest.IfyoudonotwishforEloquenttomaintainthesecolumns,addthefollowingpropertytoyourmodel:

classUserextendsModel{

protected$table='users';

public$timestamps=false;

}

Ifyouwishtocustomizetheformatofyourtimestamps,youmayoverridethegetDateFormatmethodinyourmodel:

classUserextendsModel{

protectedfunctiongetDateFormat()

{

return'U';

}

}

Timestamps

DisablingAutoTimestamps

ProvidingACustomTimestampFormat

QueryScopes

DefiningAQueryScope

Page 207: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Scopesallowyoutoeasilyre-usequerylogicinyourmodels.Todefineascope,simplyprefixamodelmethodwithscope:

classUserextendsModel{

publicfunctionscopePopular($query)

{

return$query->where('votes','>',100);

}

publicfunctionscopeWomen($query)

{

return$query->whereGender('W');

}

}

$users=User::popular()->women()->orderBy('created_at')->get();

Sometimesyoumaywishtodefineascopethatacceptsparameters.Justaddyourparameterstoyourscopefunction:

classUserextendsModel{

publicfunctionscopeOfType($query,$type)

{

return$query->whereType($type);

}

}

Thenpasstheparameterintothescopecall:

$users=User::ofType('member')->get();

Sometimesyoumaywishtodefineascopethatappliestoallqueriesperformedonamodel.Inessence,thisishowEloquent'sown"softdelete"featureworks.GlobalscopesaredefinedusingacombinationofPHPtraitsandanimplementationofIlluminate\Database\Eloquent\ScopeInterface.

First,let'sdefineatrait.Forthisexample,we'llusetheSoftDeletesthatshipswithLaravel:

traitSoftDeletes{

/**

*Bootthesoftdeletingtraitforamodel.

*

*@returnvoid

*/

publicstaticfunctionbootSoftDeletes()

{

static::addGlobalScope(newSoftDeletingScope);

}

}

UtilizingAQueryScope

DynamicScopes

GlobalScopes

Page 208: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IfanEloquentmodelusesatraitthathasamethodmatchingthebootNameOfTraitnamingconvention,thattraitmethodwillbecalledwhentheEloquentmodelisbooted,givingyouanopportunitytoregisteraglobalscope,ordoanythingelseyouwant.AscopemustimplementScopeInterface,whichspecifiestwomethods:applyandremove.

TheapplymethodreceivesanIlluminate\Database\Eloquent\Builderquerybuilderobject,andisresponsibleforaddinganyadditionalwhereclausesthatthescopewishestoadd.TheremovemethodalsoreceivesaBuilderobjectandisresponsibleforreversingtheactiontakenbyapply.Inotherwords,removeshouldremovethewhereclause(oranyotherclause)thatwasadded.So,forourSoftDeletingScope,themethodslooksomethinglikethis:

/**

*ApplythescopetoagivenEloquentquerybuilder.

*

*@param\Illuminate\Database\Eloquent\Builder$builder

*@returnvoid

*/

publicfunctionapply(Builder$builder)

{

$model=$builder->getModel();

$builder->whereNull($model->getQualifiedDeletedAtColumn());

}

/**

*RemovethescopefromthegivenEloquentquerybuilder.

*

*@param\Illuminate\Database\Eloquent\Builder$builder

*@returnvoid

*/

publicfunctionremove(Builder$builder)

{

$column=$builder->getModel()->getQualifiedDeletedAtColumn();

$query=$builder->getQuery();

foreach((array)$query->wheresas$key=>$where)

{

//Ifthewhereclauseisasoftdeletedateconstraint,wewillremoveitfrom

//thequeryandresetthekeysonthewheres.Thisallowsthisdeveloperto

//includedeletedmodelinarelationshipresultsetthatislazyloaded.

if($this->isSoftDeleteConstraint($where,$column))

{

unset($query->wheres[$key]);

$query->wheres=array_values($query->wheres);

}

}

}

Ofcourse,yourdatabasetablesareprobablyrelatedtooneanother.Forexample,ablogpostmayhavemanycomments,oranordercouldberelatedtotheuserwhoplacedit.Eloquentmakesmanagingandworkingwiththeserelationshipseasy.Laravelsupportsmanytypesofrelationships:

OneToOneOneToManyManyToManyHasManyThroughPolymorphicRelationsManyToManyPolymorphicRelations

Aone-to-onerelationshipisaverybasicrelation.Forexample,aUsermodelmighthaveonePhone.Wecandefinethis

Relationships

OneToOne

DefiningAOneToOneRelation

Page 209: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

relationinEloquent:

classUserextendsModel{

publicfunctionphone()

{

return$this->hasOne('App\Phone');

}

}

ThefirstargumentpassedtothehasOnemethodisthenameoftherelatedmodel.Oncetherelationshipisdefined,wemayretrieveitusingEloquent'sdynamicproperties:

$phone=User::find(1)->phone;

TheSQLperformedbythisstatementwillbeasfollows:

select*fromuserswhereid=1

select*fromphoneswhereuser_id=1

TakenotethatEloquentassumestheforeignkeyoftherelationshipbasedonthemodelname.Inthiscase,Phonemodelisassumedtouseauser_idforeignkey.Ifyouwishtooverridethisconvention,youmaypassasecondargumenttothehasOnemethod.Furthermore,youmaypassathirdargumenttothemethodtospecifywhichlocalcolumnthatshouldbeusedfortheassociation:

return$this->hasOne('App\Phone','foreign_key');

return$this->hasOne('App\Phone','foreign_key','local_key');

TodefinetheinverseoftherelationshiponthePhonemodel,weusethebelongsTomethod:

classPhoneextendsModel{

publicfunctionuser()

{

return$this->belongsTo('App\User');

}

}

Intheexampleabove,Eloquentwilllookforauser_idcolumnonthephonestable.Ifyouwouldliketodefineadifferentforeignkeycolumn,youmaypassitasthesecondargumenttothebelongsTomethod:

classPhoneextendsModel{

publicfunctionuser()

{

return$this->belongsTo('App\User','local_key');

}

}

Additionally,youpassathirdparameterwhichspecifiesthenameoftheassociatedcolumnontheparenttable:

DefiningTheInverseOfARelation

Page 210: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

classPhoneextendsModel{

publicfunctionuser()

{

return$this->belongsTo('App\User','local_key','parent_key');

}

}

Anexampleofaone-to-manyrelationisablogpostthat"hasmany"comments.Wecanmodelthisrelationlikeso:

classPostextendsModel{

publicfunctioncomments()

{

return$this->hasMany('App\Comment');

}

}

Nowwecanaccessthepost'scommentsthroughthedynamicproperty:

$comments=Post::find(1)->comments;

Ifyouneedtoaddfurtherconstraintstowhichcommentsareretrieved,youmaycallthecommentsmethodandcontinuechainingconditions:

$comments=Post::find(1)->comments()->where('title','=','foo')->first();

Again,youmayoverridetheconventionalforeignkeybypassingasecondargumenttothehasManymethod.And,likethehasOnerelation,thelocalcolumnmayalsobespecified:

return$this->hasMany('App\Comment','foreign_key');

return$this->hasMany('App\Comment','foreign_key','local_key');

TodefinetheinverseoftherelationshipontheCommentmodel,weusethebelongsTomethod:

classCommentextendsModel{

publicfunctionpost()

{

return$this->belongsTo('App\Post');

}

}

Many-to-manyrelationsareamorecomplicatedrelationshiptype.Anexampleofsucharelationshipisauserwithmanyroles,wheretherolesarealsosharedbyotherusers.Forexample,manyusersmayhavetheroleof"Admin".Threedatabasetablesareneededforthisrelationship:users,roles,androle_user.Therole_usertableisderivedfromthe

OneToMany

DefiningTheInverseOfARelation

ManyToMany

Page 211: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

alphabeticalorderoftherelatedmodelnames,andshouldhaveuser_idandrole_idcolumns.

Wecandefineamany-to-manyrelationusingthebelongsToManymethod:

classUserextendsModel{

publicfunctionroles()

{

return$this->belongsToMany('App\Role');

}

}

Now,wecanretrievetherolesthroughtheUsermodel:

$roles=User::find(1)->roles;

Ifyouwouldliketouseanunconventionaltablenameforyourpivottable,youmaypassitasthesecondargumenttothebelongsToManymethod:

return$this->belongsToMany('App\Role','user_roles');

Youmayalsooverridetheconventionalassociatedkeys:

return$this->belongsToMany('App\Role','user_roles','user_id','foo_id');

Ofcourse,youmayalsodefinetheinverseoftherelationshipontheRolemodel:

classRoleextendsModel{

publicfunctionusers()

{

return$this->belongsToMany('App\User');

}

}

The"hasmanythrough"relationprovidesaconvenientshort-cutforaccessingdistantrelationsviaanintermediaterelation.Forexample,aCountrymodelmighthavemanyPostthroughaUsermodel.Thetablesforthisrelationshipwouldlooklikethis:

countries

id-integer

name-string

users

id-integer

country_id-integer

name-string

posts

id-integer

user_id-integer

title-string

Eventhoughthepoststabledoesnotcontainacountry_idcolumn,thehasManyThroughrelationwillallowustoaccessa

HasManyThrough

Page 212: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

country'spostsvia$country->posts.Let'sdefinetherelationship:

classCountryextendsModel{

publicfunctionposts()

{

return$this->hasManyThrough('App\Post','User');

}

}

Ifyouwouldliketomanuallyspecifythekeysoftherelationship,youmaypassthemasthethirdandfourthargumentstothemethod:

classCountryextendsModel{

publicfunctionposts()

{

return$this->hasManyThrough('App\Post','User','country_id','user_id');

}

}

Polymorphicrelationsallowamodeltobelongtomorethanoneothermodel,onasingleassociation.Forexample,youmighthaveaphotomodelthatbelongstoeitherastaffmodeloranordermodel.Wewoulddefinethisrelationlikeso:

classPhotoextendsModel{

publicfunctionimageable()

{

return$this->morphTo();

}

}

classStaffextendsModel{

publicfunctionphotos()

{

return$this->morphMany('App\Photo','imageable');

}

}

classOrderextendsModel{

publicfunctionphotos()

{

return$this->morphMany('App\Photo','imageable');

}

}

Now,wecanretrievethephotosforeitherastaffmemberoranorder:

$staff=Staff::find(1);

foreach($staff->photosas$photo)

{

//

}

PolymorphicRelations

RetrievingAPolymorphicRelation

Page 213: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

However,thetrue"polymorphic"magiciswhenyouaccessthestaffororderfromthePhotomodel:

$photo=Photo::find(1);

$imageable=$photo->imageable;

TheimageablerelationonthePhotomodelwillreturneitheraStafforOrderinstance,dependingonwhichtypeofmodelownsthephoto.

Tohelpunderstandhowthisworks,let'sexplorethedatabasestructureforapolymorphicrelation:

staff

id-integer

name-string

orders

id-integer

price-integer

photos

id-integer

path-string

imageable_id-integer

imageable_type-string

Thekeyfieldstonoticeherearetheimageable_idandimageable_typeonthephotostable.TheIDwillcontaintheIDvalueof,inthisexample,theowningstaffororder,whilethetypewillcontaintheclassnameoftheowningmodel.ThisiswhatallowstheORMtodeterminewhichtypeofowningmodeltoreturnwhenaccessingtheimageablerelation.

Inadditiontotraditionalpolymorphicrelations,youmayalsospecifymany-to-manypolymorphicrelations.Forexample,ablogPostandVideomodelcouldshareapolymorphicrelationtoaTagmodel.First,let'sexaminethetablestructure:

posts

id-integer

name-string

videos

id-integer

name-string

tags

id-integer

name-string

taggables

tag_id-integer

taggable_id-integer

taggable_type-string

Next,we'rereadytosetuptherelationshipsonthemodel.ThePostandVideomodelwillbothhaveamorphToManyrelationshipviaatagsmethod:

classPostextendsModel{

RetrievingTheOwnerOfAPolymorphicRelation

PolymorphicRelationTableStructure

ManyToManyPolymorphicRelations

PolymorphicManyToManyRelationTableStructure

Page 214: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

publicfunctiontags()

{

return$this->morphToMany('App\Tag','taggable');

}

}

TheTagmodelmaydefineamethodforeachofitsrelationships:

classTagextendsModel{

publicfunctionposts()

{

return$this->morphedByMany('App\Post','taggable');

}

publicfunctionvideos()

{

return$this->morphedByMany('App\Video','taggable');

}

}

Whenaccessingtherecordsforamodel,youmaywishtolimityourresultsbasedontheexistenceofarelationship.Forexample,youwishtopullallblogpoststhathaveatleastonecomment.Todoso,youmayusethehasmethod:

$posts=Post::has('comments')->get();

Youmayalsospecifyanoperatorandacount:

$posts=Post::has('comments','>=',3)->get();

Nestedhasstatementsmayalsobeconstructedusing"dot"notation:

$posts=Post::has('comments.votes')->get();

Ifyouneedevenmorepower,youmayusethewhereHasandorWhereHasmethodstoput"where"conditionsonyourhasqueries:

$posts=Post::whereHas('comments',function($q)

{

$q->where('content','like','foo%');

})->get();

Eloquentallowsyoutoaccessyourrelationsviadynamicproperties.Eloquentwillautomaticallyloadtherelationshipforyou,andisevensmartenoughtoknowwhethertocalltheget(forone-to-manyrelationships)orfirst(forone-to-onerelationships)method.Itwillthenbeaccessibleviaadynamicpropertybythesamenameastherelation.Forexample,withthefollowingmodel$phone:

QueryingRelations

QueryingRelationsWhenSelecting

DynamicProperties

Page 215: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

classPhoneextendsModel{

publicfunctionuser()

{

return$this->belongsTo('App\User');

}

}

$phone=Phone::find(1);

Insteadofechoingtheuser'semaillikethis:

echo$phone->user()->first()->email;

Itmaybeshortenedtosimply:

echo$phone->user->email;

Note:RelationshipsthatreturnmanyresultswillreturnaninstanceoftheIlluminate\Database\Eloquent\Collectionclass.

EagerloadingexiststoalleviatetheN+1queryproblem.Forexample,consideraBookmodelthatisrelatedtoAuthor.Therelationshipisdefinedlikeso:

classBookextendsModel{

publicfunctionauthor()

{

return$this->belongsTo('App\Author');

}

}

Now,considerthefollowingcode:

foreach(Book::all()as$book)

{

echo$book->author->name;

}

Thisloopwillexecute1querytoretrieveallofthebooksonthetable,thenanotherqueryforeachbooktoretrievetheauthor.So,ifwehave25books,thisloopwouldrun26queries.

Thankfully,wecanuseeagerloadingtodrasticallyreducethenumberofqueries.Therelationshipsthatshouldbeeagerloadedmaybespecifiedviathewithmethod:

foreach(Book::with('author')->get()as$book)

{

echo$book->author->name;

}

Intheloopabove,onlytwoquerieswillbeexecuted:

EagerLoading

Page 216: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

select*frombooks

select*fromauthorswhereidin(1,2,3,4,5,...)

Wiseuseofeagerloadingcandrasticallyincreasetheperformanceofyourapplication.

Ofcourse,youmayeagerloadmultiplerelationshipsatonetime:

$books=Book::with('author','publisher')->get();

Youmayeveneagerloadnestedrelationships:

$books=Book::with('author.contacts')->get();

Intheexampleabove,theauthorrelationshipwillbeeagerloaded,andtheauthor'scontactsrelationwillalsobeloaded.

Sometimesyoumaywishtoeagerloadarelationship,butalsospecifyaconditionfortheeagerload.Here'sanexample:

$users=User::with(array('posts'=>function($query)

{

$query->where('title','like','%first%');

}))->get();

Inthisexample,we'reeagerloadingtheuser'sposts,butonlyifthepost'stitlecolumncontainstheword"first".

Ofcourse,eagerloadingClosuresaren'tlimitedto"constraints".Youmayalsoapplyorders:

$users=User::with(array('posts'=>function($query)

{

$query->orderBy('created_at','desc');

}))->get();

Itisalsopossibletoeagerlyloadrelatedmodelsdirectlyfromanalreadyexistingmodelcollection.Thismaybeusefulwhendynamicallydecidingwhethertoloadrelatedmodelsornot,orincombinationwithcaching.

$books=Book::all();

$books->load('author','publisher');

Youwilloftenneedtoinsertnewrelatedmodels.Forexample,youmaywishtoinsertanewcommentforapost.Insteadofmanuallysettingthepost_idforeignkeyonthemodel,youmayinsertthenewcommentfromitsparentPostmodeldirectly:

EagerLoadConstraints

LazyEagerLoading

InsertingRelatedModels

AttachingARelatedModel

Page 217: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$comment=newComment(array('message'=>'Anewcomment.'));

$post=Post::find(1);

$comment=$post->comments()->save($comment);

Inthisexample,thepost_idfieldwillautomaticallybesetontheinsertedcomment.

Ifyouneedtosavemultiplerelatedmodels:

$comments=array(

newComment(array('message'=>'Anewcomment.')),

newComment(array('message'=>'Anothercomment.')),

newComment(array('message'=>'Thelatestcomment.'))

);

$post=Post::find(1);

$post->comments()->saveMany($comments);

WhenupdatingabelongsTorelationship,youmayusetheassociatemethod.Thismethodwillsettheforeignkeyonthechildmodel:

$account=Account::find(10);

$user->account()->associate($account);

$user->save();

Youmayalsoinsertrelatedmodelswhenworkingwithmany-to-manyrelations.Let'scontinueusingourUserandRolemodelsasexamples.Wecaneasilyattachnewrolestoauserusingtheattachmethod:

$user=User::find(1);

$user->roles()->attach(1);

Youmayalsopassanarrayofattributesthatshouldbestoredonthepivottablefortherelation:

$user->roles()->attach(1,array('expires'=>$expires));

Ofcourse,theoppositeofattachisdetach:

$user->roles()->detach(1);

BothattachanddetachalsotakearraysofIDsasinput:

$user=User::find(1);

$user->roles()->detach([1,2,3]);

AssociatingModels(BelongsTo)

InsertingRelatedModels(ManyToMany)

AttachingManyToManyModels

Page 218: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$user->roles()->attach([1=>['attribute1'=>'value1'],2,3]);

Youmayalsousethesyncmethodtoattachrelatedmodels.ThesyncmethodacceptsanarrayofIDstoplaceonthepivottable.Afterthisoperationiscomplete,onlytheIDsinthearraywillbeontheintermediatetableforthemodel:

$user->roles()->sync(array(1,2,3));

YoumayalsoassociateotherpivottablevalueswiththegivenIDs:

$user->roles()->sync(array(1=>array('expires'=>true)));

Sometimesyoumaywishtocreateanewrelatedmodelandattachitinasinglecommand.Forthisoperation,youmayusethesavemethod:

$role=newRole(array('name'=>'Editor'));

User::find(1)->roles()->save($role);

Inthisexample,thenewRolemodelwillbesavedandattachedtotheusermodel.Youmayalsopassanarrayofattributestoplaceonthejoiningtableforthisoperation:

User::find(1)->roles()->save($role,array('expires'=>$expires));

WhenamodelbelongsToanothermodel,suchasaCommentwhichbelongstoaPost,itisoftenhelpfultoupdatetheparent'stimestampwhenthechildmodelisupdated.Forexample,whenaCommentmodelisupdated,youmaywanttoautomaticallytouchtheupdated_attimestampoftheowningPost.Eloquentmakesiteasy.Justaddatouchespropertycontainingthenamesoftherelationshipstothechildmodel:

classCommentextendsModel{

protected$touches=array('post');

publicfunctionpost()

{

return$this->belongsTo('App\Post');

}

}

Now,whenyouupdateaComment,theowningPostwillhaveitsupdated_atcolumnupdated:

$comment=Comment::find(1);

$comment->text='Edittothiscomment!';

$comment->save();

UsingSyncToAttachManyToManyModels

AddingPivotDataWhenSyncing

TouchingParentTimestamps

Page 219: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Asyouhavealreadylearned,workingwithmany-to-manyrelationsrequiresthepresenceofanintermediatetable.Eloquentprovidessomeveryhelpfulwaysofinteractingwiththistable.Forexample,let'sassumeourUserobjecthasmanyRoleobjectsthatitisrelatedto.Afteraccessingthisrelationship,wemayaccessthepivottableonthemodels:

$user=User::find(1);

foreach($user->rolesas$role)

{

echo$role->pivot->created_at;

}

NoticethateachRolemodelweretrieveisautomaticallyassignedapivotattribute.Thisattributecontainsamodelrepresentingtheintermediatetable,andmaybeusedasanyotherEloquentmodel.

Bydefault,onlythekeyswillbepresentonthepivotobject.Ifyourpivottablecontainsextraattributes,youmustspecifythemwhendefiningtherelationship:

return$this->belongsToMany('App\Role')->withPivot('foo','bar');

NowthefooandbarattributeswillbeaccessibleonourpivotobjectfortheRolemodel.

Ifyouwantyourpivottabletohaveautomaticallymaintainedcreated_atandupdated_attimestamps,usethewithTimestampsmethodontherelationshipdefinition:

return$this->belongsToMany('App\Role')->withTimestamps();

Todeleteallrecordsonthepivottableforamodel,youmayusethedetachmethod:

User::find(1)->roles()->detach();

Notethatthisoperationdoesnotdeleterecordsfromtherolestable,butonlyfromthepivottable.

Sometimesyoumayneedtoupdateyourpivottable,butnotdetachit.IfyouwishtoupdateyourpivottableinplaceyoumayuseupdateExistingPivotmethodlikeso:

User::find(1)->roles()->updateExistingPivot($roleId,$attributes);

LaravelalsoallowsyoutodefineacustomPivotmodel.Todefineacustommodel,firstcreateyourown"Base"modelclassthatextendsEloquent.InyourotherEloquentmodels,extendthiscustombasemodelinsteadofthedefaultEloquentbase.Inyourbasemodel,addthefollowingfunctionthatreturnsaninstanceofyourcustomPivotmodel:

publicfunctionnewPivot(Model$parent,array$attributes,$table,$exists)

{

returnnewYourCustomPivot($parent,$attributes,$table,$exists);

WorkingWithPivotTables

DeletingRecordsOnAPivotTable

UpdatingARecordOnAPivotTable

DefiningACustomPivotModel

Page 220: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

}

Allmulti-resultsetsreturnedbyEloquent,eitherviathegetmethodorarelationship,willreturnacollectionobject.ThisobjectimplementstheIteratorAggregatePHPinterfacesoitcanbeiteratedoverlikeanarray.However,thisobjectalsohasavarietyofotherhelpfulmethodsforworkingwithresultsets.

Forexample,wemaydetermineifaresultsetcontainsagivenprimarykeyusingthecontainsmethod:

$roles=User::find(1)->roles;

if($roles->contains(2))

{

//

}

CollectionsmayalsobeconvertedtoanarrayorJSON:

$roles=User::find(1)->roles->toArray();

$roles=User::find(1)->roles->toJson();

Ifacollectioniscasttoastring,itwillbereturnedasJSON:

$roles=(string)User::find(1)->roles;

Eloquentcollectionsalsocontainafewhelpfulmethodsforloopingandfilteringtheitemstheycontain:

$roles=$user->roles->each(function($role)

{

//

});

Whenfilteringcollections,thecallbackprovidedwillbeusedascallbackforarray_filter.

$users=$users->filter(function($user)

{

return$user->isAdmin();

});

Note:WhenfilteringacollectionandconvertingittoJSON,trycallingthevaluesfunctionfirsttoresetthearray'skeys.

$roles=User::find(1)->roles;

Collections

CheckingIfACollectionContainsAKey

IteratingCollections

FilteringCollections

ApplyingACallbackToEachCollectionObject

Page 221: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$roles->each(function($role)

{

//

});

$roles=$roles->sortBy(function($role)

{

return$role->created_at;

});

$roles=$roles->sortBy('created_at');

Sometimes,youmaywishtoreturnacustomCollectionobjectwithyourownaddedmethods.YoumayspecifythisonyourEloquentmodelbyoverridingthenewCollectionmethod:

classUserextendsModel{

publicfunctionnewCollection(array$models=array())

{

returnnewCustomCollection($models);

}

}

Eloquentprovidesaconvenientwaytotransformyourmodelattributeswhengettingorsettingthem.SimplydefineagetFooAttributemethodonyourmodeltodeclareanaccessor.Keepinmindthatthemethodsshouldfollowcamel-casing,eventhoughyourdatabasecolumnsaresnake-case:

classUserextendsModel{

publicfunctiongetFirstNameAttribute($value)

{

returnucfirst($value);

}

}

Intheexampleabove,thefirst_namecolumnhasanaccessor.Notethatthevalueoftheattributeispassedtotheaccessor.

Mutatorsaredeclaredinasimilarfashion:

classUserextendsModel{

SortingACollectionByAValue

SortingACollectionByAValue

ReturningACustomCollectionType

Accessors&Mutators

DefiningAnAccessor

DefiningAMutator

Page 222: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

publicfunctionsetFirstNameAttribute($value)

{

$this->attributes['first_name']=strtolower($value);

}

}

Bydefault,Eloquentwillconvertthecreated_atandupdated_atcolumnstoinstancesofCarbon,whichprovidesanassortmentofhelpfulmethods,andextendsthenativePHPDateTimeclass.

Youmaycustomizewhichfieldsareautomaticallymutated,andevencompletelydisablethismutation,byoverridingthegetDatesmethodofthemodel:

publicfunctiongetDates()

{

returnarray('created_at');

}

Whenacolumnisconsideredadate,youmaysetitsvaluetoaUNIXtimestamp,datestring(Y-m-d),date-timestring,andofcourseaDateTime/Carboninstance.

Tototallydisabledatemutations,simplyreturnanemptyarrayfromthegetDatesmethod:

publicfunctiongetDates()

{

returnarray();

}

Ifyouhavesomeattributesthatyouwanttoalwaysconverttoanotherdata-type,youmayaddtheattributetothecastspropertyofyourmodel.Otherwise,youwillhavetodefineamutatorforeachoftheattributes,whichcanbetimeconsuming.Hereisanexampleofusingthecastsproperty:

/**

*Theattributesthatshouldbecastedtonativetypes.

*

*@vararray

*/

protected$casts=[

'is_admin'=>'boolean',

];

Nowtheis_adminattributewillalwaysbecasttoabooleanwhenyouaccessit,eveniftheunderlyingvalueisstoredinthedatabaseasaninteger.Othersupportedcasttypesare:integer,real,float,double,string,boolean,andarray.

ThearraycastisparticularlyusefulforworkingwithcolumnsthatarestoredasserializedJSON.Forexample,ifyourdatabasehasaTEXTtypefieldthatcontainsserializedJSON,addingthearraycasttothatattributewillautomaticallydeserializetheattributetoaPHParraywhenyouaccessitonyourEloquentmodel:

/**

*Theattributesthatshouldbecastedtonativetypes.

*

*@vararray

DateMutators

AttributeCasting

Page 223: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

*/

protected$casts=[

'options'=>'array',

];

Now,whenyouutilizetheEloquentmodel:

$user=User::find(1);

//$optionsisanarray...

$options=$user->options;

//optionsisautomaticallyserializedbacktoJSON...

$user->options=['foo'=>'bar'];

Eloquentmodelsfireseveralevents,allowingyoutohookintovariouspointsinthemodel'slifecycleusingthefollowingmethods:creating,created,updating,updated,saving,saved,deleting,deleted,restoring,restored.

Wheneveranewitemissavedforthefirsttime,thecreatingandcreatedeventswillfire.Ifanitemisnotnewandthesavemethodiscalled,theupdating/updatedeventswillfire.Inbothcases,thesaving/savedeventswillfire.

Iffalseisreturnedfromthecreating,updating,saving,ordeletingevents,theactionwillbecancelled:

User::creating(function($user)

{

if(!$user->isValid())returnfalse;

});

YourEventServiceProviderservesasaconvenientplacetoregisteryourmodeleventbindings.Forexample:

/**

*Registeranyothereventsforyourapplication.

*

*@param\Illuminate\Contracts\Events\Dispatcher$events

*@returnvoid

*/

publicfunctionboot(DispatcherContract$events)

{

parent::boot($events);

User::creating(function($user)

{

//

});

}

Toconsolidatethehandlingofmodelevents,youmayregisteramodelobserver.Anobserverclassmayhavemethodsthatcorrespondtothevariousmodelevents.Forexample,creating,updating,savingmethodsmaybeonanobserver,inadditiontoanyothermodeleventname.

So,forexample,amodelobservermightlooklikethis:

ModelEvents

CancellingSaveOperationsViaEvents

WhereToRegisterEventListeners

ModelObservers

Page 224: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

classUserObserver{

publicfunctionsaving($model)

{

//

}

publicfunctionsaved($model)

{

//

}

}

Youmayregisteranobserverinstanceusingtheobservemethod:

User::observe(newUserObserver);

WhenbuildingJSONAPIs,youmayoftenneedtoconvertyourmodelsandrelationshipstoarraysorJSON.So,Eloquentincludesmethodsfordoingso.Toconvertamodelanditsloadedrelationshiptoanarray,youmayusethetoArraymethod:

$user=User::with('roles')->first();

return$user->toArray();

Notethatentirecollectionsofmodelsmayalsobeconvertedtoarrays:

returnUser::all()->toArray();

ToconvertamodeltoJSON,youmayusethetoJsonmethod:

returnUser::find(1)->toJson();

Notethatwhenamodelorcollectioniscasttoastring,itwillbeconvertedtoJSON,meaningyoucanreturnEloquentobjectsdirectlyfromyourapplication'sroutes!

Route::get('users',function()

{

returnUser::all();

});

Sometimesyoumaywishtolimittheattributesthatareincludedinyourmodel'sarrayorJSONform,suchaspasswords.

ConvertingToArrays/JSON

ConvertingAModelToAnArray

ConvertingAModelToJSON

ReturningAModelFromARoute

HidingAttributesFromArrayOrJSONConversion

Page 225: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Todoso,addahiddenpropertydefinitiontoyourmodel:

classUserextendsModel{

protected$hidden=array('password');

}

Note:Whenhidingrelationships,usetherelationship'smethodname,notthedynamicaccessorname.

Alternatively,youmayusethevisiblepropertytodefineawhite-list:

protected$visible=array('first_name','last_name');

Occasionally,youmayneedtoaddarrayattributesthatdonothaveacorrespondingcolumninyourdatabase.Todoso,simplydefineanaccessorforthevalue:

publicfunctiongetIsAdminAttribute()

{

return$this->attributes['admin']=='yes';

}

Onceyouhavecreatedtheaccessor,justaddthevaluetotheappendspropertyonthemodel:

protected$appends=array('is_admin');

Oncetheattributehasbeenaddedtotheappendslist,itwillbeincludedinboththemodel'sarrayandJSONforms.Attributesintheappendsarrayrespectthevisibleandhiddenconfigurationonthemodel.

Page 226: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionCreating&DroppingTablesAddingColumnsChangingColumnsRenamingColumnsDroppingColumnsCheckingExistenceAddingIndexesForeignKeysDroppingIndexesDroppingTimestamps&SoftDeletesStorageEngines

TheLaravelSchemaclassprovidesadatabaseagnosticwayofmanipulatingtables.ItworkswellwithallofthedatabasessupportedbyLaravel,andhasaunifiedAPIacrossallofthesesystems.

Tocreateanewdatabasetable,theSchema::createmethodisused:

Schema::create('users',function($table)

{

$table->increments('id');

});

Thefirstargumentpassedtothecreatemethodisthenameofthetable,andthesecondisaClosurewhichwillreceiveaBlueprintobjectwhichmaybeusedtodefinethenewtable.

Torenameanexistingdatabasetable,therenamemethodmaybeused:

Schema::rename($from,$to);

Tospecifywhichconnectiontheschemaoperationshouldtakeplaceon,usetheSchema::connectionmethod:

Schema::connection('foo')->create('users',function($table)

{

$table->increments('id');

});

Todropatable,youmayusetheSchema::dropmethod:

Schema::drop('users');

Schema::dropIfExists('users');

SchemaBuilder

Introduction

Creating&DroppingTables

AddingColumns

Page 227: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Toupdateanexistingtable,wewillusetheSchema::tablemethod:

Schema::table('users',function($table)

{

$table->string('email');

});

Thetablebuildercontainsavarietyofcolumntypesthatyoumayusewhenbuildingyourtables:

Command Description

$table->bigIncrements('id'); IncrementingIDusinga"biginteger"equivalent.

$table->bigInteger('votes'); BIGINTequivalenttothetable

$table->binary('data'); BLOBequivalenttothetable

$table->boolean('confirmed'); BOOLEANequivalenttothetable

$table->char('name',4); CHARequivalentwithalength

$table->date('created_at'); DATEequivalenttothetable

$table->dateTime('created_at'); DATETIMEequivalenttothetable

$table->decimal('amount',5,2); DECIMALequivalentwithaprecisionandscale

$table->double('column',15,8);DOUBLEequivalentwithprecision,15digitsintotaland8afterthedecimalpoint

$table->enum('choices',array('foo',

'bar'));ENUMequivalenttothetable

$table->float('amount'); FLOATequivalenttothetable

$table->increments('id'); IncrementingIDtothetable(primarykey).

$table->integer('votes'); INTEGERequivalenttothetable

$table->json('options'); JSONequivalenttothetable

$table->longText('description'); LONGTEXTequivalenttothetable

$table->mediumInteger('numbers'); MEDIUMINTequivalenttothetable

$table->mediumText('description'); MEDIUMTEXTequivalenttothetable

$table->morphs('taggable'); AddsINTEGERtaggable_idandSTRINGtaggable_type

$table->nullableTimestamps(); Sameastimestamps(),exceptallowsNULLs

$table->smallInteger('votes'); SMALLINTequivalenttothetable

$table->tinyInteger('numbers'); TINYINTequivalenttothetable

$table->softDeletes(); Addsdeleted_atcolumnforsoftdeletes

$table->string('email'); VARCHARequivalentcolumn

$table->string('name',100); VARCHARequivalentwithalength

$table->text('description'); TEXTequivalenttothetable

$table->time('sunrise'); TIMEequivalenttothetable

$table->timestamp('added_on'); TIMESTAMPequivalenttothetable

$table->timestamps(); Addscreated_atandupdated_atcolumns

$table->rememberToken(); Addsremember_tokenasVARCHAR(100)NULL

->nullable() DesignatethatthecolumnallowsNULLvalues

->default($value) Declareadefaultvalueforacolumn

Page 228: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

->unsigned() SetINTEGERtoUNSIGNED

IfyouareusingtheMySQLdatabase,youmayusetheaftermethodtospecifytheorderofcolumns:

$table->string('name')->after('email');

Sometimesyoumayneedtomodifyanexistingcolumn.Forexample,youmaywishtoincreasethesizeofastringcolumn.Thechangemethodmakesiteasy!Forexample,let'sincreasethesizeofthenamecolumnfrom25to50:

Schema::table('users',function($table)

{

$table->string('name',50)->change();

});

Wecouldalsomodifyacolumntobenullable:

Schema::table('users',function($table)

{

$table->string('name',50)->nullable()->change();

});

Torenameacolumn,youmayusetherenameColumnmethodontheSchemabuilder.Beforerenamingacolumn,besuretoaddthedoctrine/dbaldependencytoyourcomposer.jsonfile.

Schema::table('users',function($table)

{

$table->renameColumn('from','to');

});

Note:Renamingenumcolumntypesisnotsupported.

Todropacolumn,youmayusethedropColumnmethodontheSchemabuilder.Beforedroppingacolumn,besuretoaddthedoctrine/dbaldependencytoyourcomposer.jsonfile.

Schema::table('users',function($table)

{

$table->dropColumn('votes');

});

UsingAfterOnMySQL

ChangingColumns

RenamingColumns

DroppingColumns

DroppingAColumnFromADatabaseTable

DroppingMultipleColumnsFromADatabaseTable

Page 229: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Schema::table('users',function($table)

{

$table->dropColumn(array('votes','avatar','location'));

});

YoumayeasilycheckfortheexistenceofatableorcolumnusingthehasTableandhasColumnmethods:

if(Schema::hasTable('users'))

{

//

}

if(Schema::hasColumn('users','email'))

{

//

}

Theschemabuildersupportsseveraltypesofindexes.Therearetwowaystoaddthem.First,youmayfluentlydefinethemonacolumndefinition,oryoumayaddthemseparately:

$table->string('email')->unique();

Or,youmaychoosetoaddtheindexesonseparatelines.Belowisalistofallavailableindextypes:

Command Description

$table->primary('id'); Addingaprimarykey

$table->primary(array('first','last')); Addingcompositekeys

$table->unique('email'); Addingauniqueindex

$table->index('state'); Addingabasicindex

Laravelalsoprovidessupportforaddingforeignkeyconstraintstoyourtables:

$table->integer('user_id')->unsigned();

$table->foreign('user_id')->references('id')->on('users');

Inthisexample,wearestatingthattheuser_idcolumnreferencestheidcolumnontheuserstable.Makesuretocreatetheforeignkeycolumnfirst!

Youmayalsospecifyoptionsforthe"ondelete"and"onupdate"actionsoftheconstraint:

CheckingExistence

CheckingForExistenceOfTable

CheckingForExistenceOfColumns

AddingIndexes

ForeignKeys

Page 230: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$table->foreign('user_id')

->references('id')->on('users')

->onDelete('cascade');

Todropaforeignkey,youmayusethedropForeignmethod.Asimilarnamingconventionisusedforforeignkeysasisusedforotherindexes:

$table->dropForeign('posts_user_id_foreign');

Note:Whencreatingaforeignkeythatreferencesanincrementinginteger,remembertoalwaysmaketheforeignkeycolumnunsigned.

Todropanindexyoumustspecifytheindex'sname.Laravelassignsareasonablenametotheindexesbydefault.Simplyconcatenatethetablename,thenamesofthecolumnintheindex,andtheindextype.Herearesomeexamples:

Command Description

$table->dropPrimary('users_id_primary'); Droppingaprimarykeyfromthe"users"table

$table->dropUnique('users_email_unique'); Droppingauniqueindexfromthe"users"table

$table->dropIndex('geo_state_index'); Droppingabasicindexfromthe"geo"table

Todropthetimestamps,nullableTimestampsorsoftDeletescolumntypes,youmayusethefollowingmethods:

Command Description

$table->dropTimestamps(); Droppingthecreated_atandupdated_atcolumnsfromthetable

$table->dropSoftDeletes(); Droppingdeleted_atcolumnfromthetable

Tosetthestorageengineforatable,settheenginepropertyontheschemabuilder:

Schema::create('users',function($table)

{

$table->engine='InnoDB';

$table->string('email');

});

DroppingIndexes

DroppingTimestamps&SoftDeletes

StorageEngines

Page 231: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionCreatingMigrationsRunningMigrationsRollingBackMigrationsDatabaseSeeding

Migrationsareatypeofversioncontrolforyourdatabase.Theyallowateamtomodifythedatabaseschemaandstayuptodateonthecurrentschemastate.MigrationsaretypicallypairedwiththeSchemaBuildertoeasilymanageyourapplication'sschema.

Tocreateamigration,youmayusethemake:migrationcommandontheArtisanCLI:

phpartisanmake:migrationcreate_users_table

Themigrationwillbeplacedinyourdatabase/migrationsfolder,andwillcontainatimestampwhichallowstheframeworktodeterminetheorderofthemigrations.

The--tableand--createoptionsmayalsobeusedtoindicatethenameofthetable,andwhetherthemigrationwillbecreatinganewtable:

phpartisanmake:migrationadd_votes_to_user_table--table=users

phpartisanmake:migrationcreate_users_table--create=users

phpartisanmigrate

Note:Ifyoureceivea"classnotfound"errorwhenrunningmigrations,tryrunningthecomposerdump-autoloadcommand.

Somemigrationoperationsaredestructive,meaningtheymaycauseyoutolosedata.Inordertoprotectyoufromrunningthesecommandsagainstyourproductiondatabase,youwillpromptedforconfirmationbeforethesecommandsareexecuted.Toforcethecommandstorunwithoutaprompt,usethe--forceflag:

phpartisanmigrate--force

Migrations&Seeding

Introduction

CreatingMigrations

RunningMigrations

RunningAllOutstandingMigrations

ForcingMigrationsInProduction

Page 232: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

phpartisanmigrate:rollback

phpartisanmigrate:reset

phpartisanmigrate:refresh

phpartisanmigrate:refresh--seed

Laravelalsoincludesasimplewaytoseedyourdatabasewithtestdatausingseedclasses.Allseedclassesarestoredindatabase/seeds.Seedclassesmayhaveanynameyouwish,butprobablyshouldfollowsomesensibleconvention,suchasUserTableSeeder,etc.Bydefault,aDatabaseSeederclassisdefinedforyou.Fromthisclass,youmayusethecallmethodtorunotherseedclasses,allowingyoutocontroltheseedingorder.

classDatabaseSeederextendsSeeder{

publicfunctionrun()

{

$this->call('UserTableSeeder');

$this->command->info('Usertableseeded!');

}

}

classUserTableSeederextendsSeeder{

publicfunctionrun()

{

DB::table('users')->delete();

User::create(array('email'=>'[email protected]'));

}

}

Toseedyourdatabase,youmayusethedb:seedcommandontheArtisanCLI:

phpartisandb:seed

Bydefault,thedb:seedcommandrunstheDatabaseSeederclass,whichmaybeusedtocallotherseedclasses.However,youmayusethe--classoptiontospecifyaspecificseederclasstorunindividually:

phpartisandb:seed--class=UserTableSeeder

RollingBackMigrations

RollbackTheLastMigrationOperation

Rollbackallmigrations

Rollbackallmigrationsandrunthemallagain

DatabaseSeeding

ExampleDatabaseSeedClass

Page 233: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Youmayalsoseedyourdatabaseusingthemigrate:refreshcommand,whichwillalsorollbackandre-runallofyourmigrations:

phpartisanmigrate:refresh--seed

Page 234: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionConfigurationUsagePipelining

Redisisanopensource,advancedkey-valuestore.Itisoftenreferredtoasadatastructureserversincekeyscancontainstrings,hashes,lists,sets,andsortedsets.

BeforeusingRediswithLaravel,youwillneedtoinstallthepredis/predispackage(~1.0)viaComposer.

Note:IfyouhavetheRedisPHPextensioninstalledviaPECL,youwillneedtorenamethealiasforRedisinyourconfig/app.phpfile.

TheRedisconfigurationforyourapplicationisstoredintheconfig/database.phpfile.Withinthisfile,youwillseearedisarraycontainingtheRedisserversusedbyyourapplication:

'redis'=>[

'cluster'=>true,

'default'=>['host'=>'127.0.0.1','port'=>6379],

],

Thedefaultserverconfigurationshouldsufficefordevelopment.However,youarefreetomodifythisarraybasedonyourenvironment.SimplygiveeachRedisserveraname,andspecifythehostandportusedbytheserver.

TheclusteroptionwilltelltheLaravelRedisclienttoperformclient-sideshardingacrossyourRedisnodes,allowingyoutopoolnodesandcreatealargeamountofavailableRAM.However,notethatclient-sideshardingdoesnothandlefailover;therefore,isprimarilysuitedforcacheddatathatisavailablefromanotherprimarydatastore.

IfyourRedisserverrequiresauthentication,youmaysupplyapasswordbyaddingapasswordkey/valuepairtoyourRedisserverconfigurationarray.

YoumaygetaRedisinstancebycallingtheRedis::connectionmethod:

$redis=Redis::connection();

ThiswillgiveyouaninstanceofthedefaultRedisserver.Ifyouarenotusingserverclustering,youmaypasstheservernametotheconnectionmethodtogetaspecificserverasdefinedinyourRedisconfiguration:

$redis=Redis::connection('other');

Redis

Introduction

Configuration

Usage

Page 235: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

OnceyouhaveaninstanceoftheRedisclient,wemayissueanyoftheRediscommandstotheinstance.LaravelusesmagicmethodstopassthecommandstotheRedisserver:

$redis->set('name','Taylor');

$name=$redis->get('name');

$values=$redis->lrange('names',5,10);

Noticetheargumentstothecommandaresimplypassedintothemagicmethod.Ofcourse,youarenotrequiredtousethemagicmethods,youmayalsopasscommandstotheserverusingthecommandmethod:

$values=$redis->command('lrange',array(5,10));

Whenyouaresimplyexecutingcommandsagainstthedefaultconnection,justusestaticmagicmethodsontheRedisclass:

Redis::set('name','Taylor');

$name=Redis::get('name');

$values=Redis::lrange('names',5,10);

Note:RediscacheandsessiondriversareincludedwithLaravel.

Pipeliningshouldbeusedwhenyouneedtosendmanycommandstotheserverinoneoperation.Togetstarted,usethepipelinecommand:

Redis::pipeline(function($pipe)

{

for($i=0;$i<1000;$i++)

{

$pipe->set("key:$i",$i);

}

});

Pipelining

PipingManyCommandsToYourServers

Page 236: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

OverviewIntroductionUsageCallingCommandsOutsideOfCLISchedulingArtisanCommands

DevelopmentIntroductionBuildingACommandRegisteringCommands

ArtisanCLI

Page 237: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionUsageCallingCommandsOutsideOfCLISchedulingArtisanCommands

Artisanisthenameofthecommand-lineinterfaceincludedwithLaravel.Itprovidesanumberofhelpfulcommandsforyourusewhiledevelopingyourapplication.ItisdrivenbythepowerfulSymfonyConsolecomponent.

ToviewalistofallavailableArtisancommands,youmayusethelistcommand:

phpartisanlist

Everycommandalsoincludesa"help"screenwhichdisplaysanddescribesthecommand'savailableargumentsandoptions.Toviewahelpscreen,simplyprecedethenameofthecommandwithhelp:

phpartisanhelpmigrate

Youmayspecifytheconfigurationenvironmentthatshouldbeusedwhilerunningacommandusingthe--envswitch:

phpartisanmigrate--env=local

YoumayalsoviewthecurrentversionofyourLaravelinstallationusingthe--versionoption:

phpartisan--version

SometimesyoumaywishtoexecuteanArtisancommandoutsideoftheCLI.Forexample,youmaywishtofireanArtisancommandfromanHTTProute.JustusetheArtisanfacade:

Route::get('/foo',function()

{

$exitCode=Artisan::call('command:name',['--option'=>'foo']);

ArtisanCLI

Introduction

Usage

ListingAllAvailableCommands

ViewingTheHelpScreenForACommand

SpecifyingTheConfigurationEnvironment

DisplayingYourCurrentLaravelVersion

CallingCommandsOutsideOfCLI

Page 238: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

//

});

YoumayevenqueueArtisancommandssotheyareprocessedinthebackgroundbyyourqueueworkers:

Route::get('/foo',function()

{

Artisan::queue('command:name',['--option'=>'foo']);

//

});

Inthepast,developershavegeneratedaCronentryforeachconsolecommandtheywishedtoschedule.However,thisisaheadache.Yourconsolescheduleisnolongerinsourcecontrol,andyoumustSSHintoyourservertoaddtheCronentries.Let'smakeourliveseasier.TheLaravelcommandschedulerallowsyoutofluentlyandexpressivelydefineyourcommandschedulewithinLaravelitself,andonlyasingleCronentryisneededonyourserver.

Yourcommandscheduleisstoredintheapp/Console/Kernel.phpfile.Withinthisclassyouwillseeaschedulemethod.Tohelpyougetstarted,asimpleexampleisincludedwiththemethod.YouarefreetoaddasmanyscheduledjobsasyouwishtotheScheduleobject.TheonlyCronentryyouneedtoaddtoyourserveristhis:

*****php/path/to/artisanschedule:run1>>/dev/null2>&1

ThisCronwillcalltheLaravelcommandschedulereveryminute.Then,Laravelevaluatesyourscheduledjobsandrunsthejobsthataredue.Itcouldn'tbeeasier!

Let'slookatafewmoreschedulingexamples:

$schedule->call(function()

{

//Dosometask...

})->hourly();

$schedule->exec('composerself-update')->daily();

$schedule->command('foo')->cron('*****');

$schedule->command('foo')->everyFiveMinutes();

SchedulingArtisanCommands

MoreSchedulingExamples

SchedulingClosures

SchedulingTerminalCommands

ManualCronExpression

FrequentJobs

Page 239: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

$schedule->command('foo')->everyTenMinutes();

$schedule->command('foo')->everyThirtyMinutes();

$schedule->command('foo')->daily();

$schedule->command('foo')->dailyAt('15:00');

$schedule->command('foo')->twiceDaily();

$schedule->command('foo')->weekdays();

$schedule->command('foo')->weekly();

//Scheduleweeklyjobforspecificday(0-6)andtime...

$schedule->command('foo')->weeklyOn(1,'8:00');

$schedule->command('foo')->monthly();

$schedule->command('foo')->monthly()->environments('production');

$schedule->command('foo')->monthly()->evenInMaintenanceMode();

$schedule->command('foo')->monthly()->when(function()

{

returntrue;

});

DailyJobs

DailyJobsAtASpecificTime(24HourTime)

TwiceDailyJobs

JobThatRunsEveryWeekday

WeeklyJobs

MonthlyJobs

LimitTheEnvironmentTheJobsShouldRunIn

IndicateTheJobShouldRunEvenWhenApplicationIsInMaintenanceMode

OnlyAllowJobToRunWhenCallbackIsTrue

Page 240: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

IntroductionBuildingACommandRegisteringCommands

InadditiontothecommandsprovidedwithArtisan,youmayalsobuildyourowncustomcommandsforworkingwithyourapplication.Youmaystoreyourcustomcommandsintheapp/Console/Commandsdirectory;however,youarefreetochooseyourownstoragelocationaslongasyourcommandscanbeautoloadedbasedonyourcomposer.jsonsettings.

Tocreateanewcommand,youmayusethemake:consoleArtisancommand,whichwillgenerateacommandstubtohelpyougetstarted:

phpartisanmake:consoleFooCommand

Thecommandabovewouldgenerateaclassatapp/Console/FooCommand.php.

Whencreatingthecommand,the--commandoptionmaybeusedtoassigntheterminalcommandname:

phpartisanmake:consoleAssignUsers--command=users:assign

Onceyourcommandisgenerated,youshouldfilloutthenameanddescriptionpropertiesoftheclass,whichwillbeusedwhendisplayingyourcommandonthelistscreen.

Thefiremethodwillbecalledwhenyourcommandisexecuted.Youmayplaceanycommandlogicinthismethod.

ThegetArgumentsandgetOptionsmethodsarewhereyoumaydefineanyargumentsoroptionsyourcommandreceives.Bothofthesemethodsreturnanarrayofcommands,whicharedescribedbyalistofarrayoptions.

Whendefiningarguments,thearraydefinitionvaluesrepresentthefollowing:

array($name,$mode,$description,$defaultValue)

Theargumentmodemaybeanyofthefollowing:InputArgument::REQUIREDorInputArgument::OPTIONAL.

Whendefiningoptions,thearraydefinitionvaluesrepresentthefollowing:

ArtisanDevelopment

Introduction

BuildingACommand

GeneratingTheClass

GenerateANewCommandClass

WritingTheCommand

Arguments&Options

Page 241: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

array($name,$shortcut,$mode,$description,$defaultValue)

Foroptions,theargumentmodemaybe:InputOption::VALUE_REQUIRED,InputOption::VALUE_OPTIONAL,InputOption::VALUE_IS_ARRAY,InputOption::VALUE_NONE.

TheVALUE_IS_ARRAYmodeindicatesthattheswitchmaybeusedmultipletimeswhencallingthecommand:

phpartisanfoo--option=bar--option=baz

TheVALUE_NONEoptionindicatesthattheoptionissimplyusedasa"switch":

phpartisanfoo--option

Whileyourcommandisexecuting,youwillobviouslyneedtoaccessthevaluesfortheargumentsandoptionsacceptedbyyourapplication.Todoso,youmayusetheargumentandoptionmethods:

$value=$this->argument('name');

$arguments=$this->argument();

$value=$this->option('name');

$options=$this->option();

Tosendoutputtotheconsole,youmayusetheinfo,comment,questionanderrormethods.EachofthesemethodswillusetheappropriateANSIcolorsfortheirpurpose.

$this->info('Displaythisonthescreen');

$this->error('Somethingwentwrong!');

RetrievingInput

RetrievingTheValueOfACommandArgument

RetrievingAllArguments

RetrievingTheValueOfACommandOption

RetrievingAllOptions

WritingOutput

SendingInformationToTheConsole

SendingAnErrorMessageToTheConsole

Page 242: Table of Contents · Laravel 5.0 Laravel 4.2 Laravel 4.1 Laravel 5.0 introduces a fresh application structure to the default Laravel project. This new structure serves as a better

Youmayalsousetheaskandconfirmmethodstoprompttheuserforinput:

$name=$this->ask('Whatisyourname?');

$password=$this->secret('Whatisthepassword?');

if($this->confirm('Doyouwishtocontinue?[yes|no]'))

{

//

}

Youmayalsospecifyadefaultvaluetotheconfirmmethod,whichshouldbetrueorfalse:

$this->confirm($question,true);

Sometimesyoumaywishtocallothercommandsfromyourcommand.Youmaydosousingthecallmethod:

$this->call('command:name',['argument'=>'foo','--option'=>'bar']);

Onceyourcommandisfinished,youneedtoregisteritwithArtisansoitwillbeavailableforuse.Thisistypicallydoneintheapp/Console/Kernel.phpfile.Withinthisfile,youwillfindalistofcommandsinthecommandsproperty.Toregisteryourcommand,simplyaddittothislist.WhenArtisanboots,allthecommandslistedinthispropertywillberesolvedbytheIoCcontainerandregisteredwithArtisan.

AskingQuestions

AskingTheUserForInput

AskingTheUserForSecretInput

AskingTheUserForConfirmation

CallingOtherCommands

RegisteringCommands

RegisteringAnArtisanCommand