I de senere år har Laravel blitt en av de mest fremtredende rammer som programvareingeniører bruker til å bygge sine webapplikasjoner. I likhet med populariteten som CodeIgniter likte i sin høytid, har Laravel blitt lovet for brukervennlighet, vennlighet til nybegynnere og overholdelse av industristandarder.
En ting om at det ikke mange programmerere utnytter er Laravels komponentbaserte system. Siden konverteringen til komponentdrevne komponenter, har Laravel 4 blitt et veldig modulært system, som ligner på overflaten av mer modne rammer som Symfony. Dette kalles Belyse
Gruppe av komponenter, som etter min mening ikke er selve rammen selv, men er en samling av biblioteker som et rammeverk potensielt kan bruke. Laravels faktiske rammeverk er representert av Laravel-skjelettapplikasjonen (funnet på laravel / laravel
GitHub repository) som bruker disse komponentene til å bygge et webprogram.
I denne opplæringen dykker vi inn i en gruppe av disse komponentene, lærer hvordan de fungerer, hvordan de brukes av rammen, og hvordan vi kan utvide deres funksjonalitet.
Laravel Session-komponenten håndterer økter for webapplikasjonen. Den bruker et driverbasert system kalt Laravel Manager, som fungerer som både en fabrikk og en wrapper for hvilken driver som er angitt i konfigurasjonsfilen. Med denne skrivingen har sesjonskomponenten drivere for:
fil
- en filbasert øktdriver der øktdata lagres i en kryptert fil.cookie
- en informasjonskapselbasert øktdriver hvor øktdata krypteres i brukerens informasjonskapsler.database
- øktdata lagres i hvilken database som er konfigurert for applikasjonen.APC
- øktdata lagres i APC.memcached
- øktdata lagres i Memcached.Redis
- øktdata lagres i redis.matrise
- øktdata lagres i et PHP-array. Vær oppmerksom på at array-sjåføren ikke støtter utholdenhet og vanligvis bare brukes i konsollkommandoer.De fleste Laravel-brukere skjønner ikke, men en stor del av hvordan Laravel fungerer, er innenfor sine tjenesteleverandører. De er i hovedsak bootstrap-filer for hver komponent, og de er abstraherte nok, slik at brukere kan starte opp noen komponenter på noen måte.
En grov forklaring på hvordan dette virker er under:
registrere
Metoden kalles. Dette gjør det mulig for oss å instansere hvilken komponent vi ønsker. $ Dette-> app
), som ville la tjenesteleverandørene skyve forekomster av de løste klassene inn i avhengighetsbeholderen.App :: make
.Når vi går tilbake til øktene, la oss ta en rask titt på SessionServiceProivider
:
/ ** * Registrer sessionsadministratorens forekomst. * * @return void * / beskyttet funksjon registerSessionManager () $ this-> app-> bindShare ('økt', funksjon ($ app) return new SessionManager ($ app);); / ** * Registrer sessionsdriverens forekomst. * * @return void * / beskyttet funksjon registerSessionDriver () $ this-> app-> bindShare ('session.store', funksjon ($ app) // Først skal vi opprette øktleder som er ansvarlig for / / opprettelse av de ulike sessionsdrivere når de trengs av // søknad instansen, og vil løse dem på lazy load basis. $ manager = $ app ['session'], returner $ manager-> driver ();) ;
Disse to metodene kalles av registrere()
funksjon. Den første, registerSessionManager ()
, er kalt til å opprinnelig registrere SessionManager
. Denne klassen utvider sjef
som jeg nevnte på toppen. Den andre, registerSessionDriver ()
registrerer en øktbehandler for lederen, basert på det vi har konfigurert. Dette kalles til slutt denne metoden i Belyse \ Support \ manager
klasse:
/ ** * Opprett en ny driverinstans. * * @param streng $ driver * @return blandet * * @throws \ InvalidArgumentException * / beskyttet funksjon createDriver ($ driver) $ method = 'create'.ucfirst ($ driver).' Driver '; // Vi kontrollerer for å se om en skapningsmetode eksisterer for den oppgitte driveren. Hvis ikke, vil vi // sjekke om en tilpasset driveropprettelse, som gjør det mulig for utviklere å lage // drivere ved å bruke sin egen tilpassede driver skaperen Closure for å lage den. hvis (isset ($ this-> customCreators [$ driver])) return $ this-> callCustomCreator ($ driver); elseif (method_exists ($ this, $ method)) return $ this -> $ metode (); kaste nye \ InvalidArgumentException ("Driver [$ driver] støttes ikke.");
Herfra kan vi se at basert på navnet på driveren, fra konfigurasjonsfilen, kalles en bestemt metode. Så, hvis vi har det konfigurert til å bruke fil
økt behandler, vil det kalle denne metoden i SessionManager
klasse:
/ ** * Opprett en forekomst av filsessionsdriveren. * * @return \ Illuminate \ Session \ Store * / beskyttet funksjon createFileDriver () return $ this-> createNativeDriver (); / ** * Opprett en forekomst av filsessionsdriveren. * * @return \ Illuminate \ Session \ Store * / beskyttet funksjon createNativeDriver () $ path = $ this-> app ['config'] ['session.files']; returnere $ this-> buildSession (ny FileSessionHandler ($ this-> app ['files'], $ path));
Førerklassen injiseres deretter inn i a butikk
klassen, som er ansvarlig for å ringe til de faktiske økt metodene. Dette lar oss faktisk skille implementeringen av SessionHandlerInterface
fra SPL til driverne, den butikk
klassen letter det.
La oss lage vår egen Session Handler, en MongoDB Session Handler. Først må vi opprette en MongoSessionHandler
inne i en nyinstallert Laravel prosjekt instans. (Vi skal låne tungt fra Symfony \ Component \ HttpFoundation \ Session \ Storage \ Handler \ MongoDbSessionHandler
) .:
config = $ config; $ connection_string = 'mongodb: //'; hvis ! tom ($ this-> config ['brukernavn']) &&! tomt ($ this-> config ['passord'])) $ connection_string. = "$ this-> config ['bruker'] : $ dette-> konfig [ 'passord'] @ "; $ connection_string. = "$ this-> config ['host']"; $ this-> connection = new Mongo ($ connection_string); $ this-> collection = $ this-> connection-> selectCollection ($ this-> config ['database'], $ this-> config ['samling']); / ** * @inheritDoc * / offentlig funksjon åpen ($ savePath, $ sessionName) return true; / ** * @inheritDoc * / offentlig funksjon lukk () return true; / ** * @inheritDoc * / public function read ($ sessionId) $ session_data = $ this-> collection-> findOne (array ('_id' => $ sessionId,)); hvis is_null ($ session_data)) return "; annet return $ session_data ['session_data'] -> bin; / ** * @inheritDoc * / offentlig funksjon skrive ($ sessionId, $ data) $ this-> collection-> update (array ('_id' => $ sessionId), array ('$ set' => array ('session_data' => ny MongoBinData ($ data, MongoBinData :: BYTE_ARRAY), 'tidsstempel' => ny MongoDate (),)), array ('upsert' => true, 'multiple' => false)); / ** * @inheritDoc * / offentlig funksjon ødelegge ($ sessionId) $ this- > samling-> fjern (array ('_id' => $ sessionId)); return true; / ** * @inheritDoc * / offentlig funksjon gc ($ levetid) $ time = new MongoDate $ levetid); $ dette-> samling-> fjern (array ('timestamp' => array ('$ lt' => $ tid),)); return true;
Du bør lagre dette i leverandør / laravel / rammeverk / src / Illuminate / økt
mappe. I forbindelse med dette prosjektet legger vi det her, men ideelt sett bør denne filen være innenfor eget navneområde for biblioteket.
Deretter må vi sørge for at sjef
klassen kan ringe denne driveren. Vi kan gjøre dette ved å benytte Manager :: forlenge
metode. Åpen leverandør / laravel / rammeverk / src / Illuminate / økt / SessionServiceProvider.php
og legg til følgende kode. Ideelt sett bør vi utvide tjenesteleverandøren, men det er utenfor omfanget av denne opplæringen.
/ ** * Konfigurer Mongo Driver tilbakeringing * * @return void * / offentlig funksjon setupMongoDriver () $ manager = $ this-> app ['session']; $ manager-> utvide ('mongo', funksjon ($ app) returner ny MongoSessionHandler (array ('host' => $ app ['config'] -> get ('session.mongo.host'), 'brukernavn' => $ app ['config'] -> få ('session.mongo.username'), 'passord' => $ app ['config'] -> få ('session.mongo.password'), 'database' => $ app ['config'] -> få ('session.mongo.database'), 'samling' => $ app ['config'] -> få ('session.mongo.collection'))); );
Pass på at du oppdaterer registrere()
metode for å ringe denne metoden:
/ ** * Registrer tjenesteleverandøren. * * @return void * / public function register () $ this-> setupDefaultDriver (); $ Dette-> registerSessionManager (); $ Dette-> setupMongoDriver (); $ Dette-> registerSessionDriver ();
Deretter må vi definere Mongo DB-konfigurasjonen. Åpen app / config / session.php
og definer følgende konfigurasjonsinnstillinger:
/ ** * Mongo DB-innstillinger * / 'mongo' => array ('host' => '127.0.0.1', 'brukernavn' => ", 'passord' =>", 'database' => 'laravel' 'samling' => 'laravel_session_collection')
Mens vi er på denne filen, bør vi også oppdatere sjåfør
konfigurasjon på toppen:
'driver' => 'mongo'
Nå, prøv å få tilgang til hovedsiden (vanligvis, localhost / somefolder / offentlig
). Hvis denne siden laster uten å vise Hoppsann
siden, så gratulerer, vi har opprettet en helt ny sesjonsdriver! Test det ved å sette inn noen dummy data på økten, via Session :: satt ()
og deretter ekko det tilbake via Session :: får ()
.
Laravel Auth-komponenten håndterer brukerautentisering for rammen, samt passordhåndtering. Hva Laravel-komponenten har gjort her, er å skape en abstrakt tolkning av det typiske brukerhåndteringssystemet som kan brukes i de fleste webapplikasjoner, noe som igjen hjelper programmereren å enkelt implementere et innloggingssystem. Som Session-komponenten benytter den også Laravel Manager. For tiden har Auth-komponenten drivere for:
veltalende
- Dette gjør bruk av Laravels innebygde ORM kalt Veltalende
. Den benytter også pre-laget User.php
klasse inne i modeller
mappe.database
- Dette bruker hvilken databaseforbindelse som er konfigurert som standard. Det gjør bruk av a GenericUser
klassen for å få tilgang til brukerdataene.Siden dette følger samme implementering som Økt
komponent, tjenesteleverandøren er svært lik det vi har sett på toppen:
/ ** * Registrer tjenesteleverandøren. * * @return void * / public function register () $ this-> app-> bindShare ('auth', funksjon ($ app) // Når autentiseringstjenesten faktisk er blitt forespurt av utvikleren // en variabel i applikasjonen som indikerer slik. Dette hjelper oss / / vet at vi må sette inn noen kø i informasjonskapsler senere. $ app ['auth.loaded'] = true; returner ny AuthManager ($ app);) ;
Her kan vi se at det i utgangspunktet skaper en AuthManager
klasse som bryter rundt hvilken som helst sjåfør vi bruker, samt å fungere som en fabrikk for den. Inne i AuthManager
, det skaper igjen den riktige driveren, innpakket rundt a Vakt
klassen, som fungerer på samme måte som butikk
klasse fra Økt
.
Som før, la oss begynne med å lage en MongoUserProvider
:
config = $ config; $ connection_string = 'mongodb: //'; hvis ! tom ($ this-> config ['brukernavn']) &&! tomt ($ this-> config ['passord'])) $ connection_string. = "$ this-> config ['bruker'] : $ dette-> konfig [ 'passord'] @ "; $ connection_string. = "$ this-> config ['host']"; $ this-> connection = new Mongo ($ connection_string); $ this-> collection = $ this-> connection-> selectCollection ($ this-> config ['database'], $ this-> config ['samling']); / ** * Hent en bruker etter deres unike identifikator. * * @param blandet $ identifikator * @return \ Illuminate \ Auth \ UserInterface | null * / offentlig funksjon retrieveById ($ identifier) $ user_data = $ this-> collection-> findOne (array ('_id' => $ identifiserer, )); hvis (! er_null ($ user_data)) returner ny GenericUser ((array) $ user_data); / ** * Hent en bruker av de oppgitte legitimasjonene. * * @param array $ credentials * @return \ Illuminate \ Auth \ UserInterface | null * / offentlig funksjon retrieveByCredentials (array $ credentials) // Forsøk å se etter brukeren først uansett passord // Vi gjør det i validateCredentials metode hvis (isset ($ credentials ['passord'])) unset ($ credentials ['passord']); $ user_data = $ this-> collection-> findOne ($ credentials); hvis (! er_null ($ user_data)) returner ny GenericUser ((array) $ user_data); / ** * Bekreft en bruker mot de oppgitte legitimasjonene. * * @param \ Illuminate \ Auth \ UserInterface $ bruker * @param array $ credentials * @return bool * / offentlig funksjon validateCredentials (UserInterface $ bruker, array $ credentials) if (! isset ($ credentials ['passord']) ) return false; returnere ($ credentials ['passord'] === $ bruker-> getAuthPassword ());
Det er viktig å merke seg at jeg ikke sjekker mot et hashed-passord, dette ble gjort for enkelhets skyld, for å gjøre det lettere for oss å lage dummy-data og teste dette senere. I produksjonskode må du passe på å hash passordet. Sjekk ut Belyse \ Auth \ DatabaseUserProvider
klasse for et godt eksempel på hvordan du gjør dette.
Etterpå må vi registrere vår tilpassede driver tilbakeringing på AuthManager
. For å gjøre det, må vi oppdatere tjenesteleverandøren registrere
metode:
/ ** * Registrer tjenesteleverandøren. * * @return void * / public function register () $ this-> app-> bindShare ('auth', funksjon ($ app) // Når autentiseringstjenesten faktisk er blitt forespurt av utvikleren // en variabel i applikasjonen som indikerer slik. Dette hjelper oss / / vet at vi må sette inn køer i køen etterpå senere. $ app ['auth.loaded'] = true; $ auth_manager = ny AuthManager ($ app); $ auth_manager-> utvide ('mongo', funksjon ($ app) returner ny MongoUserProvider (array ('host' => $ app ['config'] -> get ('auth.mongo.host'), 'brukernavn' => $ app ['config'] -> get ('auth.mongo.username'), 'passord' => $ app ['config'] -> get ('auth.mongo.password'), 'database' => $ app ['config'] -> få ('auth.mongo.database'), 'samling' => $ app ['config'] -> get ('auth.mongo.collection'))); ); return $ auth_manager;);
Til slutt må vi også oppdatere auth.php
konfigurasjonsfil for å gjøre bruk av Mongo-driveren, samt gi den den rette Mongo-konfigurasjonsverdien:
'driver' => 'mongo', ... / ** * Mongo DB innstillinger * / 'mongo' => array ('host' => '127.0.0.1', 'brukernavn' => ", 'passord' => , 'database' => 'laravel', 'collection' => 'laravel_auth_collection')
Testing dette er litt vanskeligere, for å gjøre det, bruk Mongo DB CLI til å sette inn en ny bruker i samlingen:
mongo> bruk laravel_auth byttet til db laravel_auth> db.laravel_auth_collection.insert (id: 1, email: "[email protected]", passord: "test_password")> db.laravel_auth_collection.find ()> "_id" : ObjectId ("530c609f2caac8c3a8e4814f"), "id" 1, "email": "[email protected]", "passord": "test_password"
Nå, teste det ut ved å prøve en Auth :: validere
metodeanrop:
var_dump (Auth :: validere (array ('email' => '[email protected]', 'passord' => 'test_password'))));
Dette bør dumpe en bool (sann)
. Hvis det gjør det, har vi vellykket opprettet vår egen Auth-driver!
Laravel Cache-komponenten håndterer cachemekanismer for bruk i rammen. Som begge komponentene som vi har diskutert, benytter den også Laravel Manager (merker du et mønster?). Cachekomponenten har drivere for:
APC
memcached
Redis
fil
- en filbasert cache. Data lagres i app / lagring / cache
sti.database
- database-basert cache. Data lagres i rader i databasen. Databaseskjemaet er beskrevet i Laravel-dokumentasjonen.matrise
- data blir "cached" i en matrise. Husk at matrise
hurtigbufferen er ikke vedvarende og ryddes på hver sidebelastning.Siden dette følger samme implementering som begge komponenter som vi har diskutert, kan du trygt anta at tjenesteleverandøren er ganske lik:
/ ** * Registrer tjenesteleverandøren. * * @return void * / public function register () $ this-> app-> bindShare ('cache', funksjon ($ app) returner ny CacheManager ($ app);); $ this-> app-> bindShare ('cache.store', funksjon ($ app) return $ app ['cache'] -> driver ();); $ this-> app-> bindShared ('memcached.connector', funksjon () returner ny MemcachedConnector;); $ Dette-> registerCommands ();
De registrere()
Metoden her lager en CacheManager
, som igjen fungerer som en wrapper og fabrikk for sjåførene. Innenfor sjefen bryter den sjåføren rundt en Oppbevaringssted
klasse, ligner på butikk
og Vakt
klasser.
Opprett MongoStore
, som skal utvide Belyse \ Cache \ StoreInterface
:
config = $ config; $ connection_string = 'mongodb: //'; hvis ! tom ($ this-> config ['brukernavn']) &&! tomt ($ this-> config ['passord'])) $ connection_string. = "$ this-> config ['bruker'] : $ dette-> konfig [ 'passord'] @ "; $ connection_string. = "$ this-> config ['host']"; $ this-> connection = new Mongo ($ connection_string); $ this-> collection = $ this-> connection-> selectCollection ($ this-> config ['database'], $ this-> config ['samling']); / ** * Hent et element fra hurtigbufferen med nøkkel. * * @param string $ key * @return mixed * / offentlig funksjon få ($ key) $ cache_data = $ this-> getObject ($ key); hvis (! $ cache_data) return null; returner unserialize ($ cache_data ['cache_data']); / ** * Returner hele objektet i stedet for bare cache_data * * @param string $ key * @return array | null * / beskyttet funksjon getObject ($ key) $ cache_data = $ this-> collection-> findOne ('key' => $ key,)); hvis (is_null ($ cache_data)) return null; hvis (isset ($ cache_data ['utløper']) && time ()> = $ cache_data ['utløper']) $ this-> glemmer ($ key); return null; returner $ cache_data; / ** * Lagre et element i hurtigbufferen i et gitt antall minutter. * * @param streng $ nøkkel * @param blandet $ verdi * @param int $ minutter * @return void * / offentlig funksjon satt ($ nøkkel, $ verdi, $ minutter) $ utløp = $ this-> utløp ); $ this-> collection-> update (array ('key' => $ nøkkel), array ('$ set' => array ('cache_data' => serialize ($ verdi), 'utløp' => $ utløp, ' ttl '=> ($ minutter * 60))), array (' upsert '=> true,' multiple '=> false)); / ** * Øk verdien av et element i hurtigbufferen. * * @param streng $ nøkkel * @param blandet $ verdi * @return void * * @throws \ LogicException * / offentlig funksjon økning ($ key, $ value = 1) $ cache_data = $ this-> getObject ($ key) ; hvis (! $ cache_data) $ new_data = array ('cache_data' => serialize ($ value), 'utløp' => $ this-> utløp (0), 'ttl' => $ this-> utløp ); andre $ new_data = array ('cache_data' => serialize (unserialize ($ cache_data ['cache_data']) + $ verdi), 'utløp' => $ this-> utløp ((int) ($ cache_data ['ttl '] / 60)),' ttl '=> $ cache_data [' ttl ']); $ this-> collection-> update (array ('key' => $ nøkkel), array ('$ set' => $ new_data), array ('upsert' => true, 'multiple' => false)) ; / ** * Reduser verdien av et element i hurtigbufferen. * * @param streng $ nøkkel * @param blandet $ verdi * @return void * * @throws \ LogicException * / offentlig funksjon reduksjon ($ key, $ value = 1) $ cache_data = $ this-> getObject ($ key) ; hvis (! $ cache_data) $ new_data = array ('cache_data' => serialize ((0 - $ verdi)), 'utløp' => $ this-> utløp (0), 'ttl' => $ this-> utløp (0)); ellers $ new_data = array ('cache_data' => serialize (unserialize ($ cache_data ['cache_data']) - $ verdi), 'utløp' => $ this-> utløp ((int) ($ cache_data ['ttl '] / 60)),' ttl '=> $ cache_data [' ttl ']); $ this-> collection-> update (array ('key' => $ nøkkel), array ('$ set' => $ new_data), array ('upsert' => true, 'multiple' => false)) ; / ** * Lagre et element i hurtigbufferen på ubestemt tid. * * @param streng $ nøkkel * @param blandet $ verdi * @return void * / offentlig funksjon for alltid ($ nøkkel, $ verdi) return $ this-> put ($ key, $ value, 0); / ** * Fjern et element fra hurtigbufferen. * * @param string $ key * @return void * / offentlig funksjon glemme ($ key) $ this-> collection-> remove (array ('key' => $ nøkkel)); / ** * Fjern alle elementene fra hurtigbufferen. * * @return void * / public function flush () $ this-> collection-> remove (); / ** * Få utløptidspunktet basert på de angitte minuttene. * * @param int $ minutes * @return int * / beskyttet funksjon utløp ($ minutter) hvis ($ minutter === 0) returnere 9999999999; returtid () + ($ minutter * 60); / ** * Hent hurtigbuffer-prefikset. * * @return streng * / offentlig funksjon getPrefix () return ";
Vi må også legge til Mongo-tilbakeringingen igjen til sjefen:
/ ** * Registrer tjenesteleverandøren. * * @return void * / offentlig funksjon register () $ this-> app-> bindShare ('cache', funksjon ($ app) $ cache_manager = ny CacheManager ($ app); $ cache_manager-> utvide ('mongo ', funksjon ($ app) return new MongoStore (array (' host '=> $ app [' config '] -> get (' cache.mongo.host '),' brukernavn '=> $ app [' config ' ] -> få ('cache.mongo.username'), 'passord' => $ app ['config'] -> få ('cache.mongo.password'), 'database' => $ app ['config' ] -> få ('cache.mongo.database'), 'samling' => $ app ['config'] -> få ('cache.mongo.collection'));); return $ cache_manager;) ; $ this-> app-> bindShare ('cache.store', funksjon ($ app) return $ app ['cache'] -> driver ();); $ this-> app-> bindShared ('memcached.connector', funksjon () returner ny MemcachedConnector;); $ Dette-> registerCommands ();
Til slutt må vi oppdatere cache.php
config-fil:
'driver' => 'mongo', ... / ** * Mongo DB innstillinger * / 'mongo' => array ('host' => '127.0.0.1', 'brukernavn' => ", 'passord' => , 'database' => 'laravel', 'collection' => 'laravel_cache_collection')
Nå, forsøk å bruke Cache :: sette ()
og Cache :: får ()
metoder. Hvis det gjøres riktig, bør vi kunne bruke MongoDB til å cache dataene!
I denne opplæringen lærte vi om følgende:
Belyse
, som brukes av Laravel-rammeverket.Forhåpentligvis hjelper dette programmerere til å lage sine egne drivere og utvide den nåværende funksjonaliteten til Laravel-rammeverket.