laravel: up and running · 2018. 8. 1. · laravel is a powerful and flexible php framework. it has...

795

Upload: others

Post on 25-Jan-2021

5 views

Category:

Documents


0 download

TRANSCRIPT

  • Laravel:UpandRunningAFrameworkforBuildingModernPHPApps

    MattStauffer

  • Laravel:UpandRunningbyMattStauffer

    Copyright©2017MattStauffer.Allrightsreserved.

    PrintedintheUnitedStatesofAmerica.

    PublishedbyO’ReillyMedia,Inc.,1005GravensteinHighwayNorth,Sebastopol,CA95472.

    O’Reillybooksmaybepurchasedforeducational,business,orsalespromotionaluse.Onlineeditionsarealsoavailableformosttitles(http://oreilly.com/safari).Formoreinformation,contactourcorporate/institutionalsalesdepartment:[email protected].

    Editor:AllysonMacDonald

    ProductionEditor:ColleenLobner

    Copyeditor:RachelHead

    Proofreader:KimCofer

    Indexer:AngelaHoward

    InteriorDesigner:DavidFutato

    CoverDesigner:RandyComer

    Illustrator:RebeccaDemarest

    December2016:FirstEdition

    http://oreilly.com/safari

  • RevisionHistoryfortheFirstEdition2016-11-14:FirstRelease

    Seehttp://oreilly.com/catalog/errata.csp?isbn=9781491936085forreleasedetails.

    TheO’ReillylogoisaregisteredtrademarkofO’ReillyMedia,Inc.Laravel:UpandRunning,thecoverimageofagemsbok,andrelatedtradedressaretrademarksofO’ReillyMedia,Inc.

    Whilethepublisherandtheauthorhaveusedgoodfaitheffortstoensurethattheinformationandinstructionscontainedinthisworkareaccurate,thepublisherandtheauthordisclaimallresponsibilityforerrorsoromissions,includingwithoutlimitationresponsibilityfordamagesresultingfromtheuseoforrelianceonthiswork.Useoftheinformationandinstructionscontainedinthisworkisatyourownrisk.Ifanycodesamplesorothertechnologythisworkcontainsordescribesissubjecttoopensourcelicensesortheintellectualpropertyrightsofothers,itisyourresponsibilitytoensurethatyourusethereofcomplieswithsuchlicensesand/orrights.

    978-1-491-93608-5

    [LSI]

    http://oreilly.com/catalog/errata.csp?isbn=9781491936085

  • DedicationThisbookisdedicatedtomygraciousandinspiringwife,Tereva,myjoyfulandcourageousson,Malachi,andmybeautifuldaughter,Mia,whospentthemajorityofthisbook’screationinhermama’sbelly.

  • Preface

    ThestoryofhowIgotstartedwithLaravelisacommonone:IhadwrittenPHPforyears,butIwasonmywayoutthedoor,pursuingthepowerofRailsandothermodernwebframeworks.Railsinparticularhadalivelycommunity,aperfectcombinationofopinionateddefaultsandflexibility,andthepowerofRubyGemstoleverageprepackagedcommoncode.

    Somethingkeptmefromjumpingship,andIwasgladforthatwhenIfoundLaravel.ItofferedeverythingIwasdrawntoinRails,butitwasn’tjustaRailsclone;thiswasaninnovativeframeworkwithincredibledocumentation,awelcomingcommunity,andclearinfluencesfrommanylanguagesandframeworks.

    SincethatdayI’vebeenabletosharemyjourneyoflearningLaravelthroughbloggingandspeakingatconferences;I’vewrittendozensofappsinLaravelforsideandworkprojects,andI’vemetthousandsofLaraveldevelopersonlineandinperson.Ihaveplentyoftoolsinmytoolkitatourconsultancy,butIamhonestlyhappiestwhenIsitdowninfrontofacommandlineandtypelaravelnewproject.

  • WhatThisBookIsAboutThisisnotthefirstbookaboutLaravel,anditwon’tbethelast.Idon’tintendforthistobeabookthatcoverseverylineofcodeoreveryimplementationpattern.Idon’twantthistobethesortofbookthatgoesoutofdatewhenanewversionofLaravelisreleased.Instead,itsprimarypurposeistoprovidedeveloperswithahigh-leveloverviewandconcreteexamplestolearnwhattheyneedtogetstarted,asquicklyaspossible.Ratherthanmirroringthedocs,IwanttohelpyouunderstandthefoundationalconceptsbehindLaravel.

    LaravelisapowerfulandflexiblePHPframework.Ithasathrivingcommunityandawideecosystemoftools,andasaresultit’sgrowinginappealandreach.ThisbookisfordeveloperswhoalreadyknowhowtomakewebsitesandapplicationsandwanttoquicklylearnhowtodosoinLaravel.

    Laravel’sdocumentationisthoroughandexcellent.IfyoufindthatIdon’tcoveranyparticulartopicdeeplyenoughforyourliking,Iencourageyoutovisittheonlinedocumentationanddigdeeperintothatparticulartopic.

    Ithinkyouwillfindthebookacomfortablebalancebetweenhigh-levelintroductionandconcreteapplication,andbytheendyoushouldfeelcomfortablewritinganentireapplicationinLaravel,fromscratch.And,ifIdidmyjobwell,you’llbeexcitedtotry.

    http://laravel.com/docs

  • WhoThisBookIsForThisbookassumesknowledgeofbasicobject-orientedprogrammingpractices,PHP(oratleastthegeneralsyntaxofC-familylanguages),andthebasicconceptsoftheModel–View–Controller(MVC)patternandtemplating.Ifyou’venevermadeawebsitebefore,youmayfindyourselfinoveryourhead.Butaslongasyouhavesomeprogrammingexperience,youdon’thavetoknowanythingaboutLaravelbeforeyoureadthisbook—we’llcovereverythingyouneedtoknow,fromthesimplest“Hello,world!”

    Laravelcanrunonanyoperatingsystem,buttherewillbesomeBash(shell)commandsinthebookthatareeasiesttorunonLinux/MacOS.WindowsusersmayhaveahardertimewiththesecommandsandwithmodernPHPdevelopment,butifyoufollowtheinstructionstogetHomestead(aLinuxvirtualmachine)running,you’llbeabletorunallofthecommandsfromthere.

  • HowThisBookIsStructuredThisbookisstructuredinwhatIimaginetobeachronologicalorder:ifyou’rebuildingyourfirstwebappwithLaravel,theearlychapterscoverthefoundationalcomponentsyou’llneedtogetstarted,andthelaterchapterscoverlessfoundationalormoreesotericfeatures.

    Eachsectionofthebookcanbereadonitsown,butforsomeonenewtotheframework,I’vetriedtostructurethechapterssothatit’sactuallyveryreasonabletostartfromthebeginningandreaduntiltheend.

    Whereapplicable,eachchapterwillendwithtwosections:“Testing”and“TL;DR.”Ifyou’renotfamiliar,TL;DRmeans“toolong;didn’tread.”Thesefinalsectionswillshowyouhowtowritetestsforthefeaturescoveredineachchapterandgiveahigh-leveloverviewofwhatwascovered.

    ThebookiswrittenforLaravel5.3,butbecauseLaravel5.1isthelatestLTSrelease,anyfeaturesthatarenewin5.2or5.3willbeidentified.

  • ConventionsUsedinThisBookThefollowingtypographicalconventionsareusedinthisbook:

    ItalicIndicatesnewterms,URLs,emailaddresses,filenames,andfileextensions.

    Constantwidth

    Usedforprogramlistings,aswellaswithinparagraphstorefertoprogramelementssuchasvariableorfunctionnames,databases,datatypes,environmentvariables,statements,andkeywords.

    Constantwidthbold

    Showscommandsorothertextthatshouldbetypedliterallybytheuser.

    Constantwidthitalic

    Showstextthatshouldbereplacedwithuser-suppliedvaluesorbyvaluesdeterminedbycontext.

    TIPThiselementsignifiesatiporsuggestion.

    NOTEThiselementsignifiesageneralnote.

    WARNINGThiselementindicatesawarningorcaution.

  • O’ReillySafariNOTE

    Safari(formerlySafariBooksOnline)ismembership-basedtrainingandreferenceplatformforenterprise,government,educators,andindividuals.

    Membershaveaccesstothousandsofbooks,trainingvideos,LearningPaths,interactivetutorials,andcuratedplaylistsfromover250publishers,includingO’ReillyMedia,HarvardBusinessReview,PrenticeHallProfessional,Addison-WesleyProfessional,MicrosoftPress,Sams,Que,PeachpitPress,Adobe,FocalPress,CiscoPress,JohnWiley&Sons,Syngress,MorganKaufmann,IBMRedbooks,Packt,AdobePress,FTPress,Apress,Manning,NewRiders,McGraw-Hill,Jones&Bartlett,andCourseTechnology,amongothers.

    Formoreinformation,pleasevisithttp://oreilly.com/safari.

    http://oreilly.com/safarihttp://oreilly.com/safari

  • HowtoContactUsPleaseaddresscommentsandquestionsconcerningthisbooktothepublisher:

    O’ReillyMedia,Inc.

    1005GravensteinHighwayNorth

    Sebastopol,CA95472

    800-998-9938(intheUnitedStatesorCanada)

    707-829-0515(internationalorlocal)

    707-829-0104(fax)

    Wehaveawebpageforthisbook,wherewelisterrata,examples,andanyadditionalinformation.Youcanaccessthispageathttp://bit.ly/laravel-up-and-running.

    Tocommentorasktechnicalquestionsaboutthisbook,[email protected].

    Formoreinformationaboutourbooks,courses,conferences,andnews,seeourwebsiteathttp://www.oreilly.com.

    FindusonFacebook:http://facebook.com/oreilly

    FollowusonTwitter:http://twitter.com/oreillymedia

    WatchusonYouTube:http://www.youtube.com/oreillymedia

    http://bit.ly/laravel-up-and-runningmailto:[email protected]://www.oreilly.comhttp://facebook.com/oreillyhttp://twitter.com/oreillymediahttp://www.youtube.com/oreillymedia

  • AcknowledgmentsThisbookwouldnothavehappenedwithoutthegracioussupportofmyamazingwifeTerevaortheunderstanding(“Daddy’swriting,buddy!”)ofmysonMalachi.Andwhileshewasn’texplicitlyawareofit,mydaughterMiawasaroundforalmosttheentirecreationofthebook,sothisbookisdedicatedtothewholefamily.Thereweremany,manylongeveninghoursandweekendStarbuckstripsthattookmeawayfrommyfamily,andIcouldn’tbemoregratefulfortheirsupportandalsotheirpresencejustmakingmylifeawesome.

    Additionally,theentireTightenCo.familyhassupportedandencouragedmethroughthewritingofthebook,severalevenediting(KeithDamiani,editorextraordinaire)andhelpingmewithchallengingcodesamples(AdamWathan,KingoftheCollectionPipeline).DanSheetz,mypartnerinTightencrime,hasbeengraciousenoughtowatchmewhileawaymanyaworkhourcrankingonthisbookandwasnothingbutsupportiveandencouraging;andDaveHicking,ouroperationsmanager,helpedmearrangemyscheduleandworkresponsibilitiesaroundwritingtime.

    TaylorOtwelldeservesthanksandhonorforcreatingLaravel—andthereforecreatingsomanyjobsandhelpingsomanydevelopersloveourlivesthatmuchmore.Hedeservesappreciationforhowhe’sfocusedondeveloperhappinessandhowhardhe’sworkedtohaveempathyfordevelopersandtobuildapositiveandencouragingcommunity.ButIalsowanttothankhimforbeingakind,encouraging,andchallengingfriend.Taylor,you’reaboss.

    ThankstoJeffreyWay,whoIstillcontendtobeoneofthebestteachersontheInternet.HeoriginallyintroducedmetoLaravelandstillintroducesmorepeopleeveryday.He’salso,unsurprisingly,afantastichumanbeingwhomI’mgladtocallafriend.

    ThankyoutoJessD’Amico,ShawnMcCool,IanLandsman,andTaylorforseeingvalueinmeasaconferencespeakerearlyonandgivingmeaplatformtoteachfrom.ThankstoDayleReesformakingitsoeasyforsomanytolearnLaravelintheearlydays.

    ThankstoeverypersonwhoputtheirtimeandeffortintowritingblogpostsaboutLaravel,especiallyearlyon:EricBarnes,ChrisFidao,MattMachuga,JasonLewis,RyanTablada,DriesVints,MaksSurguy,andsomanymore.

    AndthankstotheentirecommunityoffriendsonTwitter,IRC,andSlackwho’veinteractedwithmeovertheyears.IwishIcouldnameeveryname,butIwouldmisssomeandthenfeelawfulaboutmissingthem.Youallarebrilliant,andI’mhonoredtogettointeractwithyouonaregularbasis.

    ThankstomyO’Reillyeditor,AllyMacDonald,andallofmytechnicaleditors:KeithDamiani,MichaelDyrynda,AdamFairholm,andMylesHyson.

    And,ofcourse,thankstotherestofmyfamilyandfriends,whosupportedmedirectlyorindirectlythroughthisprocess—myparentsandsiblings,theGainesvillecommunity,otherbusinessownersandauthors,otherconferencespeakers,andtheinimitableDCB.Ineedto

  • stopwritingbecausebythetimeIrunoutofspacehereI’llbethankingmyStarbucksbaristas.

  • Chapter1.WhyLaravel?

    Intheearlydaysofthedynamicweb,writingawebapplicationlookedalotdifferentthanitdoestoday.Developersthenwereresponsibleforwritingthecodefornotjusttheuniquebusinesslogicofourapplications,butalsoeachofthecomponentsthataresocommonacrosssites—userauthentication,inputvalidation,databaseaccess,templating,andmore.

    Today,programmershavedozensofapplicationdevelopmentframeworksandthousandsofcomponentsandlibrarieseasilyaccessible.It’sacommonrefrainamongprogrammersthat,bythetimeyoulearnoneframework,threenewer(andpurportedlybetter)frameworkshavepoppedupintendingtoreplaceit.

    “Justbecauseit’sthere”mightbeavalidjustificationforclimbingamountain,buttherearebetterreasonstochoosetouseaspecificframework—ortouseaframeworkatall.It’sworthaskingthequestion:whyframeworks?Morespecifically,whyLaravel?

  • WhyUseaFramework?It’seasytoseewhyit’sbeneficialtousetheindividualcomponents,orpackages,thatareavailabletoPHPdevelopers.Withpackages,someoneelseisresponsiblefordevelopingandmaintaininganisolatedpieceofcodethathasawell-definedjob,andintheorythatpersonhasadeeperunderstandingofthissinglecomponentthanyouhavetimetohave.

    FrameworkslikeLaravel—andSymfony,Silex,Lumen,andSlim—prepackageacollectionofthird-partycomponentstogetherwithcustomframework“glue”likeconfigurationfiles,serviceproviders,prescribeddirectorystructures,andapplicationbootstraps.So,thebenefitofusingaframeworkingeneralisthatsomeonehasmadedecisionsnotjustaboutindividualcomponentsforyou,butalsoabouthowthosecomponentsshouldfittogether.

  • “I’llJustBuildItMyself”Let’ssayyoustartanewwebappwithoutthebenefitofaframework.Wheredoyoubegin?Well,itshouldprobablyrouteHTTPrequests,soyounowneedtoevaluatealloftheHTTPrequestandresponselibrariesavailableandpickone.Thenarouter.Oh,andyou’llprobablyneedtosetupsomeformofroutesconfigurationfile.Whatsyntaxshouldituse?Whereshoulditgo?Whataboutcontrollers?Wheredotheylive,andhowaretheyloaded?Well,youprobablyneedadependencyinjectioncontainertoresolvethecontrollersandtheirdependencies.Butwhichone?

    Furthermore,whatifyoudotakethetimetoanswerallthosequestionsandsuccessfullycreateyourapplication—what’stheimpactonthenextdeveloper?Whataboutwhenyouhavefoursuchcustom-framework–basedapplications,oradozen,andyouhavetorememberwherethecontrollersliveineach,orwhattheroutingsyntaxis?

  • ConsistencyandFlexibilityFrameworksaddressthisissuebyprovidingacarefullyconsideredanswertothequestion“Whichcomponentshouldweusehere?”andensuringthattheparticularcomponentschosenworkwelltogether.Additionally,frameworksprovideconventionsthatreducetheamountofcodeadevelopernewtotheprojecthastounderstand—ifyouunderstandhowroutingworksinoneLaravelproject,forexample,youunderstandhowitworksinallLaravelprojects.

    Whensomeoneprescribesrollingyourownframeworkforeachnewproject,whatthey’rereallyadvocatingistheabilitytocontrolwhatdoesanddoesn’tgointoyourapplication’sfoundation.Thatmeansthebestframeworkswillnotonlyprovideyouwithasolidfoundation,butalsogiveyouthefreedomtocustomizetoyourheart’scontent.Andthis,asI’llshowyouintherestofthisbook,ispartofwhatmakesLaravelsospecial.

  • AShortHistoryofWebandPHPFrameworksAnimportantpartofbeingabletoanswerthequestion“WhyLaravel?”isunderstandingLaravel’shistory—andunderstandingwhatcamebeforeit.PriortoLaravel’sriseinpopularity,therewereavarietyofframeworksandothermovementsinPHPandotherwebdevelopmentspaces.

  • RubyonRailsDavidHeinemeierHanssonreleasedthefirstversionofRubyonRailsin2004,andit’sbeenhardtofindawebapplicationframeworksincethenthathasn’tbeeninfluencedbyRailsinsomeway.

    RailspopularizedMVC,RESTfulJSONAPIs,conventionoverconfiguration,ActiveRecord,andmanymoretoolsandconventionsthathadaprofoundinfluenceonthewaywebdevelopersapproachedtheirapplications—especiallywithregardtorapidapplicationdevelopment.

  • TheInfluxofPHPFrameworksItwascleartomostdevelopersthatRails,andsimilarwebapplicationframeworks,werethewaveofthefuture,andPHPframeworks,includingthoseadmittedlyimitatingRails,startingpoppingupquickly.

    CakePHPwasthefirstin2005,anditwassoonfollowedbySymfony,CodeIgniter,ZendFramework,andKohana(aCodeIgniterfork).Yiiarrivedin2008,andAuraandSlimin2010.2011broughtFuelPHPandLaravel,bothofwhichwerenotquiteCodeIgniteroffshoots,butinsteadproposedasalternatives.

    SomeoftheseframeworksweremoreRails-y,focusingondatabaseobject-relationalmappers(ORMs),MVCstructures,andothertoolstargetingrapiddevelopment.Others,likeSymfonyandZend,focusedmoreonenterprisedesignpatternsandecommerce.

  • TheGoodandtheBadofCodeIgniterCakePHPandCodeIgniterwerethetwoearlyPHPframeworksthatweremostopenabouthowmuchtheirinspirationwasdrawnfromRails.CodeIgniterquicklyrosetofameandby2010wasarguablythemostpopularoftheindependentPHPframeworks.

    CodeIgniterwassimple,easytouse,andboastedamazingdocumentationandastrongcommunity.Butitsuseofmoderntechnologyandpatternsadvancedslowly,andastheframeworkworldgrewandPHP’stoolingadvanced,CodeIgniterstartedfallingbehindintermsofbothtechnologicaladvancesandout-of-the-boxfeatures.Unlikemanyotherframeworks,CodeIgniterwasmanagedbyacompany,andtheywereslowtocatchupwithPHP5.3’snewerfeatureslikenamespacesandthemovestoGitHubandlaterComposer.Itwasin2010thatTaylorOtwell,Laravel’screator,becamedissatisfiedenoughwithCodeIgniterthathesetofftowritehisownframework.

  • Laravel1,2,and3ThefirstbetaofLaravel1wasreleasedinJune2011,anditwaswrittencompletelyfromscratch.ItfeaturedacustomORM(Eloquent);closure-basedrouting(inspiredbyRubySinatra);amodulesystemforextension;andhelpersforforms,validation,authentication,andmore.

    EarlyLaraveldevelopmentmovedquickly,andLaravel2and3werereleasedinNovember2011andFebruary2012,respectively.Theyintroducedcontrollers,unittesting,acommand-linetool,aninversionofcontrol(IoC)container,Eloquentrelationships,andmigrations.

  • Laravel4WithLaravel4,Taylorrewrotetheentireframeworkfromthegroundup.BythispointComposer,PHP’snow-ubiquitouspackagemanager,wasshowingsignsofbecominganindustrystandardandTaylorsawthevalueofrewritingtheframeworkasacollectionofcomponents,distributedandbundledtogetherbyComposer.

    TaylordevelopedasetofcomponentsunderthecodenameIlluminateand,inMay2013,releasedLaravel4withanentirelynewstructure.Insteadofbundlingthemajorityofitscodeasadownload,LaravelnowpulledinthemajorityofitscomponentsfromSymfony(anotherframeworkthatreleaseditscomponentsforusebyothers)andtheIlluminatecomponentsthroughComposer.

    Laravel4alsointroducedqueues,amailcomponent,facades,anddatabaseseeding.AndbecauseLaravelwasnowrelyingonSymfonycomponents,itwasannouncedthatLaravelwouldbemirroring(notexactly,butsoonafter)thesix-monthlyreleasescheduleSymfonyfollows.

  • Laravel5Laravel4.3wasscheduledtoreleaseinNovember2014,butasdevelopmentprogressed,itbecameclearthatthesignificanceofitschangesmeritedamajorrelease,andLaravel5wasreleasedinFebruary2015.

    Laravel5featuredarevampeddirectorystructure,removaloftheformandHTMLhelpers,theintroductionofthecontractinterfaces,aspateofnewviews,Socialiteforsocialmediaauthentication,Elixirforassetcompilation,Schedulertosimplifycron,dotenvforsimplifiedenvironmentmanagement,formrequests,andabrandnewREPL(read–evaluate–printloop).

  • What’sSoSpecialAboutLaravel?SowhatisitthatsetsLaravelapart?WhyisitworthhavingmorethanonePHPframeworkatanytime?TheyallusecomponentsfromSymfonyanyway,right?Let’stalkabitaboutwhatmakesLaravel“tick.”

  • ThePhilosophyofLaravelYouonlyneedtoreadthroughtheLaravelmarketingmaterialsandREADMEstostartseeingitsvalues.Tayloruseslight-relatedwordslike“Illuminate”and“Spark.”Andthentherearethese:“Artisans.”“Elegant.”Also,these:“Breathoffreshair.”“Freshstart.”Andfinally:“Rapid.”“Warpspeed.”

    Thetwomoststronglycommunicatedvaluesoftheframeworkaretoincreasedeveloperspeedanddeveloperhappiness.Taylorhasdescribedthe“Artisan”languageasintentionallycontrastingagainstmoreutilitarianvalues.Youcanseethegenesisofthissortofthinkinginhis2011questiononStackExchangeinwhichhestated,“SometimesIspendridiculousamountsoftime(hours)agonizingovermakingcodelookpretty”—justforthesakeofabetterexperienceoflookingatthecodeitself.Andhe’softentalkedaboutthevalueofmakingiteasierandquickerfordeveloperstotaketheirideastofruition,gettingridofunnecessarybarrierstocreatinggreatproducts.

    Laravelis,atitscore,aboutequippingandenablingdevelopers.Itsgoalistoprovideclear,simple,andbeautifulcodeandfeaturesthathelpdevelopersquicklylearn,start,anddevelop,andwritecodethat’ssimple,clear,andwilllast.

    TheconceptoftargetingdevelopersisclearacrossLaravelmaterials.“Happydevelopersmakethebestcode”iswritteninthedocumentation.“Developerhappinessfromdownloadtodeploy”wastheunofficialsloganforawhile.Ofcourse,anytoolorframeworkwillsayitwantsdeveloperstobehappy.Buthavingdeveloperhappinessasaprimaryconcern,ratherthansecondary,hashadahugeimpactonLaravel’sstyleanddecision-makingprogress.Whereotherframeworksmaytargetarchitecturalpurityastheirprimarygoal,orcompatibilitywiththegoalsandvaluesofenterprisedevelopmentteams,Laravel’sprimaryfocusisonservingtheindividualdeveloper.

    http://bit.ly/2dT5kmS

  • HowLaravelAchievesDeveloperHappinessJustsayingyouwanttomakedevelopershappyisonething.Doingitisanother,anditrequiresyoutoquestionwhatinaframeworkismostlikelytomakedevelopersunhappyandwhatismostlikelytomakethemhappy.ThereareafewwaysLaraveltriestomakedevelopers’liveseasier.

    First,Laravelisarapidapplicationdevelopmentframework.Thatmeansitfocusesonashallow(easy)learningcurveandonminimizingthestepsbetweenstartinganewappandpublishingit.Allofthemostcommontasksinbuildingwebapplications,fromdatabaseinteractionstoauthenticationtoqueuestoemailtocaching,aremadesimplerbythecomponentsLaravelprovides.ButLaravel’scomponentsaren’tjustgreatontheirown;theyprovideaconsistentAPIandpredictablestructuresacrosstheentireframework.Thatmeansthat,whenyou’retryingsomethingnewinLaravel,you’remorethanlikelygoingtoendupsaying,“…anditjustworks.”

    Thisdoesn’tendattheframeworkitself,either.Laravelprovidesanentireecosystemoftoolsforbuildingandlaunchingapplications.YouhaveHomesteadandValetforlocaldevelopment,Forgeforservermanagement,andEnvoyerforadvanceddeployment.Andthere’sasuiteofadd-onpackages:Cashierforpaymentsandsubscriptions,EchoforWebSockets,Scoutforsearch,PassportforAPIauthentication,Socialiteforsociallogin,andSparktobootstrapyourSaaS.Laravelistryingtotaketherepetitiveworkoutofdevelopers’jobssotheycandosomethingunique.

    Next,Laravelfocuseson“conventionoverconfiguration”—meaningthatifyou’rewillingtouseLaravel’sdefaults,you’llhavetodomuchlessworkthanwithotherframeworksthatrequireyoutodeclareallofyoursettingsevenifyou’reusingtherecommendedconfiguration.ProjectsbuiltonLaraveltakelesstimethanthosebuiltonmostotherPHPframeworks.

    Laravelalsofocusesdeeplyonsimplicity.It’spossibletousedependencyinjectionandmockingandtheDataMapperpatternandrepositoriesandCommandQueryResponsibilitySegregationandallsortsofothermorecomplexarchitecturalpatternswithLaravel,ifyouwant.Butwhileotherframeworksmightsuggestusingthosetoolsandstructuresoneveryproject,Laravelanditsdocumentationandcommunityleantowardstartingwiththesimplestpossibleimplementation—aglobalfunctionhere,afacadethere,ActiveRecordoverthere.Thisallowsdeveloperstocreatethesimplestpossibleapplicationtosolvefortheirneeds.

    AninterestingsourceofhowLaravelisdifferentisthatitscreatoranditscommunityaremoreconnectedtoandinspiredbyRubyandRailsandfunctionalprogramminglanguagesthanbyJava.There’sastrongcurrentinmodernPHPtoleantowardverbosityandcomplexity,embracingthemoreJava-esqueaspectsofPHP.ButLaraveltendstobeontheotherside,embracingexpressive,dynamic,andsimplecodingpracticesandlanguagefeatures.

  • TheLaravelCommunityIfthisbookisyourfirstexposuretotheLaravelcommunity,youhavesomethingspecialtolookforwardto.OneofthedistinguishingelementsofLaravel,whichhascontributedtoitsgrowthandsuccess,isthewelcoming,teachingcommunitythatsurroundsit.FromJeffreyWay’sLaracastsvideotutorialstoLaravelNewstoSlackandIRCchannels,fromTwitterfriendstobloggerstotheLaraconconferences,Laravelhasarichandvibrantcommunityfulloffolkswho’vebeenaroundsincedayoneandfolkswhoareontheirowndayone.Andthisisn’tanaccident:

    FromtheverybeginningofLaravel,I’vehadthisideathatallpeoplewanttofeelliketheyarepartofsomething.It’sanaturalhumaninstincttowanttobelongandbeacceptedintoagroupofotherlike-mindedpeople.So,byinjectingpersonalityintoawebframeworkandbeingreallyactivewiththecommunity,thattypeoffeelingcangrowinthecommunity.TaylorOtwell,ProductandSupportinterview

    TaylorunderstoodfromtheearlydaysofLaravelthatasuccessfulopensourceprojectneededtwothings:gooddocumentationandawelcomingcommunity.AndthosetwothingsarenowhallmarksofLaravel.

    https://laracasts.com/https://laravel-news.com/

  • HowItWorksUpuntilnow,everythingI’vesharedherehasbeenentirelyabstract.Whataboutthecode,youask?Let’sdigintoasimpleapplication(Example1-1)soyoucanseewhatworkingwithLaravelday-to-dayisactuallylike.

    Example1-1.“Hello,World”inroutes/web.php//File:routes/web.php

  • Route::get('/',function(){returnGreeting::first()->body;});//File:app/Greeting.php

  • WhyLaravel?So—whyLaravel?

    BecauseLaravelhelpsyoubringyourideastorealitywithnowastedcode,usingmoderncodingstandards,surroundedbyavibrantcommunity,withanempoweringecosystemoftools.

    Andbecauseyou,deardeveloper,deservetobehappy.

  • Chapter2.SettingUpaLaravelDevelopmentEnvironment

    PartofPHP’ssuccesshasbeenbecauseit’shardtofindawebserverthatcan’tservePHP.However,modernPHPtoolshavestricterrequirementsthanthoseofthepast.ThebestwaytodevelopforLaravelistoensureaconsistentlocalandremoteserverenvironmentforyourcode,andthankfully,theLaravelecosystemhasafewtoolsforthis.

  • SystemRequirementsEverythingwe’llcoverinthischapterispossiblewithWindowsmachines,butyou’llneeddozensofpagesofcustominstructionsandcaveats.I’llleavethoseinstructionsandcaveatstoactualWindowsusers,sotheexampleshereandintherestofthebookwillfocusonUnix/Linux/MacOSdevelopers.

    WhetheryouchoosetoserveyourwebsitebyinstallingPHPandothertoolsonyourlocalmachine,serveyourdevelopmentenvironmentfromavirtualmachineviaVagrant,orrelyonatoollikeMAMP/WAMP/XAMPP,yourdevelopmentenvironmentwillneedtohaveallofthefollowinginstalledinordertoserveLaravelsites:

    PHP>=5.6.4forLaravel5.3orPHP>=5.5.9for5.1and5.2

    OpenSSLPHPextension

    PDOPHPextension

    MbstringPHPextension

    TokenizerPHPextension

  • ComposerWhatevermachineyou’redevelopingonwillneedtohaveComposerinstalledglobally.Ifyou’renotfamiliarwithComposer,it’satoolthat’satthefoundationofmostmodernPHPdevelopment.ComposerisadependencymanagerforPHP,muchlikeNPMforNodeorRubyGemsforRuby.You’llneedComposertoinstallLaravel,updateLaravel,andbringinexternaldependencies.

    https://getcomposer.org/

  • LocalDevelopmentEnvironmentsFormanyprojects,hostingyourdevelopmentenvironmentusingasimplertoolsetwillbeenough.IfyoualreadyhaveMAMPorWAMPorXAMPPinstalledonyoursystem,thatwilllikelybefinetorunLaravel.YoucanalsojustrunLaravelwithPHP’sbuilt-inwebserver,assumingyoursystemPHPistherightversion.

    AllyoureallyneedtogetstartedistheabilitytorunPHP.Everythingpastthatisuptoyou.

    However,Laravelofferstwotoolsforlocaldevelopment,ValetandHomestead,andwe’llcoverbothbriefly.Ifyou’reunsureofwhichtouse,I’drecommendusingValetandjustskimmingtheHomesteadsection;however,bothtoolsarevaluableandworthunderstanding.

  • LaravelValetIfyouwanttousePHP’sbuilt-inwebserver,yoursimplestoptionistoserveeverysitefromalocalhostURL.Ifyourunphp-Slocalhost:8000-tpublicfromyourLaravelsite’srootfolder,PHP’sbuilt-inwebserverwillserveyoursiteathttp://localhost:8000/.Youcanalsorunphpartisanserveonceyouhaveyourapplicationsetuptoeasilyspinupanequivalentserver.

    Butifyou’reinterestedintyingeachofyoursitestoaspecificdevelopmentdomain,you’llneedtogetcomfortablewithyouroperatingsystem’shostsfileanduseatoollikednsmasq.Let’sinsteadtrysomethingsimpler.

    Ifyou’reaMacuser(therearealsounofficialforksforWindowsandLinux),LaravelValettakesawaytheneedtoconnectyourdomainstoyourapplicationfolders.ValetinstallsdnsmasqandaseriesofPHPscriptsthatmakeitpossibletotypelaravelnewmyapp&&openmyapp.devandforittojustwork.You’llneedtoinstallafewtoolsusingHomebrew,whichthedocumentationwillwalkyouthrough,butthestepsfrominitialinstallationtoservingyourappsarefewandsimple.

    InstallValet(seethedocsforthelatestinstallationinstruction—it’sunderveryactivedevelopmentatthistimeofwriting),andpointitatoneormoredirectorieswhereyoursiteswilllive.Iranvaletparkfrommy~/Sitesdirectory,whichiswhereIputallofmyunder-developmentapps.Now,youcanjustadd.devtotheendofthedirectorynameandvisititinyourbrowser.

    Valetmakesiteasytoserveallfoldersinagivenfolderas“FOLDERNAME.dev”usingvaletpark,toservejustasinglefolderusingvaletlink,toopentheValet-serveddomainforafolderusingvaletopen,toservetheValetsitewithHTTPSusingvaletsecure,andtoopenanngroktunnelsoyoucanshareyoursitewithotherswithvaletshare.

    http://bit.ly/2eNPJ5Thttps://laravel.com/docs/valethttps://laravel.com/docs/valet

  • LaravelHomesteadHomesteadisanothertoolyoumightwanttousetosetupyourlocaldevelopmentenvironment.It’saconfigurationtoolthatsitsontopofVagrantandprovidesapre-configuredvirtualmachineimagethatisperfectlysetupforLaraveldevelopment,andmirrorsthemostcommonproductionenvironmentthatmanyLaravelsitesrunon.

    SettingupHomesteadIfyouchoosetouseHomestead,it’sgoingtotakeabitmoreworktosetupthansomethinglikeMAMPorValet.Thebenefitsaremyriad,however:configuredcorrectly,yourlocalenvironmentcanbeincrediblyclosetoyourremoteworkingenvironment;youwon’thavetoworryaboutupdatingyourdependenciesonyourlocalmachine;andyoucanlearnallaboutthestructureofUbuntuserversfromthesafetyofyourlocalmachine.

    WHATTOOLSDOHOMESTEADOFFER?

    YoucanalwaysupgradetheindividualcomponentsofyourHomesteadvirtualmachine,buthereareafewimportanttoolsHomesteadcomeswithbydefault:

    Toruntheserverandservethesite,Ubuntu,PHP,andNginx(awebserversimilartoApache).

    Fordatabase/storageandqueues,MySQL,Postgres,Redis,Memcached,andbeanstalkd.

    Forbuildstepsandothertools,Node.

    InstallingHomestead’sdependenciesFirst,you’llneedtodownloadandinstalleitherVirtualBoxorVMWare.VirtualBoxismostcommonbecauseit’sfree.

    Next,downloadandinstallVagrant.

    Vagrantisconvenientbecauseitmakesiteasyforyoutocreateanewlocalvirtualmachinefromaprecreated“box,”whichisessentiallyatemplateforavirtualmachine.So,thenextstepistorunvagrantboxaddlaravel/homesteadfromyourterminaltodownloadthebox.

    InstallingHomesteadNext,let’sactuallyinstallHomestead.YoucaninstallmultipleinstancesofHomestead(perhapshostingadifferentHomesteadboxperproject),butIpreferasingleHomesteadvirtualmachineforallofmyprojects.Ifyouwantoneperproject,you’llwanttoinstallHomesteadinyourprojectdirectory;checktheHomesteaddocumentationonlineforinstructions.Ifyouwantasinglevirtualmachineforallofyourprojects,installHomesteadinyouruser ’shomedirectoryusingthefollowingcommand:

    gitclonehttps://github.com/laravel/homestead.git~/Homestead

    https://www.virtualbox.org/wiki/Downloadshttps://www.vagrantup.com/downloads.htmlhttps://laravel.com/docs/5.3/homestead

  • Now,runtheinitializationscriptfromwhereveryouputtheHomesteaddirectory:

    bash~/Homestead/init.sh

    ThiswillplaceHomestead’sprimaryconfigurationfile,Homestead.yaml,inanew~/.homesteaddirectory.

    ConfiguringHomesteadOpenupHomestead.yamlandconfigureithowyou’dlike.Here’swhatitlookslikeoutofthebox:

    ip:"192.168.10.10"memory:2048cpus:1provider:virtualbox

    authorize:~/.ssh/id_rsa.pub

    keys:-~/.ssh/id_rsa

    folders:-map:~/Codeto:/home/vagrant/Code

    sites:-map:homestead.appto:/home/vagrant/Code/Laravel/public

    databases:-homestead

    #blackfire:#-id:foo#token:bar#client-id:foo#client-token:bar

    #ports:#-send:50000#to:5000#-send:7777#to:777#protocol:udp

    You’llneedtotellityourprovider(likelyvirtualbox),pointittoyourpublicSSHkey(bydefault~/.ssh/id_rsa.pub;ifyoudon’thaveone,GitHubhasagreattutorialoncreatingSSHkeys),mapfoldersandsitestotheirlocalmachineequivalents,andprovisionadatabase.

    MappingfoldersinHomesteadallowsyoutoeditfilesonyourlocalmachineandhavethosefilesshowupinyourVagrantboxsotheycanbeserved.Forexample,ifyouhavea~/Sitesdirectorywhereyouputallofyourcode,you’dmapthefoldersinHomesteadbyreplacingthefolderssectioninHomestead.yamlwiththefollowing:

    folders:-map:~/Sitesto:/home/vagrant/Sites

    http://bit.ly/2e7Auof

  • You’venowjustcreatedadirectoryinyourHomesteadvirtualmachineat/home/vagrant/Sitesthatwillmirroryourcomputer ’sdirectoryat~/Sites.

  • TOP-LEVELDOMAINSFORDEVELOPMENTSITESYoucanchooseanyconventionforlocaldevelopmentsites’URLs,but.appand.devarethemostcommon.Homesteadsuggests.app,soifI’mworkingonalocalcopyofsymposiumapp.com,I’lldevelopatsymposiumapp.app.

    Now,let’ssetupourfirstexamplewebsite.Let’ssayourlivesiteisgoingtobeprojectName.com.InHomestead.yaml,we’llmapourlocaldevelopmentfoldertoprojectName.app,sowehaveaseparateURLtovisitforlocaldevelopment:

    sites:-map:projectName.appto:/home/vagrant/Sites/projectName/public

    Asyoucansee,we’remappingtheURLprojectName.apptothevirtualmachinedirectory/home/vagrant/Sites/projectName/public,whichisthepublicfolderwithinourLaravelinstall.We’lllearnmoreaboutthatlater.

    Finally,you’regoingtoneedtoteachyourlocalmachinethat,whenyoutrytovisitprojectName.app,itshouldlookatyourcomputer ’slocalIPaddresstoresolveit.MacandLinuxusersshouldedit/etc/hosts,andWindowsusersC:\Windows\System32\drivers\etc\hosts.Addalinetothisfilethatlookslikethis:

    192.168.10.10projectName.app

    Onceyou’veprovisionedHomestead,yoursitewillbeavailabletobrowse(onyourmachine)athttp://projectName.app/.

    CreatingdatabasesinHomesteadJustlikeyoucandefineasiteinHomestead.yaml,youcanalsodefineadatabase.Databasesarealotsimpler,becauseyou’reonlytellingtheprovisionertocreateadatabasewiththatname,nothingelse.Wedothisasfollows:

    databases:-projectname

    ProvisioningHomesteadThefirsttimeyouactuallyturnonaHomesteadbox,youneedtotellVagranttoinitializeit.NavigatetoyourHomesteaddirectoryandrunvagrantup:

    cd~/Homesteadvagrantup

    YourHomesteadboxisnowupandrunning;it’smirroringalocalfolder,andit’sservingittoaURLyoucanvisitinanybrowseronyourcomputer.ItalsohascreatedaMySQL

    http://projectName.app/

  • database.Nowthatyouhavethatenvironmentrunning,you’rereadytosetupyourfirstLaravelproject—butfirst,aquicknoteaboutusingHomesteadday-to-day.

    UsingHomesteadday-to-dayIt’scommontoleaveyourHomesteadvirtualmachineupandrunningatalltimes,butifyoudon’t,orifyouhaverecentlyrestartedyourcomputer,you’llneedtoknowhowtospintheboxupanddown.

    SinceHomesteadisbasedonVagrantcommands,you’lljustusebasicVagrantcommandsformostHomesteadactions.ChangetothedirectorywhereyouinstalledHomestead(usingcd)andthenrunthefollowingcommandsasneeded:

    vagrantupspinsuptheHomesteadbox.

    vagrantsuspendtakesasnapshotofwheretheboxisandthenshutsitdown;like“hibernating”adesktopmachine.

    vagranthaltshutstheentireboxdown;liketurningoffadesktopmachine.

    vagrantdestroydeletestheentirebox;likeformattingadesktopmachine.

    vagrantprovisionre-runstheprovisionersonthepreexistingbox.

    ConnectingtoHomesteaddatabasesfromdesktopapplicationsIfyouuseadesktopapplicationlikeSequelPro,you’lllikelywanttoconnecttoyourHomesteadMySQLdatabasesfromyourhostmachine.Thesesettingswillgetyougoing:

    Connectiontype:Standard(non-SSH)

    Host:127.0.0.1

    Username:homestead

    Password:secret

    Port:33060

  • CreatingaNewLaravelProjectTherearetwowaystocreateanewLaravelproject,butbotharerunfromthecommandline.ThefirstoptionistogloballyinstalltheLaravelinstallertool(usingComposer);thesecondistouseComposer ’screate-projectfeature.

    YoucanlearnaboutbothoptionsinmoredetailontheInstallationdocumentationpage,butI’drecommendtheLaravelinstallertool.

    http://laravel.com/docs/installation

  • InstallingLaravelwiththeLaravelInstallerToolIfyouhaveComposerinstalledglobally,installingtheLaravelinstallertoolisassimpleasrunningthefollowingcommand:

    composerglobalrequire"laravel/installer=~1.1"

    OnceyouhavetheLaravelinstallertoolinstalled,spinningupanewLaravelprojectissimple.Justrunthiscommandfromyourcommandline:

    laravelnewprojectName

    ThiswillcreateanewsubdirectoryofyourcurrentdirectorynamedprojectNameandinstallabareLaravelprojectinit.

  • InstallingLaravelwithComposer’screate-projectFeatureComposeralsooffersafeaturecalledcreate-projectforcreatingnewprojectswithaparticularskeleton.TousethistooltocreateanewLaravelproject,issuethefollowingcommand:

    composercreate-projectlaravel/laravelprojectName--prefer-dist

    Justliketheinstallertool,thiswillcreateasubdirectoryofyourcurrentdirectorynamedprojectNamethatcontainsaskeletonLaravelinstall,readyforyoutodevelop.

  • Laravel’sDirectoryStructureWhenyouopenupadirectorythatcontainsaskeletonLaravelapplication,you’llseethefollowingfilesanddirectories:

    app/bootstrap/config/database/public/resources/routes/storage/tests/vendor/.env.env.example.gitattributes.gitignoreartisancomposer.jsoncomposer.lockgulpfile.jspackage.jsonphpunit.xmlreadme.mdserver.php

    Let’swalkthroughthemonebyonetogetfamiliar.

  • TheFoldersTherootdirectorycontainsthefollowingfoldersbydefault:

    appiswherethebulkofyouractualapplicationwillgo.Models,controllers,routedefinitions,commands,andyourPHPdomaincodeallgoinhere.

    bootstrapcontainsthefilesthattheLaravelframeworkusestobooteverytimeitruns.

    configiswherealltheconfigurationfileslive.

    databaseiswheredatabasemigrationsandseedslive.

    publicisthedirectorytheserverpointstowhenit’sservingthewebsite.Thiscontainsindex.php,whichisthefrontcontrollerthatkicksoffthebootstrappingprocessandroutesallrequestsappropriately.It’salsowhereanypublic-facingfileslikeimages,stylesheets,scripts,ordownloadsgo.

    resourcesiswherenon-PHPfilesthatareneededforotherscriptslive.Views,languagefiles,and(optionally)Sass/LESSandsourceJavaScriptfileslivehere.

    routesiswherealloftheroutedefinitionslive,bothforHTTProutesand“consoleroutes,”orArtisancommands.

    storageiswherecaches,logs,andcompiledsystemfileslive.

    testsiswhereunitandintegrationtestslive.

    vendoriswhereComposerinstallsitsdependencies.It’sGit-ignored(markedtobeexcludedfromyourversioncontrolsystem),asComposerisexpectedtorunasapartofyourdeployprocessonanyremoteservers.

  • TheLooseFilesTherootdirectoryalsocontainsthefollowingfiles:

    .envand.env.examplearethefilesthatdictatetheenvironmentvariables(variablesthatareexpectedtobedifferentineachenvironmentandarethereforenotcommittedtoversioncontrol)..env.exampleisatemplatethateachenvironmentshouldduplicatetocreateitsown.envfile,whichisGit-ignored.

    artisanisthefilethatallowsyoutorunArtisancommands(seeChapter7)fromthecommandline.

    .gitignoreand.gitattributesareGitconfigurationfiles.

    composer.jsonandcomposer.lockaretheconfigurationfilesforComposer;composer.jsonisuser-editableandcomposer.lockisnot.ThesefilessharesomebasicinformationaboutthisprojectandalsodefineitsPHPdependencies.

    gulpfile.jsisthe(optional)configurationfileforElixirandGulp.Thisisforcompilingandprocessingyourfrontendassets.

    package.jsonislikecomposer.jsonbutforfrontendassets.

    phpunit.xmlisaconfigurationfileforPHPUnit,thetoolLaravelusesfortestingoutofthebox.

    readme.mdisaMarkdownfilegivingabasicintroductiontoLaravel.

    server.phpisabackupserverthattriestoallowless-capableserverstostillpreviewtheLaravelapplication.

  • ConfigurationThecoresettingsofyourLaravelapplication—databaseconnection,queueandmailsettings,etc.—liveinfilesintheconfigfolder.Eachofthesefilesreturnsanarray,andeachvalueinthearraywillbeaccessiblebyaconfigkeythatiscomprisedofthefilenameandalldescendantkeys,separatedbydots(.)

    So,ifyoucreateafileatconfig/services.phpthatlookslikethis:

    //config/services.phpreturn['sparkpost'=>['secret'=>'abcdefg']];

    youwillnowhaveaccesstothatconfigvariableusingconfig('services.sparkpost.secret').

    Anyconfigurationvariablesthatshouldbedistinctforeachenvironment(andthereforenotcommittedtosourcecontrol)willinsteadliveinyour.envfiles.Let’ssayyouwanttouseadifferentBugsnagAPIkeyforeachenvironment.You’dsettheconfigfiletopullitfrom.env:

    //config/services.phpreturn['bugsnag'=>['api_key'=>env('BUGSNAG_API_KEY')]];

    Thisenv()helperfunctionpullsavaluefromyour.envfilewiththatsamekey.Sonow,addthatkeytoyour.env(settingsforthisenvironment)and.env.example(templateforallenvironments)files:

    BUGSNAG_API_KEY=oinfp9813410942

    Your.envfilealreadycontainsquiteafewenvironment-specificvariablesneededbytheframework,likewhichmaildriveryou’llbeusingandwhatyourbasicdatabasesettingsare.

  • UpandRunningYou’renowupandrunningwithabareLaravelinstall.Rungitinit,committhebarefileswithgitadd.andgitcommit,andyou’rereadytostartcoding.That’sit!Andifyou’reusingValet,youcanrunthefollowingcommandsandinstantlyseeyoursiteliveinyourbrowser:

    laravelnewmyProject&&cdmyProject&&valetopen

    EverytimeIstartanewproject,thesearethestepsItake:

    laravelnewmyProjectcdmyProjectgitinitgitadd.gitcommit-m"Initialcommit"

    Ikeepallofmysitesina~/Sitesfolder,whichIhavesetupasmyprimaryValetdirectory,sointhiscaseI’dinstantlyhavemyProject.devaccessibleinmybrowserwithnoaddedwork.Icanedit.envandpointittoaparticulardatabase,addthatdatabaseinmyMySQLapp,andI’mreadytostartcoding.

  • LAMBOIperformthethissetofstepssooftenthatIcreatedasimpleglobalComposerpackagetodoitforme.It’scalledLambo,andyoucanlearnmoreaboutitonGitHub.

    https://github.com/tightenco/lambo

  • TestingIneverychapterafterthis,the“Testing”sectionattheendofthechapterwillshowyouhowtowritetestsforthefeatureorfeaturesthatwerecovered.Sincethischapterdoesn’tcoveratestablefeature,let’stalktestsquickly.(TolearnmoreaboutwritingandrunningtestsinLaravel,headovertoChapter12.)

    Outofthebox,LaravelbringsinPHPUnitasadependencyandisconfiguredtorunthetestsinanyfileinthetestsdirectorywhosenameendswithTest.php(forexample,tests/UserTest.php).

    So,thesimplestwaytowritetestsistocreateafileinthetestsdirectorywithanamethatendswithTest.php.Andtheeasiestwaytorunthemistorun./vendor/bin/phpunitfromthecommandline(intheprojectroot).

    Ifanytestsrequiredatabaseaccess,besuretorunyourtestsfromthemachinewhereyourdatabaseishosted—soifyou’rehostingyourdatabaseinVagrant,makesuretosshintoyourVagrantboxtorunyourtestsfromthere.Again,youcanlearnaboutthisandmuchmoreinChapter12.

  • TL;DRSinceLaravelisaPHPframework,it’sverysimpletoserveitlocally.Laravelalsoprovidestwotoolsformanagingyourlocaldevelopment:asimplertoolcalledValetthatusesyourlocalmachinetoprovideyourdependencies,andapreconfiguredVagrantsetupnamedHomestead.Laravelrelieson,andcanbeinstalledby,Composer,andcomesoutoftheboxwithaseriesoffoldersandfilesthatreflectbothitsconventionsanditsrelationshipwithotheropensourcetools.

  • Chapter3.RoutingandControllers

    Theessentialfunctionofanywebapplicationframeworkistotakerequestsfromauseranddeliverresponses,usuallyviaHTTP(S).Thismeansdefininganapplication’sroutesisthefirstandmostimportantprojecttotacklewhenlearningawebframework;withoutroutes,youhavenoabilitytointeractwiththeenduser.

    InthischapterwewillexamineroutesinLaravelandshowhowtodefinethem,howtopointthemtothecodetheyshouldexecute,andhowtouseLaravel’sroutingtoolstohandleadiversearrayofroutingneeds.

  • RouteDefinitionsInaLaravelapplication,youwilldefineyour“web”routesinroutes/web.phpandyour“API”routesinroutes/api.php.Webroutesarethosethatwillbevisitedbyyourendusers;APIroutesarethoseforyourAPI,ifyouhaveone.Fornow,we’llprimarilyfocusontheroutesinroutes/web.php.

    NOTEInprojectsrunningversionsofLaravelpriorto5.3,therewillbeonlyoneroutesfile,locatedatapp/Http/routes.php.

    Thesimplestwaytodefinearouteistomatchapath(e.g.,/)withaclosure,asseeninExample3-1.

    Example3-1.Basicroutedefinition//routes/web.phpRoute::get('/',function(){return'Hello,World!';});

    WHAT’SACLOSURE?

    ClosuresarePHP’sversionofanonymousfunctions.Aclosureisafunctionthatyoucanpassaroundasanobject,assigntoavariable,passasaparametertootherfunctionsandmethods,orevenserialize.

    You’venowdefinedthat,ifanyonevisits/(therootofyourdomain),Laravel’sroutershouldruntheclosuredefinedthereandreturntheresult.Notethatwereturnourcontentanddon’techoorprintit.

  • AQUICKINTRODUCTIONTOMIDDLEWAREYoumightbewondering,“WhyamIreturning‘Hello,World!’insteadofechoingit?”

    Therearequiteafewanswers,butthesimplestisthattherearealotofwrappersaroundLaravel’srequestandresponsecycle,includingsomethingcalledmiddleware.Whenyourrouteclosureorcontrollermethodisdone,it’snottimetosendtheoutputtothebrowseryet;returningthecontentallowsittocontinueflowingthroughtheresponsestackandthemiddlewarebeforeitisreturnedbacktotheuser.

    Manysimplewebsitescouldbedefinedentirelywithinthewebroutesfile.WithafewsimpleGETroutescombinedwithsometemplatesasillustratedinExample3-2,youcancanserveaclassicwebsiteeasily.

    Example3-2.SamplewebsiteRoute::get('/',function(){returnview('welcome');});

    Route::get('about',function(){returnview('about');});

    Route::get('products',function(){returnview('products');});

    Route::get('services',function(){returnview('services');});

  • STATICCALLSIfyouhavemuchexperiencedevelopingPHP,youmightbesurprisedtoseestaticcallsontheRouteclass.Thisisnotactuallyastaticmethodperse,butratherservicelocationusingLaravel’sfacades,whichwe’llcoverinChapter11.

    Ifyouprefertoavoidfacades,youcanaccomplishthesesamedefinitionslikethis:

    $router->get('/',function(){return'Hello,World!';});

    HTTPMETHODS

    Ifyou’renotfamiliarwiththeideaofHTTPmethods,readoninthischapterformoreinformation,butfornow,justknowthateveryHTTPrequesthasa“verb,”oraction,alongwithit.Laravelallowsyoutodefineyourroutesbasedonwhichverbwasused;themostcommonareGETandPOST,followedbyPUT,DELETE,andPATCH.Eachmethodcommunicatesadifferentthingtotheserver,andtoyourcode,abouttheintentionsofthecaller.

  • RouteVerbsYoumight’venoticedthatwe’vebeenusingRoute::getinourroutedefinitions.Thismeanswe’retellingLaraveltoonlymatchfortheserouteswhentheHTTPrequestusestheGETaction.Butwhatifit’saformPOST,ormaybesomeJavaScriptsendingPUTorDELETErequests?Thereareafewotheroptionsformethodstocallonaroutedefinition,asillustratedinExample3-3.

    Example3-3.RouteverbsRoute::get('/',function(){return'Hello,World!';});

    Route::post('/',function(){});

    Route::put('/',function(){});

    Route::delete('/',function(){});

    Route::any('/',function(){});

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

  • RouteHandlingAsyou’veprobablyguessed,passingaclosuretotheroutedefinitionisnottheonlywaytoteachithowtoresolvearoute.Closuresarequickandsimple,butthelargeryourapplicationgets,theclumsieritbecomestoputallofyourroutinglogicinonefile.Additionally,applicationsusingrouteclosurescan’ttakeadvantageofLaravel’sroutecaching(moreonthatlater),whichcanshaveuptohundredsofmillisecondsoffofeachrequest.

    Theothercommonoptionistopassacontrollernameandmethodasastringinplaceoftheclosure,asinExample3-4.

    Example3-4.RoutescallingcontrollermethodsRoute::get('/','WelcomeController@index');

    ThisistellingLaraveltopassrequeststothatpathtotheindex()methodoftheApp\Http\Controllers\WelcomeControllercontroller.Thismethodwillbepassedthesameparametersandtreatedthesamewayasaclosureyoumight’vealternativelyputinitsplace.

  • RouteParametersIftherouteyou’redefininghasparameters—segmentsintheURLstructurethatarevariable—it’ssimpletodefinetheminyourrouteandpassthemtoyourclosure(seeExample3-5).

    Example3-5.RouteparametersRoute::get('users/{id}/friends',function($id){//});

    THENAMINGRELATIONSHIPBETWEENROUTEPARAMETERSANDCLOSURE/CONTROLLER METHODPARAMETERS

    AsyoucanseeinExample3-5,it’smostcommontousethesamenamesforyourrouteparameters({id})andthemethodparameterstheyinjectintoyourroutedefinition(function($id)).Butisthisnecessary?

    Unlessyou’reusingroute/modelbinding,no.Theonlythingthatdefineswhichrouteparametermatcheswithwhichmethodparameteristheirorder(lefttoright),asyoucanseehere:

    Route::get('users/{userId}/comments/{commentId}',function($thisIsActuallyTheRouteId,$thisisReallyTheCommentId){//});

    Thathavingbeensaid,justbecauseyoucanmakethemdifferentdoesn’tmeanyoushould.Irecommendkeepingthemthesameforthesakeoffuturedevelopers,whocouldgettrippedupbyinconsistentnaming.

    Youcanalsomakeyourrouteparametersoptionalbyincludingaquestionmark(?)aftertheparametername,asillustratedinExample3-6.Inthiscase,youshouldalsoprovideadefaultvaluefortheroute’scorrespondingvariable.

    Example3-6.OptionalrouteparametersRoute::get('users/{id?}',function($id='fallbackId'){//});

    Andyoucanuseregularexpressions(regexes)todefinethatarouteshouldonlymatchifaparametermeetsparticularrequirements,asinExample3-7.

    Example3-7.RegularexpressionrouteconstraintsRoute::get('users/{id}',function($id){//})->where('id','[0-9]+');

    Route::get('users/{username}',function($username){//})->where('username','[A-Za-z]+');

    Route::get('posts/{id}/{slug}',function($id,$slug){//})->where(['id'=>'[0-9]+','slug'=>'[A-Za-z]+']);

    Asyou’veprobablyguessed,ifyouvisitapaththatmatchesaroutestring,buttheregexdoesn’tmatchtheparameter,itwon’tbematched.Sinceroutesarematchedtoptobottom,

  • users/abcwouldskipthefirstclosureinExample3-7,butitwouldbematchedbythesecondclosure,soitwouldgetroutedthere.Ontheotherhand,posts/abc/123wouldn’tmatchanyoftheclosures,soitwouldreturna404NotFounderror.

  • RouteNamesThesimplestwaytorefertotheserouteselsewhereinyourapplicationisjustbytheirpath.There’saurl()helpertosimplifythatlinkinginyourviews,ifyouneedit;seeExample3-8foranexample.Thehelperwillprefixyourroutewiththefulldomainofyoursite.

    Example3-8.URLhelper

  • DEFININGCUSTOMROUTESINLARAVEL5.1Fluentroutedefinitionsdon’texistinLaravel5.1.You’llneedtoinsteadpassanarraytothesecondparameterofyourroutedefinition;checktheLaraveldocstoseemoreabouthowthisworks.Here’sExample3-9inLaravel5.1:

    Route::get('members/{id}',['as'=>'members.show','uses'=>'MembersController@show']);

    Inourexample,we’venamedthisroutemembers.show;resourcePlural.actionisacommonconventionwithinLaravelforrouteandviewnames.

    ROUTENAMINGCONVENTIONS

    Youcannameyourrouteanythingyou’dlike,butthecommonconventionistousethepluraloftheresourcename,thenaperiod,thentheaction.So,herearetheroutesmostcommonforaresourcenamedphoto:

    photos.indexphotos.createphotos.storephotos.showphotos.editphotos.updatephotos.destroy

    Tolearnmoreabouttheseconventions,see“ResourceControllers”.

    Wealsointroducedtheroute()helper.Justlikeurl(),it’sintendedtobeusedinviewstosimplifylinkingtoanamedroute.Iftheroutehasnoparameters,youcansimplypasstheroutename:(route('members.index'))andreceivearoutestringhttp://myapp.com/members/index).Ifithasparameters,passtheminasanarrayasthesecondparameterlikewedidinthisexample.

    Ingeneral,Irecommendusingroutenamesinsteadofpathstorefertoyourroutes,andthereforeusingtheroute()helperinsteadoftheurl()helper.Sometimesitcangetabitclumsy—forexample,ifyou’reworkingwithmultiplesubdomains—butitprovidesanincrediblelevelofflexibilitytolaterchangetheapplication’sroutingstructurewithoutmajorpenalty.

  • PASSINGROUTEPARAMETERSTOTHEROUTE( ) HELPER

    Whenyourroutehasparameters(e.g.,users/{id}),youneedtodefinethoseparameterswhenyou’reusingtheroute()helpertogeneratealinktotheroute.

    Thereareafewdifferentwaystopasstheseparameters.Let’simaginearoutedefinedasusers/{userId}/comments/{commentId}.IftheuserIDis1andthecommentIDis2,let’slookatafewoptionswehaveavailabletous:

    Option1:

    route('users.comments.show',[1,2])//http://myapp.com/users/1/comments/2

    Option2:

    route('users.comments.show',['userId'=>1,'commentId'=>2])//http://myapp.com/users/1/comments/2

    Option3:

    route('users.comments.show',['commentId'=>2,'userId'=>1])//http://myapp.com/users/1/comments/2

    Option4:

    route('users.comments.show',['userId'=>1,'commentId'=>2,'opt'=>'a'])//http://myapp.com/users/1/comments/2?opt=a

    Asyoucansee,nonkeyedarrayvaluesareassignedinorder;keyedarrayvaluesarematchedwiththerouteparametersmatchingtheirkeys,andanythingleftoverisaddedasaqueryparameter.

  • RouteGroupsOftenagroupofroutesshareaparticularcharacteristic—acertainauthenticationrequirement,apathprefix,orperhapsacontrollernamespace.Definingthesesharedcharacteristicsagainandagainoneachroutenotonlyseemstediousbutalsocanmuddyuptheshapeofyourroutesfileandobscuresomeofthestructuresofyourapplication.

    Routegroupsallowyoutogroupseveralroutestogether,andapplyanysharedconfigurationsettingsoncetotheentiregroup,toreducethisduplication.Additionally,routegroupsarevisualcuestofuturedevelopers(andtoyourownbrain)thattheseroutesaregroupedtogether.

    Togrouptwoormoreroutestogether,you“surround”theroutedefinitionswitharoutegroup,asshowninExample3-10.Inreality,you’reactuallypassingaclosuretothegroupdefinition,anddefiningthegroupedrouteswithinthatclosure.

    Example3-10.DefiningaroutegroupRoute::group([],function(){Route::get('hello',function(){return'Hello';});Route::get('world',function(){return'World';});});

    Bydefault,aroutegroupdoesn’tactuallydoanything.There’snodifferencebetweenthegroupinExample3-10andseparatingasegmentofyourrouteswithcodecomments.Theemptyarraythat’sthefirstparameter,however,allowsyoutopassavarietyofconfigurationsettingsthatwillapplytotheentireroutegroup.

  • MiddlewareProbablythemostcommonuseforroutegroupsistoapplymiddlewaretoagroupofroutes.We’lllearnmoreaboutmiddlewareinChapter10,but,amongotherthings,they’rewhatLaravelusesforauthenticatingusersandrestrictingguestusersfromusingcertainpartsofasite.

    InExample3-11,we’recreatingaroutegrouparoundthedashboardandaccountviewsandapplyingtheauthmiddlewaretoboth.Inthisexample,itmeansusershavetobeloggedintotheapplicationtoviewthedashboardortheaccountpage.

    Example3-11.Restrictingagroupofroutestologged-inusersonlyRoute::group(['middleware'=>'auth'],function(){Route::get('dashboard',function(){returnview('dashboard');});Route::get('account',function(){returnview('account');});});

  • APPLYINGMIDDLEWAREINCONTROLLERSOftenit’sclearerandmoredirecttoattachmiddlewaretoyourroutesinthecontrollerinsteadofattheroutedefinition.Youcandothisbycallingthemiddleware()methodintheconstructorofyourcontroller.Thestringyoupasstothemiddleware()methodisthenameofthemiddleware,andyoucanoptionallychainmodifiermethods(only()andexcept())todefinewhichmethodswillreceivethatmiddleware:

    classDashboardControllerextendsController{publicfunction__construct(){$this->middleware('auth');

    $this->middleware('admin-auth')->only('admin');

    $this->middleware('team-member')->except('admin');}}

    Notethat,ifyou’redoingalotof“only”and“except”customizations,that’softenasignthatyoushouldbreakoutanewcontrollerfortheexceptionalroutes.

  • PathPrefixesIfyouhaveagroupofroutesthatshareasegmentoftheirpath—forexample,ifyoursite’sAPIisprefixedwith/api—youcanuseroutegroupstosimplifythisstructure(seeExample3-12).

    Example3-12.PrefixingagroupofroutesRoute::group(['prefix'=>'api'],function(){Route::get('/',function(){//Handlesthepath/api});Route::get('users',function(){//Handlesthepath/api/users});});

    Notethateachprefixedgroupalsohasa/routethatrepresentstherootoftheprefix—inExample3-12that’s/api.

  • SubdomainRoutingSubdomainroutingisthesameasrouteprefixing,butit’sscopedbysubdomaininsteadofrouteprefix.Therearetwoprimaryusesforthis.First,youmaywanttopresentdifferentsectionsoftheapplication(orentirelydifferentapplications)todifferentsubdomains.Example3-13showshowyoucanachievethis.

    Example3-13.SubdomainroutingRoute::group(['domain'=>'api.myapp.com'],function(){Route::get('/',function(){//});});

    Second,youmightwanttosetpartofthesubdomainasaparameter,asillustratedinExample3-14.Thisismostoftendoneincasesofmultitenancy(thinkSlackorHarvest,whereeachcompanygetsitsownsubdomain,liketighten.slack.co).

    Example3-14.ParameterizedsubdomainroutingRoute::group(['domain'=>'{account}.myapp.com'],function(){Route::get('/',function($account){//});Route::get('users/{id}',function($account,$id){//});});

    Notethatanyparametersforthegroupgetpassedintothegroupedroutes’methodsasthefirstparameter(s).

  • NamespacePrefixesWhenyou’regroupingroutesbysubdomainorrouteprefix,it’slikelytheircontrollershaveasimilarPHPnamespace.IntheAPIexample,alloftheAPIroutes’controllersmightbeunderanAPInamespace.Byusingtheroutegroupnamespaceprefix,asshowninExample3-15,youcanavoidlongcontrollerreferencesingroupslike"API/ControllerA@index"and"API/ControllerB@index".

    Example3-15.Routegroupnamespaceprefixes//App\Http\Controllers\ControllerARoute::get('/','ControllerA@index');

    Route::group(['namespace'=>'API'],function(){//App\Http\Controllers\API\ControllerBRoute::get('api/','ControllerB@index');});

  • NamePrefixesTheprefixesdon’tstopthere.It’scommonthatroutenameswillreflecttheinheritancechainofpathelements,sousers/comments/5willbeservedbyaroutenamedusers.comments.show.Inthiscase,it’scommontousearoutegrouparoundalloftheroutesthatarebeneaththeusers.commentsresource.

    JustlikewecanprefixURLsegmentsandcontrollernamespaces,wecanalsoprefixstringstotheroutename.Withroutegroupnameprefixes,wecandefinethateveryroutewithinthisgroupshouldhaveagivenstringprefixedtoitsname.Inthiscontext,we’reprefixing"users."toeachroutename,then"comments."(seeExample3-16).

    Example3-16.RoutegroupnameprefixesRoute::group(['as'=>'users.','prefix'=>'users'],function(){Route::group(['as'=>'comments.','prefix'=>'comments'],function(){//Routenamewillbeusers.comments.showRoute::get('{id}',function(){//})->name('show');});});

  • ViewsInafewoftherouteclosureswe’velookedatsofar,we’veseensomethingalongthelinesofreturnview('account').What’sgoingonhere?

    Ifyou’renotfamiliarwiththeModel–View–Controller(MVC)pattern,views(ortemplates)arefilesthatdescribewhatsomeparticularoutputshouldlooklike.YoumighthaveviewsforJSONorXMLoremails,butthemostcommonviewsinawebframeworkoutputHTML.

    InLaravel,therearetwoformatsofviewyoucanuseoutofthebox:plainPHP,orBladetemplates(seeChapter4).Thedifferenceisinthefilename:about.phpwillberenderedwiththePHPengine,andabout.blade.phpwillberenderedwiththeBladeengine.

  • THREEWAYSTOLOADAVIEW()Therearethreedifferentwaystoreturnaview.Fornow,justconcernyourselfwithview(),butifyoueverseeView::make(),it’sthesamething,andyoucouldalsoinjecttheIlluminate\View\ViewFactoryifyouprefer.

    Onceyou’veloadedaview,youhavetheoptiontosimplyreturnit(asinExample3-17),whichwillworkfineiftheviewdoesn’trelyonanyvariablesfromthecontroller.

    Example3-17.Simpleview()usageRoute::get('/',function(){returnview('home');});

    Thiscodelooksforaviewinresources/views/home.blade.phporresources/views/home.php,andloadsitscontentsandparsesanyinlinePHPorcontrolstructuresuntilyouhavejusttheview’soutput.Onceyoureturnit,it’spassedontotherestoftheresponsestackandeventuallyreturnedtotheuser.

    Butwhatifyouneedtopassinvariables?TakealookatExample3-18.

    Example3-18.PassingvariablestoviewsRoute::get('tasks',function(){returnview('tasks.index')->with('tasks',Task::all());});

    Thisclosureloadstheresources/views/tasks/index.blade.phporresources/views/tasks/index.phpviewandpassesitasinglevariablenamedtasks,whichcontainstheresultoftheTask::all()method.Task::all()isanEloquentdatabasequerywe’lllearnaboutinChapter8.

  • UsingViewComposerstoShareVariableswithEveryViewSometimesitcanbecomeahassletopassthesamevariablesoverandover.Theremaybeavariablethatyouwantaccessibletoeveryviewinthesite,ortoacertainclassofviewsoracertainincludedsubview—forexample,allviewsrelatedtotasks,ortheheaderpartial.

    It’spossibletosharecertainvariableswitheverytemplateorjustcertaintemplates,likeinthefollowingcode:

    view()->share('variableName','variableValue');

    Tolearnmore,checkout“ViewComposersandServiceInjection”.

  • ControllersI’vementionedcontrollersafewtimes,butuntilnowmostoftheexampleshaveshownrouteclosures.Ifyou’renotfamiliarwiththeMVCpattern(Figure3-1),controllersareessentiallyclassesthatorganizethelogicofoneormoreroutestogetherinoneplace.Controllerstendtogroupsimilarroutestogether,especiallyifyourapplicationisstructuredalongatraditionallyCRUD-likeformat;inthiscase,acontrollermighthandlealltheactionsthatcanbeperformedonaparticularresource.

    Figure3-1.AbasicillustrationofMVC

  • WHATISCRUD?CRUDstandsforcreate,read,update,delete,whicharethefourprimaryoperationsthatwebapplicationsmostcommonlyprovideonaresource.Forexample,youcancreateanewblogpost,youcanreadthatpost,youcanupdateit,oryoucandeleteit.

    Itmaybetemptingtocramalloftheapplication’slogicintothecontrollers,butit’sbettertothinkofcontrollersasthetrafficcopsthatrouteHTTPrequestsaroundyourapplication.Sincethereareotherwaysrequestscancomeintoyourapplication—cronjobs,Artisancommand-linecalls,queuejobs,etc.—it’swisetonotrelyoncontrollersformuchbehavior.Thismeansacontroller ’sprimaryjobistocapturetheintentofanHTTPrequestandpassitontotherestoftheapplication.

    So,let’screateacontroller.OneeasywaytodothisiswithanArtisancommand,sofromthecommandlinerunthefollowing:

    phpartisanmake:controllerTasksController

  • ARTISANANDARTISANGENERATORSLaravelcomesbundledwithacommand-linetoolcalledArtisan.Artisancanbeusedtorunmigrations,createusersandotherdatabaserecordsmanually,andperformmanyothermanual,one-timetasks.

    Underthemakenamespace,Artisanprovidestoolsforgeneratingskeletonfilesforavarietyofsystemfiles.That’swhatallowsustorunphpartisanmake:controller.

    TolearnmoreaboutthisandotherArtisanfeatures,seeChapter7.

    ThiswillcreateanewfilenamedTasksController.phpinapp/Http/Controllers,withthecontentsshowninExample3-19.

    Example3-19.Defaultgeneratedcontroller

  • CONTROLLER NAMESPACING

    InExample3-21wereferencedacontrollerwiththefullyqualifiedclassnameofApp\Http\Controllers\TasksController,butweonlyusedtheclassname.Thisisn’tbecausewecansimplyreferencecontrollersbytheirclassname.Rather,wecanignoretheApp\Http\Controllers\whenwereferencecontrollers;bydefault,Laravelisconfiguredtolookforcontrollerswithinthatnamespace.

    ThismeansthatifyouhaveacontrollerwiththefullyqualifiedclassnameofApp\Http\Controllers\API\ExercisesController,you’dreferenceitinaroutedefinitionasAPI\ExercisesController.

    Themostcommonuseofacontrollermethod,then,willbesomethinglikeExample3-22.

    Example3-22.Commoncontrollermethodexample//TasksController.php...publicfunctionindex(){returnview('tasks.index')->with('tasks',Task::all());}

    Thiscontrollermethodloadstheresources/views/tasks/index.blade.phporresources/views/tasks/index.phpviewandpassesitasinglevariablenamedtasks,whichcontainstheresultoftheTask::all()Eloquentmethod.

  • GENERATINGRESOURCECONTROLLERSIfyoueverusedphpartisanmake:controllerinLaravelpriorto5.3,youmightbeexpectingittoautogeneratemethodsforallofthebasicresourcerouteslikecreate()andupdate().YoucanbringthisbehaviorbackinLaravel5.3bypassingthe--resourceflagwhenyoucreatethecontroller:

    phpartisanmake:controllerTasksController--resource

  • GettingUserInputThesecondmostcommonactiontoperforminacontrollermethodistotakeinputfromtheuserandactonit.Thatintroducesafewnewconcepts,solet’stakealookatabitofsamplecodeandwalkthroughthenewpieces.

    First,let’sbinditquickly;seeExample3-23.

    Example3-23.Bindingbasicformactions//routes/web.phpRoute::get('tasks/create','TasksController@create');Route::post('tasks','TasksController@store');

    Noticethatwe’rebindingtheGETactionoftasks/create(whichshowstheform)andthePOSTactionoftasks/(whichiswherewePOSTwhenwe’recreatinganewtask).Wecanassumethecreate()methodinourcontrollerjustshowsaform,solet’slookatthestore()methodinExample3-24.

    Example3-24.Commonforminputcontrollermethod//TasksController.php...publicfunctionstore(){$task=newTask;$task->title=Input::get('title');$task->description=Input::get('description');$task->save();

    returnredirect('tasks');}

    ThisexamplemakesuseofEloquentmodelsandtheredirect()functionality,andwe’lltalkaboutthemmorelater,butyoucanseewhatwe’redoinghere:wecreateanewTask,pulldataoutoftheuserinputandsetitonthetask,saveit,andthenredirectbacktothepagethatshowsalltasks.

    TherearetwomainwaystogetuserinputfromaPOST:theInputfacade,whichweusedhere,andtheRequestobject,whichwe’lltalkaboutnext.

  • IMPORTINGFACADESIfyoufollowanyoftheseexamples,whetherincontrollersoranyotherPHPclassthatisnamespaced,youmightfinderrorsshowingthatthefacadecannotbefound.Thisisbecausethey’renotpresentineverynamespace,butratherthey’remadeavailableintherootnamespace.

    So,inExample3-24,we’dneedtoimporttheInputfacadeatthetopofthefile.Therearetwowaystodothat:eitherwecanimport\Input,orwecanimportIlluminate\Support\Facades\Input.Forexample:

  • InjectingDependenciesintoControllersLaravel’sfacadespresentasimpleinterfacetothemostusefulclassesinLaravel’scodebase.Youcangetinformationaboutthecurrentrequestanduserinput,thesession,caches,andmuchmore.

    Butifyouprefertoinjectyourdependencies,orifyouwanttouseaservicethatdoesn’thaveafacade,you’llneedtofindsomewaytobringinstancesoftheseclassesintoyourcontroller.

    ThisisourfirstexposuretoLaravel’sservicecontainer.Fornow,ifthisisunfamiliar,youcanthinkaboutitasalittlebitofLaravelmagic;or,ifyouwanttoknowmoreabouthowit’sactuallyfunctioning,youcanskipaheadtoChapter11.

    Allcontrollermethods(includingtheconstructors)areresolvedoutofLaravel’scontainer,whichmeansanythingyoutypehintthatthecontainerknowshowtoresolvewillbeautomaticallyinjected.

    Asaniceexample,whatifyou’dpreferhavinganinstanceoftheRequestobjectinsteadofusingthefacade?JusttypehintIlluminate\Http\Requestinyourmethodparameters,likeinExample3-25.

    Example3-25.Controllermethodinjectionviatypehinting//TasksController.php...publicfunctionstore(\Illuminate\Http\Request$request){$task=newTask;$task->title=$request->input('title');$task->description=$request->input('description');$task->save();

    returnredirect('tasks');}

    So,you’vedefinedaparameterthatmustbepassedintothestore()method.Andsinceyoutypehintedit,andsinceLaravelknowshowtoresolvethatclassname,you’regoingtohavetheRequestobjectreadyforyoutouseinyourmethodwithnoworkonyourpart.Noexplicitbinding,noanythingelse—it’sjustthereasthe$requestvariable.

    Bytheway,thisisactuallyhowIandmanyotherLaraveldevelopersprefertogettheuserinput:injectaninstanceoftheRequestandreadtheuserinputfromthere,insteadofrelyingontheInputfacade.

  • ResourceControllersSometimesnamingthemethodsinyourcontrollerscanbethehardestpartofwritingacontroller.Thankfully,LaravelhassomeconventionsforalloftheroutesofatraditionalREST/CRUDcontroller(calleda“resourcecontroller”inLaravel);additionally,itcomeswithageneratoroutoftheboxandaconvenienceroutedefinitionthatallowsyoutobindanentireresourcecontrolleratonce.

    ToseethemethodsthatLaravelexpectsforaresourcecontroller,let’sgenerateanewcontrollerfromthecommandline:

    phpartisanmake:controllerMySampleResourceController--resource

    Nowopenapp/Http/Controllers/MySampleResourceController.php.You’llseeitcomesprefilledwithquiteafewmethods.Let’swalkoverwhateachrepresents.We’lluseaTaskasanexample.

    ThemethodsofLaravel’sresourcecontrollersForeach,youcanseetheHTTPverb,theURL,thecontrollermethodname,andthe“name.”Table3-1showstheHTTPverb,theURL,thecontrollermethodname,andthe“name”foreachofthesedefaultmethods.

    Table3-1.ThemethodsofLaravel’sresourcecontrollers

    Verb URL Controllermethod Name Description

    GET tasks index() tasks.index Showalltasks

    GET tasks/create create() tasks.create Showthecreatetaskform

    POST tasks store() tasks.store Acceptformsubmissionfromthecreatetaskform

    GET tasks/{task} show() tasks.show Showonetask

    GET tasks/{task}/edit edit() tasks.edit Editonetask

    PUT/PATCH tasks/{task} update() tasks.update Acceptformsubmissionfromtheedittaskform

    DELETE tasks/{task} destroy() tasks.destroy Deleteonetask

    BindingaresourcecontrollerSo,we’veseenthatthesearetheconventionalroutenamestouseinLaravel,andalsothatit’seasytogeneratearesourcecontrollerwithmethodsforeachofthesedefaultroutes.Thankfully,youdon’thavetogenerateroutesforeachofthesecontrollermethodsbyhand,ifyoudon’twantto.Instead,there’satrickforthat,andit’scalled“resourcecontrollerbinding.”TakealookatExample3-26.

  • Example3-26.Resourcecontrollerbinding//routes/web.phpRoute::resource('tasks','TasksController');

    Thiswillautomaticallybindalloftheroutesforthisresourcetotheappropriatemethodnamesonthespecifiedcontroller.It’llalsonametheseroutesappropriately;forexample,theindex()methodonthetasksresourcecontrollerwillbenamedtasks.index.

  • ARTISANROUTE:LISTIfyoueverfindyourselfinasituationwhereyou’rewonderingwhatroutesyourcurrentapplicationhasavailable,there’satoolforthat:fromthecommandline,runphpartisanroute:listandyou’llgetalistingofalloftheavailableroutes(seeFigure3-2).

    Figure3-2.phpartisanroute:listexample

  • RouteModelBindingOneofthemostcommonroutingpatternsisthatthefirstlineofanycontrollermethodtriestofindtheresourcewiththegivenID,likeinExample3-27.

    Example3-27.GettingaresourceforeachrouteRoute::get('conferences/{id}',function($id){$conference=Conference::findOrFail($id);});

    Laravelprovidesafeaturethatsimplifiesthispatterncalled“routemodelbinding.”Thisallowsyoutodefinethataparticularparametername(e.g.,{conference})willindicatetotherouteresolverthatitshouldlookupanEloquentrecordwiththatIDandthenpassitinastheparameterinsteadofjustpassingtheID.

    Therearetwokindsofroutemodelbinding:implicitandcustom(orexplicit).

  • ImplicitRouteModelBindingThesimplestwaytouseroutemodelbindingistonameyourrouteparametersomethinguniquetothatmodel(e.g.,nameit$conferenceinsteadof$id),thentypehintthatparameterintheclosure/controllermethodandusethesamevariablenamethere.It’seasiertoshowthantodescribe,sotakealookatExample3-28.

    Example3-28.UsinganexplicitroutemodelbindingRoute::get('conferences/{conference}',function(Conference$conference){returnview('conferences.show')->with('conference',$conference);});

    Becausetherouteparameter({conference})isthesameasthemethodparameter($conference),andthemethodparameteristypehintedwithaConferencemodel(Conference$conference),Laravelseesthisasaroutemodelbinding.Everytimethisrouteisvisited,theapplicationwillassumethatwhateverispassedintotheURLinplaceof{conference}isanIDthatshouldbeusedtolookupaConference,andthenthatresultingmodelinstancewillbepassedintoyourclosureorcontrollermethod.

  • CUSTOMIZINGTHEROUTEKEYFORANELOQUENTMODELAnytimeanEloquentmodelislookedupviaaURLsegment(usuallybecauseofroutemodelbinding),thedefaultcolumnEloquentwilllookitupbyisitsprimarykey(ID).

    TochangethecolumnyourEloquentmodelusesforURLlookups,addamethodtoyourmodelnamedgetRouteKeyName():

    publicfunctiongetRouteKeyName(){return'slug';}

    Now,aURLlikeconferences/{conference}willexpecttogetthesluginsteadoftheID,andwillperformitslookupsaccordingly.

    ImplicitroutemodelbindingwasaddedinLaravel5.2,soyouwon’thaveaccesstoitin5.1.

  • CustomRouteModelBindingTomanuallyconfigureroutemodelbindings,addalineliketheoneinExample3-29totheboot()methodinApp\Providers\RouteServiceProvider.

    Example3-29.Addingaroutemodelbindingpublicfunctionboot(Router$router){//Justallowstheparent'sboot()methodtostillrunparent::boot($router);

    //Performthebinding$router->model('event',Conference::class);}

    You’venowdefinedthatwheneveraroutehasaparameterinitsdefinitionnamed{event},asdemonstratedinExample3-30,therouteresolverwillreturnaninstanceoftheConferenceclasswiththeIDofthatURLparameter.

    Example3-30.UsinganexplicitroutemodelbindingRoute::get('events/{event}',function(Conference$event){returnview('events.show')->with('event',$event);});

  • RouteCachingIfyou’relookingtosqueezeeverymillisecondoutofyourloadtime,youmaywanttotakealookatroutecaching.OneofthepiecesofLaravel’sbootstrapthatcantakeanywherefromafewdozentoafewhundredmillisecondsisparsingtheroutes/*files,androutecachingspeedsupthisprocessdramatically.

    Tocacheyourroutesfile,youneedtobeusingallcontrollerandresourceroutes(norouteclosures).Ifyourappisn’tusinganyrouteclosures,youcanrunphpartisanroute:cache,Laravelwillserializetheresultsofyourroutes/*files.Ifyouwanttodeletethecache,runphpartisanroute:clear.

    Here’sthedrawback:Laravelwillnowmatchroutesagainstthatcachedfileinsteadofyouractualroutes/*files.Youcanmakeendlesschangestothosefiles,andtheywon’ttakeeffectuntilyourunroute:cacheagain.Thismeansyou’llhavetorecacheeverytimeyoumakeachange,whichintroducesalotofpotentialforconfusion.

    Here’swhatIwouldrecommendinstead:sinceGitignorestheroutecachefilebydefaultanyway,consideronlyusingroutecachingonyourproductionserver,andrunthephpartisanroute:cachecommandeverytimeyoudeploynewcode(whetherviaaGitpost-deployhook,aForgedeploycommand,orasapartofwhateverotherdeploysystemyouuse).Thiswayyouwon’thaveconfusinglocaldevelopmentissues,butyourremoteenvironmentwillstillbenefitfromroutecaching.

  • FormMethodSpoofingSometimes,youneedtomanuallydefinewhichHTTPverbaformshouldsendas.HTMLformsonlyallowforGETorPOST,soifyouwantanyothersortofverb,you’llneedtospecifythatyourself.

  • AnIntroductiontoHTTPVerbsWe’vetalkedabouttheGETandPOSTHTTPverbsalready.Ifyou’renotfamiliarwithHTTPverbs,theothertwomostcommononesarePUTandDELETE,butthere’salsoHEAD,OPTIONS,PATCH,andtwoothersthatareprettymuchneverusedinnormalwebdevelopment,TRACEandCONNECT.

    Here’sthequickrundown:GETrequestsaresourceandHEADasksforaheaders-onlyversionoftheGET,POSTcreatesaresource,PUToverwritesaresourceandPATCHmodifiesaresource,DELETEdeletesaresource,andOPTIONSaskstheserverwhichverbsareallowedatthisURL.

  • HTTPVerbsinLaravelAswe’veshownalready,youcandefinewhichverbsaroutewillmatchintheroutedefinitionusingRoute::get(),Route::post(),Route::any(),orRoute::match().YoucanalsomatchwithRoute::patch(),Route::put(),andRoute::delete().

    ButhowdoesonesendarequestotherthanGETwithawebbrowser?First,themethodattributeinanHTMLformdeterminesitsHTTPverb:ifyourformhasamethodof"GET",itwillsubmitviaqueryparametersandaGETmethod;iftheformhasamethodof"POST",itwillsubmitviathepostbodyandaPOSTmethod.

    JavaScriptframeworksmakeiteasytosendotherrequests,likeDELETEandPATCH.ButifyoufindyourselfneedingtosubmitHTMLformsinLaravelwithverbsotherthanGETorPOST,you’llneedtouseformmethodspoofing,whichisspoofingtheHTTPmethodinanHTMLform.

  • HTTPMethodSpoofinginHTMLFormsToinformLaravelthattheformyou’recurrentlysubmittingshouldbetreatedassomethingotherthanPOST,addahiddenvariablenamed_methodwiththevalueofeither"PUT","PATCH",or"DELETE",andLaravelwillmatchandroutethatformsubmissionasifitwereactuallyarequestwiththatverb.

    TheforminExample3-31,sinceit’spassingLaravelthemethodof"DELETE",willmatchroutesdefinedwithRoute::delete()butnotthosewithRoute::post().

    Example3-31.Formmethodspoofing

  • CSRFProtectionIfyou’vetriedtocreateandsubmitaforminaLaravelapplicationalready—includingtheforminExample3-31—you’velikelyrunintothedreadedTokenMismatchException.

    Bydefault,allroutesinLaravelexcept“read-only”routes(thoseusingGET,HEAD,orOPTIONS)areprotectedagainstcross-siterequestforgery(CSRF)attacksbyrequiringatoken,intheformofaninputnamed_token,tobepassedalongwitheachrequest.Thistokenisgeneratedatthestartofeverysession,andeverynon–read-onlyroutecomparesthesubmitted_tokenagainstthesessiontoken.

  • WHATISCSRF?Across-siterequestforgeryiswhenonewebsitepretendstobeanother.Thegoalisforsomeonetohijackyourusers’accesstoyourwebsite,bysubmittingformsfromtheirwebsitetoyourwebsiteviathelogged-inuser’sbrowser.

    ThebestwayaroundCSRFattacksistoprotectallinboundroutes—POST,DELETE,etc.—withatoken,whichLaraveldoesoutofthebox.

    Youhavetwooptionsforgettingaroundthis.Thefirst,andpreferred,methodistoaddthe_tokeninputtoeachofyoursubmissions.InHTMLforms,that’ssimple;lookatExample3-32.

    Example3-32.CSRFtokens

  • RedirectsSofartheonlythingswe’vereturnedfromacontrollermethodorroutedefinitionhavebeenviews.Butthereareafewotherstructureswecanreturntogivethebrowserinstructionsonhowtobehave.

    First,let’scovertheredirect.Therearetwocommonwaystogeneratearedirect;we’llusetheredirectglobalhelperhere,butyoumaypreferthefacade.BothcreateaninstanceofIlluminate\Http\RedirectResponse,performsomeconveniencemethodsonit,andthenreturnit.Youcanalsodothismanually,butyou’llhavetodoalittlemoreworkyourself.TakealookatExample3-34toseeafewwaysyoucanreturnaredirect.

    Example3-34.Differentwaystoreturnaredirect//UsingtheglobalhelpertogeneratearedirectresponseRoute::get('redirect-with-helper',function(){returnredirect()->to('login');});

    //UsingtheglobalhelpershortcutRoute::get('redirect-with-helper-shortcut',function(){returnredirect('login');});

    //UsingthefacadetogeneratearedirectresponseRoute::get('redirect-with-facade',function(){returnRedirect::to('login');});

    Notethattheredirect()helperexposesthesamemethodsastheRedirectfacade,butitalsohasashortcut;ifyoupassparametersdirectlytothehelper,insteadofchainingmethodsafterit,it’sashortcuttotheto()redirectmethod.

  • redirect()->to()Themethodsignaturefortheto()methodforredirectslookslikethis:

    functionto($to=null,$status=302,$headers=[],$secure=null)

    $toisavalidinternalpath;$statusistheHTTPstatus(defaultingto302FOUND);$headersallowsyoutodefinewhichHTTPheaderstosendalongwithyourredirect;and$secureallowsyoutooverridethedefaultchoiceofhttpversushttps(whichisnormallysetbasedonyourcurrentrequestURL).Example3-35showsanotherexampleofitsuse.

    Example3-35.redirect()->to()Route::get('redirect',function(){returnredirect()->to('home');

    //orsame,usingtheshortcut:

    returnredirect('home');});

  • redirect()->route()Theroute()methodisthesameastheto()method,butratherthanpointingtoaparticularpath,itpointstoaparticularroutename(seeExample3-36).

    Example3-36.redirect()->route()Route::get('redirect',function(){returnredirect()->route('conferences.index');});

    Notethat,sincesomeroutenamesrequireparameters,itsparameterorderisalittledifferent.route()hasanoptionalsecondparameterfortherouteparameters:

    functionroute($to=null,$parameters=[],$status=302,$headers=[])

    So,usingitmightlookalittlelikeExample3-37.

    Example3-37.redirect()->route()withparametersRoute::get('redirect',function(){returnredirect()->route('conferences.show',['conference'=>99]);});

  • redirect()->back()Becauseofsomeofthebuilt-inconveniencesofLaravel’ssessionimplementation,yourapplicationwillalwayshaveknowledgeofwhattheuser ’spreviouslyvisitedpagewas.Thatopensuptheopportunityforaredirect()->()redirect,whichsimplyredirectstheusertowhateverpageshecamefrom.There’salsoaglobalshortcutforthis:back().

  • OtherRedirectMethodsTheredirectserviceprovidesothermethodsthatarelesscommonlyused,butstillavailable:

    home()redirectstoaroutenamedhome.

    refresh()redirectstothesamepagetheuseriscurrentlyon.

    away()allowsforredirectingtoanexternalURLwithoutthedefaultURLvalidation.

    secure()isliketo()withthesecureparametersetto"true".

    action()allowsyoutolinktoacontrollerandmethodlikethis:redirect()->action('MyController@myMethod').

    guest()isusedinternallybytheauthsystem(discussedinChapter9);whenauservisitsaroutehe’snotauthenticatedfor,thiscapturesthe“intended”routeandthenredirectstheuser(usuallytoaloginpage).

    intended()isalsousedinternallybytheauthsystem;afterasuccessfulauthentication,thisgrabsthe“intended”URLstoredbytheguest()methodandredirectstheuserthere.

  • redirect()->with()Whenyou’reredirectinguserstodifferentpages,youoftenwanttopasscertaindataalongwiththem.Youcouldmanuallyflashthedatatothesession,butLaravelhassomeconveniencemethodstohelpyouwiththat.

    Mostcommonly,youcanpassalongeitheranarrayofkeysandvaluesorasinglekeyandvalueusingwith(),likeinExample3-38.

    Example3-38.RedirectwithdataRoute::get('redirect-with-key-value',function(){returnredirect('dashboard')->with('error',true);});

    Route::get('redirect-with-array',function(){returnredirect('dashboard')->with(['error'=>true,'message'=>'Whoops!']);});

  • CHAININGMETHODSONREDIRECTSAswithmanyotherfacades,mostcallstotheRedirectfacadecanacceptfluentmethodchains,likethewith()callsinExample3-38.Learnmoreaboutfluencyin“WhatIsaFluentInterface?”.

    YoucanalsousewithInput(),asinExample3-39,toredirectwiththeuser ’sforminputflashed;thisismostcommoninthecaseofavalidationerror,whereyouwanttosendtheuserbacktotheformshejustcamefrom.

    Example3-39.RedirectwithforminputRoute::get('form',function(){returnview('form');});

    Route::post('form',function(){returnredirect('form')->withInput()->with(['error'=>true,'message'=>'Whoops!']);});

    TheeasiestwaytogettheflashedinputthatwaspassedwithwithInput()isusingtheold()helper,whichcanbeusedtogetalloldinput(old())orjustthevalueforaparticularkey(old('username'),withthesecondparameterasthedefaultifthereisnooldvalue).You’llcommonlyseethisinviews,whichallowsthisHTMLtobeusedbothonthe“create”andthe“edit”viewforthisform:

  • THEVALIDATE()SHORTCUTINCONTROLLERMETHODSLikehowExample3-40looks?Ifyou’redefiningyourroutesinacontroller,there’sasimpleandpowerfultoolthatcleansupthatcode.Readmorein“validate()intheControllerUsingValidatesRequests”.

  • AbortingtheRequestAsidefromreturningviewsandredirects,themostcommonwaytoexitarouteistoabort.Thereareafewgloballyavailablemethods(abort(),abort_if(),andabort_unless()),whichoptionallytakeHTTPstatuscodes,amessage,andaheadersarrayasparameters.

    AsExample3-41shows,abort_if()andabort_unless()takeafirstparameterthatisevaluatedforitstruthiness,andperformtheabortdependingontheresult.

    Example3-41.403ForbiddenabortsRoute::post('something-you-cant-do',function(Illuminate\Http\Request){abort(403,'Youcannotdothat!');abort_unless($request->has('magicToken'),403);abort_if($request->user()->isBanned,403);});

  • CustomResponsesThereareafewotheroptionsavailableforustoreturn,solet’sgooverthemostcommonresponsesafterviews,redirects,andaborts.Justlikewithredirects,youcaneitherusetheresponse()helperortheResponsefacadetorunthesemethodson.

  • response()->make()IfyouwanttocreateanHTTPresponsemanually,justpassyourdataintothefirstparameterofresponse()->make():e.g.,returnresponse()->make('Hello,World!').Onceagain,thesecondparameteristheHTTPstatuscodeandthethirdisyourheaders.

  • response()->json()and->jsonp()TocreateaJSON-encodedHTTPresponsemanually,passyourJSON-ablecontent(arrays,collections,orwhateverelse)tothejson()method:e.g.,returnresponse()->json(User::all());.It’sjustlikemake(),exceptitjson_encodesyourcontentandsetstheappropriateheaders.

  • response()->download()and->file()Tosendafilefortheendusertodownload,passeitheranSplFileInfoinstanceorastringfilenametodownload(),withanoptionalsecondparameterofthefilename:e.g.,returnresponse()->download('file501751.pdf','myFile.pdf').

    Todisplaythesamefileinthebrowser(ifit’saPDForanimageorsomethingelsethebrowsercanhandle),useresponse()->file()instead,whichtakesthesameparameters.

  • TestingInsomeothercommunities,theideaofunittestingcontrollermethodsiscommon,butwithinLaravel(andmostofthePHPcommunity),it’smostcommontorelyonapplicationtestingtotestthefunctionalityofroutes.

    Forexample,toverifythataPOSTrouteworkscorrectly,wecanwriteatestlikeExample3-42.

    Example3-42.WritingasimplePOSTroutetest//AssignmentTest.phppublicfunctiontest_post_creates_new_assignment(){$this->post('/assignments',['title'=>'Mygreatassignment']);

    $this->seeInDatabase('assignments',['title'=>'Mygreatassignment']);}

    Didwedirectlycallthecontrollermethods?No.Butweensuredthatthegoalofthisroute—toreceiveaPOSTandsaveitsimportantinformationtothedatabase—wasmet.

    Youcanalsousesimilarsyntaxtovisitarouteandverifythatcertaintextshowsuponthepage,orthatclickingcertainbuttonsdoescertainthings(seeExample3-43).

    Example3-43.WritingasimpleGETroutetest//AssignmentTest.phppublicfunctiontest_list_page_shows_all_assignments(){$assignment=Assignment::create(['title'=>'Mygreatassignment']);

    $this->visit('assignments')->dee(['Mygreatassignment']);}

  • TL;DRLaravel’sroutesaredefinedinroutes/web.phpandroutes/api.php,whereyoucandefinetheexpectedpathforeachroute,whichsegmentsarestaticandwhichareparameters,whichHTTPverbscanaccesstheroute,andhowtoresolveit.Youcanalsoattachmiddlewaretoroutes,groupthem,andgivethemnames.

    WhatisreturnedfromtherouteclosureorcontrollermethoddictateshowLaravelrespondstotheuser.Ifit’sastringoraview,it’spresentedtotheuser;ifit’sothersortsofdata,it’sconvertedtoJSONandpresentedtotheuser;andifit’saredirect,itforcesaredirect.

    Laravelprovidesaseriesoftoolsandconveniencestosimplifycommonrouting-relatedtasksandstructures.Theseincluderesourcecontrollers,routemodelbinding,andformmethodspoofing.

  • Chapter4.BladeTemplating

    Comparedtomostotherbackendlanguages,PHPactuallyfunctionsrelativelywellasatemplatinglanguage.Butithasitsshortcomings,andit’salsojustuglytobeusing

  • USINGTWIGWITHLARAVELUnlikemanyotherSymfony-basedframeworks,Laraveldoesn’tuseTwigbydefault.Butifyou’rejustinlovewithTwig,there’saTwigBridgepackagethatmakesiteasytouseTwiginsteadofBlade.

    https://github.com/rcrowe/TwigBridge

  • EchoingDataAsyoucanseeinExample4-1,{{and}}areusedtowrapsectionsofPHPthatyou’dliketoecho.{{$variable}}issimilartoinplainPHP.

    It’sdifferentinoneway,however,andyoumight’veguessedthisalready:BladeescapesallechoesbydefaultusingPHP’shtmlentities()toprotectyourusersfrommaliciousscriptinsertion.Thatmeans{{$variable}}isfunctionallyequivalentto.Ifyouwanttoechowithouttheescaping,use{!!and!!}instead.

    {{AND}}WHENUSINGAFRONTENDTEMPLATINGFRAMEWORK

    Youmight’venoticedthattheechosyntaxforBlade({{}})issimilartotheechosyntaxformanyfrontendframeworks.So,howdoesLaravelknowwhenyou’rewritingBladeversusHandlebars?

    Bladewillignoreany{{that’[email protected],itwillparsethefirstofthefollowingexamples,butthesecondwillbeechoedoutdirectly:

    //ParsedasBlade;thevalueof$bladeVariableisechoedtotheview{{$bladeVariable}}

    //@isremoved,and"{{handlebarsVariable}}"echoedtotheviewdirectly@{{handlebarsVariable}}

  • ControlStructuresMostofthecontrolstructuresinBladewillbeveryfamiliar.ManydirectlyechothenameandstructureofthesametaginPHP.

    Thereareafewconveniencehelpers,butingeneral,thecontrolstructuresjustlookcleanerthantheywouldinPHP.

  • ConditionalsFirst,let’stakealookatthecontrolstructuresthatallowforlogic.

    @ifBlade’s@if($condition)compilesto.@else,@elseif,and@endifalsocompiletotheexactsamesyntaxinPHP.TakealookatExample4-2forsomeexamples.

    Example4-2.@if,@else,@elseif,and@endif@if(count($talks)===1)Thereisonetalkatthistimeperiod.@elseif(count($talks)===0)Therearenotalksatthistimeperiod.@elseThereare{{count($talks)}}talksatthistimeperiod.@endif

    JustlikewiththenativePHPconditionals,youcanmixandmatchthesehowyouwant.Theydon’thaveanyspeciallogic;there’sliterallyaparserlookingforsomethingwiththeshapeof@if($condition)andreplacingitwiththeappropriatePHPcode.

    @unlessand@endunless@unless,ontheotherhand,isanewsyntaxthatdoesn’thaveadirectequivalentinPHP.It’sthedirectinverseof@if.@unless($condition)isthesameas

  • LoopsNext,let’stakealookattheloops.

    @for,@foreach,and@while@for,@foreach,and@whileworkthesameinBladeastheydoinPHP;seeExamples4-4,4-5,and4-6.

    Example4-4.@forand@endfor@for($i=0;$i<$talk->slotsCount();$i++)Thenumberis{{$i}}
    @endfor

    Example4-5.@foreachand@endforeach@foreach($talksas$talk)•{{$talk->title}}({{$talk->length}}minutes)
    @endforeach

    Example4-6.@whileand@endwhile@while($item=array_pop($items)){{$item->orSomething()}}
    @endwhile

    @forelse@forelseisa@foreachthatalsoallowsyoutoprograminafallbackiftheobjectyou’reiteratingoverisempty.Wesawitinactionatthestartofthischapter;Example4-7showsanotherexample.

    Example4-7.@forelse@forelse($talksas$talk)•{{$talk->title}}({{$talk->length}}minutes)
    @emptyNotalksthisday.@endforelse

  • $LOOPWITHIN@FOREACHAND@FORELSEThe@[email protected]’snotavailableinPHPforeachloops:the$loopvariable.Usedwithina@foreachor@forelseloop,thisvariablewillreturnastdClassobjectwiththefollowingproperties:

    index

    The0-basedindexofthecurrentitemintheloop;0wouldmean“fi