laravel 5.0 documentation

242

Upload: bartos-gabor

Post on 26-Jan-2016

56 views

Category:

Documents


5 download

DESCRIPTION

laravel documentation

TRANSCRIPT

Page 1: Laravel 5.0 Documentation
Page 2: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

AGitBookversionofLaravel5.0Documentation

Introduction

Page 9: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

*/

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

}

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

'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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

(Freenode).

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

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

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

SecurityVulnerabilities

CodingStyle

Page 28: Laravel 5.0 Documentation

InstallationInstallComposerInstallLaravelServerRequirements

ConfigurationIntroductionAfterInstallationAccessingConfigurationValuesEnvironmentConfigurationConfigurationCachingMaintenanceModePrettyURLs

HomesteadIntroductionIncludedSoftwareInstallation&SetupDailyUsagePorts

Setup

Page 29: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

location/{

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

}

Ofcourse,whenusingHomestead,prettyURLswillbeconfiguredautomatically.

Page 35: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

RoutingBasicRoutingCSRFProtectionMethodSpoofingRouteParametersNamedRoutesRouteGroupsRouteModelBindingThrowing404Errors

MiddlewareIntroductionDefiningMiddlewareRegisteringMiddlewareTerminableMiddleware

ControllersIntroductionBasicControllersControllerMiddlewareImplicitControllersRESTfulResourceControllersDependencyInjection&ControllersRouteCaching

RequestsObtainingARequestInstanceRetrievingInputOldInputCookiesFilesOtherRequestInformation

ResponsesBasicResponsesRedirectsOtherResponsesResponseMacros

ViewsBasicUsageViewComposers

TheBasics

Page 40: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

});

});

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

<?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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

*@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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$method=Request::method();

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

{

//

}

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

{

//

}

$url=Request::url();

RetrievingTheRequestMethod

DeterminingIfTheRequestPathMatchesAPattern

GetTheCurrentRequestURL

Page 59: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

//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: Laravel 5.0 Documentation

});

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: Laravel 5.0 Documentation

ServiceProvidersIntroductionBasicProviderExampleRegisteringProvidersDeferredProviders

ServiceContainerIntroductionBasicUsageBindingInterfacesToImplementationsContextualBindingTaggingPracticalApplicationsContainerEvents

ContractsIntroductionWhyContracts?ContractReferenceHowToUseContracts

FacadesIntroductionExplanationPracticalUsageCreatingFacadesMockingFacadesFacadeClassReference

RequestLifecycleIntroductionLifecycleOverviewFocusOnServiceProviders

ApplicationStructureIntroductionTheRootDirectoryTheAppDirectoryNamespacingYourApplication

ArchitectureFoundations

Page 68: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

'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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

*

*@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: Laravel 5.0 Documentation

->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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

}

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

}

/**

*Handletheevent.

*

*@paramNewUserRegistered$event

*@returnvoid

*/

publicfunctionhandle(NewUserRegistered$event)

{

//

}

}

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

Page 81: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

}

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

AuthenticationIntroductionAuthenticatingUsersRetrievingTheAuthenticatedUserProtectingRoutesHTTPBasicAuthenticationPasswordReminders&ResetSocialAuthentication

BillingIntroductionConfigurationSubscribingToAPlanNoCardUpFrontSwappingSubscriptionsSubscriptionQuantityCancellingASubscriptionResumingASubscriptionCheckingSubscriptionStatusHandlingFailedPaymentsHandlingOtherStripeWebhooksInvoices

CacheConfigurationCacheUsageIncrements&DecrementsCacheTagsDatabaseCache

CollectionsIntroductionBasicUsage

CommandBusIntroductionCreatingCommandsDispatchingCommandsQueuedCommandsCommandPipeline

CoreExtensionManagers&FactoriesCacheSessionAuthenticationIoCBasedExtension

ElixirIntroductionInstallation&SetupUsageGulpExtensions

EncryptionIntroductionBasicUsage

Errors&Logging

Services

Page 90: Laravel 5.0 Documentation

ConfigurationHandlingErrorsHTTPExceptionsLogging

EventsBasicUsageQueuedEventHandlersEventSubscribers

Filesystem/CloudStorageIntroductionConfigurationBasicUsage

HashingIntroductionBasicUsage

HelpersArraysPathsStringsURLsMiscellaneous

LocalizationIntroductionLanguageFilesBasicUsagePluralizationValidationLocalizationOverridingPackageLanguageFiles

MailConfigurationBasicUsageEmbeddingInlineAttachmentsQueueingMailMail&LocalDevelopment

PackageDevelopmentIntroductionViewsTranslationsConfigurationPublishingFileGroupsRouting

PaginationConfigurationUsageAppendingToPaginationLinksConvertingToJSON

QueuesConfigurationBasicUsageQueueingClosuresRunningTheQueueListenerDaemonQueueWorkerPushQueuesFailedJobs

SessionConfiguration

Page 91: Laravel 5.0 Documentation

SessionUsageFlashDataDatabaseSessionsSessionDrivers

TemplatesBladeTemplatingOtherBladeControlStructuresExtendingBlade

UnitTestingIntroductionDefining&RunningTestsTestEnvironmentCallingRoutesFromTestsMockingFacadesFrameworkAssertionsHelperMethodsRefreshingTheApplication

ValidationBasicUsageControllerValidationFormRequestValidationWorkingWithErrorMessagesErrorMessages&ViewsAvailableValidationRulesConditionallyAddingRulesCustomErrorMessagesCustomValidationRules

Page 92: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

<?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: Laravel 5.0 Documentation

{

//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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

*

*@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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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

{

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

$table->text('value');

$table->integer('expiration');

});

Page 108: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

*/

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

}

}

}

CommandpipeclassesareresolvedthroughtheIoCcontainer,sofeelfreetotype-hintanydependenciesyouneedwithintheirconstructors.

YoumayevendefineaClosureasacommandpipe:

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

{

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

{

return$next($command);

}

}]);

Page 113: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

extendedtheserviceprovider,swapouttheHashServiceProviderinyourconfig/app.phpconfigurationfilewiththenameofyourextendedprovider.

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

Page 118: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

});

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$monolog=Log::getMonolog();

Youmayalsoregisteraneventtocatchallmessagespassedtothelog:

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

{

//

});

RegisteringALogEventListener

Page 127: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

//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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

Dumpthegivenvariableandendexecutionofthescript.

dd($value);

IfthegivenvalueisaClosure,returnthevaluereturnedbytheClosure.Otherwise,returnthevalue.

$value=value(function(){return'bar';});

Returnthegivenobject.UsefulformethodchainingconstructorsinPHP5.3.x.

$value=with(newFoo)->doWork();

value

with

Page 143: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

<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: Laravel 5.0 Documentation
Page 150: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

viathedatakeyintheJSONarray.

Page 156: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

Ifyouwouldliketodeleteafailedjob,youmayusethequeue:forgetcommand:

phpartisanqueue:forget5

Todeleteallofyourfailedjobs,youmayusethequeue:flushcommand:

phpartisanqueue:flush

Page 163: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

@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: Laravel 5.0 Documentation
Page 170: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

//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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

{

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: Laravel 5.0 Documentation

{

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

}

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: Laravel 5.0 Documentation

BasicUsageConfigurationRead/WriteConnectionsRunningQueriesDatabaseTransactionsAccessingConnectionsQueryLogging

QueryBuilderIntroductionSelectsJoinsAdvancedWheresAggregatesRawExpressionsInsertsUpdatesDeletesUnionsPessimisticLocking

EloquentORMIntroductionBasicUsageMassAssignmentInsert,Update,DeleteSoftDeletingTimestampsQueryScopesGlobalScopesRelationshipsQueryingRelationsEagerLoadingInsertingRelatedModelsTouchingParentTimestampsWorkingWithPivotTablesCollectionsAccessors&MutatorsDateMutatorsAttributeCastingModelEventsModelObserversConvertingToArrays/JSON

SchemaBuilderIntroductionCreating&DroppingTablesAddingColumnsChangingColumnsRenamingColumnsDroppingColumnsCheckingExistenceAddingIndexesForeignKeysDroppingIndexes

Database

Page 189: Laravel 5.0 Documentation

DroppingTimestamps&SoftDeletesStorageEngines

Migrations&SeedingIntroductionCreatingMigrationsRunningMigrationsRollingBackMigrationsDatabaseSeeding

RedisIntroductionConfigurationUsagePipelining

Page 190: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

->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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

DB::table('users')->where('votes','>',100)->sharedLock()->get();

To"lockforupdate"onaSELECTstatement,youmayusethelockForUpdatemethodonaquery:

DB::table('users')->where('votes','>',100)->lockForUpdate()->get();

Page 200: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

//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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

}

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

*/

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

->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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

Youmayalsoseedyourdatabaseusingthemigrate:refreshcommand,whichwillalsorollbackandre-runallofyourmigrations:

phpartisanmigrate:refresh--seed

Page 234: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

OverviewIntroductionUsageCallingCommandsOutsideOfCLISchedulingArtisanCommands

DevelopmentIntroductionBuildingACommandRegisteringCommands

ArtisanCLI

Page 237: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

//

});

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: Laravel 5.0 Documentation

$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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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: Laravel 5.0 Documentation

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