Laravel 5.0 Documentation
-
Upload
bartos-gabor -
Category
Documents
-
view
40 -
download
5
description
Transcript of Laravel 5.0 Documentation
![Page 1: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/1.jpg)
![Page 2: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/2.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/3.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/4.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/5.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/6.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/7.jpg)
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 9: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/9.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/10.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/11.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/12.jpg)
*/
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/13.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/14.jpg)
}
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/15.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/16.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/17.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/18.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/19.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/20.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/21.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/22.jpg)
'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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/23.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/24.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/25.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/26.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/27.jpg)
(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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/28.jpg)
InstallationInstallComposerInstallLaravelServerRequirements
ConfigurationIntroductionAfterInstallationAccessingConfigurationValuesEnvironmentConfigurationConfigurationCachingMaintenanceModePrettyURLs
HomesteadIntroductionIncludedSoftwareInstallation&SetupDailyUsagePorts
Setup
![Page 29: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/29.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/30.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/31.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/32.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/33.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/34.jpg)
location/{
try_files$uri$uri//index.php?$query_string;
}
Ofcourse,whenusingHomestead,prettyURLswillbeconfiguredautomatically.
![Page 35: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/35.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/36.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/37.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/38.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/39.jpg)
RoutingBasicRoutingCSRFProtectionMethodSpoofingRouteParametersNamedRoutesRouteGroupsRouteModelBindingThrowing404Errors
MiddlewareIntroductionDefiningMiddlewareRegisteringMiddlewareTerminableMiddleware
ControllersIntroductionBasicControllersControllerMiddlewareImplicitControllersRESTfulResourceControllersDependencyInjection&ControllersRouteCaching
RequestsObtainingARequestInstanceRetrievingInputOldInputCookiesFilesOtherRequestInformation
ResponsesBasicResponsesRedirectsOtherResponsesResponseMacros
ViewsBasicUsageViewComposers
TheBasics
![Page 40: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/40.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/41.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/42.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/43.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/44.jpg)
});
});
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/45.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/46.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/47.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/48.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/49.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/50.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/51.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/52.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/53.jpg)
<?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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/54.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/55.jpg)
*@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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/56.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/57.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/58.jpg)
$method=Request::method();
if(Request::isMethod('post'))
{
//
}
if(Request::is('admin/*'))
{
//
}
$url=Request::url();
RetrievingTheRequestMethod
DeterminingIfTheRequestPathMatchesAPattern
GetTheCurrentRequestURL
![Page 59: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/59.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/60.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/61.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/62.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/63.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/64.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/65.jpg)
//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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/66.jpg)
});
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/67.jpg)
ServiceProvidersIntroductionBasicProviderExampleRegisteringProvidersDeferredProviders
ServiceContainerIntroductionBasicUsageBindingInterfacesToImplementationsContextualBindingTaggingPracticalApplicationsContainerEvents
ContractsIntroductionWhyContracts?ContractReferenceHowToUseContracts
FacadesIntroductionExplanationPracticalUsageCreatingFacadesMockingFacadesFacadeClassReference
RequestLifecycleIntroductionLifecycleOverviewFocusOnServiceProviders
ApplicationStructureIntroductionTheRootDirectoryTheAppDirectoryNamespacingYourApplication
ArchitectureFoundations
![Page 68: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/68.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/69.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/70.jpg)
'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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/71.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/72.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/73.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/74.jpg)
*
*@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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/75.jpg)
->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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/76.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/77.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/78.jpg)
}
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/79.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/80.jpg)
}
/**
*Handletheevent.
*
*@paramNewUserRegistered$event
*@returnvoid
*/
publicfunctionhandle(NewUserRegistered$event)
{
//
}
}
Whentheeventlistenerisresolved,theservicecontainerwillreadthetype-hintsontheconstructoroftheclass,andinjecttheappropriatevalue.Tolearnmoreaboutregisteringthingsintheservicecontainer,checkoutthedocumentation.
![Page 81: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/81.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/82.jpg)
}
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/83.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/84.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/85.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/86.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/87.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/88.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/89.jpg)
AuthenticationIntroductionAuthenticatingUsersRetrievingTheAuthenticatedUserProtectingRoutesHTTPBasicAuthenticationPasswordReminders&ResetSocialAuthentication
BillingIntroductionConfigurationSubscribingToAPlanNoCardUpFrontSwappingSubscriptionsSubscriptionQuantityCancellingASubscriptionResumingASubscriptionCheckingSubscriptionStatusHandlingFailedPaymentsHandlingOtherStripeWebhooksInvoices
CacheConfigurationCacheUsageIncrements&DecrementsCacheTagsDatabaseCache
CollectionsIntroductionBasicUsage
CommandBusIntroductionCreatingCommandsDispatchingCommandsQueuedCommandsCommandPipeline
CoreExtensionManagers&FactoriesCacheSessionAuthenticationIoCBasedExtension
ElixirIntroductionInstallation&SetupUsageGulpExtensions
EncryptionIntroductionBasicUsage
Errors&Logging
Services
![Page 90: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/90.jpg)
ConfigurationHandlingErrorsHTTPExceptionsLogging
EventsBasicUsageQueuedEventHandlersEventSubscribers
Filesystem/CloudStorageIntroductionConfigurationBasicUsage
HashingIntroductionBasicUsage
HelpersArraysPathsStringsURLsMiscellaneous
LocalizationIntroductionLanguageFilesBasicUsagePluralizationValidationLocalizationOverridingPackageLanguageFiles
MailConfigurationBasicUsageEmbeddingInlineAttachmentsQueueingMailMail&LocalDevelopment
PackageDevelopmentIntroductionViewsTranslationsConfigurationPublishingFileGroupsRouting
PaginationConfigurationUsageAppendingToPaginationLinksConvertingToJSON
QueuesConfigurationBasicUsageQueueingClosuresRunningTheQueueListenerDaemonQueueWorkerPushQueuesFailedJobs
SessionConfiguration
![Page 91: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/91.jpg)
SessionUsageFlashDataDatabaseSessionsSessionDrivers
TemplatesBladeTemplatingOtherBladeControlStructuresExtendingBlade
UnitTestingIntroductionDefining&RunningTestsTestEnvironmentCallingRoutesFromTestsMockingFacadesFrameworkAssertionsHelperMethodsRefreshingTheApplication
ValidationBasicUsageControllerValidationFormRequestValidationWorkingWithErrorMessagesErrorMessages&ViewsAvailableValidationRulesConditionallyAddingRulesCustomErrorMessagesCustomValidationRules
![Page 92: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/92.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/93.jpg)
<?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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/94.jpg)
{
//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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/95.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/96.jpg)
*
*@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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/97.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/98.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/99.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/100.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/101.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/102.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/103.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/104.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/105.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/106.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/107.jpg)
Schema::create('cache',function($table)
{
$table->string('key')->unique();
$table->text('value');
$table->integer('expiration');
});
![Page 108: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/108.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/109.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/110.jpg)
*/
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/111.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/112.jpg)
}
}
}
CommandpipeclassesareresolvedthroughtheIoCcontainer,sofeelfreetotype-hintanydependenciesyouneedwithintheirconstructors.
YoumayevendefineaClosureasacommandpipe:
$dispatcher->pipeThrough([function($command,$next)
{
returnDB::transaction(function()use($command,$next)
{
return$next($command);
}
}]);
![Page 113: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/113.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/114.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/115.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/116.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/117.jpg)
extendedtheserviceprovider,swapouttheHashServiceProviderinyourconfig/app.phpconfigurationfilewiththenameofyourextendedprovider.
Thisisthegeneralmethodofextendinganycoreclassthatisboundinthecontainer.Essentiallyeverycoreclassisboundinthecontainerinthisfashion,andcanbeoverridden.Again,readingthroughtheincludedframeworkserviceproviderswillfamiliarizeyouwithwherevariousclassesareboundintothecontainer,andwhatkeystheyareboundby.ThisisagreatwaytolearnmoreabouthowLaravelisputtogether.
![Page 118: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/118.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/119.jpg)
});
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/120.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/121.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/122.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/123.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/124.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/125.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/126.jpg)
$monolog=Log::getMonolog();
Youmayalsoregisteraneventtocatchallmessagespassedtothelog:
Log::listen(function($level,$message,$context)
{
//
});
RegisteringALogEventListener
![Page 127: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/127.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/128.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/129.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/130.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/131.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/132.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/133.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/134.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/135.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/136.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/137.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/138.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/139.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/140.jpg)
//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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/141.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/142.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/143.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/144.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/145.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/146.jpg)
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.
Configuration
APIDrivers
MailgunDriver
MandrillDriver
LogDriver
BasicUsage
![Page 147: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/147.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/148.jpg)
<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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/149.jpg)
![Page 150: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/150.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/151.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/152.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/153.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/154.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/155.jpg)
viathedatakeyintheJSONarray.
![Page 156: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/156.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/157.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/158.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/159.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/160.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/161.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/162.jpg)
Ifyouwouldliketodeleteafailedjob,youmayusethequeue:forgetcommand:
phpartisanqueue:forget5
Todeleteallofyourfailedjobs,youmayusethequeue:flushcommand:
phpartisanqueue:flush
![Page 163: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/163.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/164.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/165.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/166.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/167.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/168.jpg)
@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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/169.jpg)
![Page 170: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/170.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/171.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/172.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/173.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/174.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/175.jpg)
//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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/176.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/177.jpg)
{
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/178.jpg)
{
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/179.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/180.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/181.jpg)
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
![Page 182: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/182.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/183.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/184.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/185.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/186.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/187.jpg)
}
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/188.jpg)
BasicUsageConfigurationRead/WriteConnectionsRunningQueriesDatabaseTransactionsAccessingConnectionsQueryLogging
QueryBuilderIntroductionSelectsJoinsAdvancedWheresAggregatesRawExpressionsInsertsUpdatesDeletesUnionsPessimisticLocking
EloquentORMIntroductionBasicUsageMassAssignmentInsert,Update,DeleteSoftDeletingTimestampsQueryScopesGlobalScopesRelationshipsQueryingRelationsEagerLoadingInsertingRelatedModelsTouchingParentTimestampsWorkingWithPivotTablesCollectionsAccessors&MutatorsDateMutatorsAttributeCastingModelEventsModelObserversConvertingToArrays/JSON
SchemaBuilderIntroductionCreating&DroppingTablesAddingColumnsChangingColumnsRenamingColumnsDroppingColumnsCheckingExistenceAddingIndexesForeignKeysDroppingIndexes
Database
![Page 189: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/189.jpg)
DroppingTimestamps&SoftDeletesStorageEngines
Migrations&SeedingIntroductionCreatingMigrationsRunningMigrationsRollingBackMigrationsDatabaseSeeding
RedisIntroductionConfigurationUsagePipelining
![Page 190: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/190.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/191.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/192.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/193.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/194.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/195.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/196.jpg)
->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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/197.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/198.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/199.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/200.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/201.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/202.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/203.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/204.jpg)
//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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/205.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/206.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/207.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/208.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/209.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/210.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/211.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/212.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/213.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/214.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/215.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/216.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/217.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/218.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/219.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/220.jpg)
}
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/221.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/222.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/223.jpg)
*/
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/224.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/225.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/226.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/227.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/228.jpg)
->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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/229.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/230.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/231.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/232.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/233.jpg)
Youmayalsoseedyourdatabaseusingthemigrate:refreshcommand,whichwillalsorollbackandre-runallofyourmigrations:
phpartisanmigrate:refresh--seed
![Page 234: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/234.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/235.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/236.jpg)
OverviewIntroductionUsageCallingCommandsOutsideOfCLISchedulingArtisanCommands
DevelopmentIntroductionBuildingACommandRegisteringCommands
ArtisanCLI
![Page 237: Laravel 5.0 Documentation](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/237.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/238.jpg)
//
});
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/239.jpg)
$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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/240.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/241.jpg)
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](https://reader030.fdocuments.us/reader030/viewer/2022012406/5695cf1d1a28ab9b028caab1/html5/thumbnails/242.jpg)
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