In de afgelopen jaren is Laravel een van de meest prominente frameworks geworden die software engineers gebruiken voor het bouwen van hun webapplicaties. Vergelijkbaar met de populariteit die CodeIgniter genoot tijdens zijn hoogtijdagen, werd Laravel geprezen om zijn gebruiksgemak, vriendelijkheid voor beginners en de naleving van industriestandaarden.
Een ding is echter dat niet veel programmeurs profiteren van Laravel's op componenten gebaseerde systeem. Sinds de conversie naar door componisten aangestuurde componenten is Laravel 4 een zeer modulair systeem geworden, vergelijkbaar met de breedsprakigheid van meer volwassen frameworks zoals Symfony. Dit wordt het Verlichten
een groep componenten, die naar mijn mening niet het eigenlijke raamwerk zelf is, maar een verzameling van bibliotheken die een raamwerk mogelijk kan gebruiken. Het feitelijke kader van Laravel wordt weergegeven door de Laravel-skeletentoepassing (te vinden op de laravel / laravel
GitHub-repository) die gebruikmaakt van deze componenten om een webtoepassing te bouwen.
In deze tutorial duiken we in een groep van deze componenten, leren hoe ze werken, hoe ze door het framework worden gebruikt en hoe we hun functionaliteit kunnen uitbreiden.
De Laravel Session-component verwerkt sessies voor de webtoepassing. Het maakt gebruik van een op stuurprogramma's gebaseerd systeem, de Laravel Manager, die fungeert als zowel een fabriek als een wrapper voor welk stuurprogramma dan ook in het configuratiebestand wordt ingesteld. Vanaf dit schrijven heeft de Session-component stuurprogramma's voor:
het dossier
- een op bestanden gebaseerd sessiestuurprogramma waarin sessiegegevens worden opgeslagen in een gecodeerd bestand.koekje
- een op cookies gebaseerd sessiestuurprogramma waarbij sessiegegevens worden gecodeerd in de cookies van de gebruiker.databank
- sessiegegevens worden opgeslagen in elke database die voor de toepassing is geconfigureerd.apc
- sessiegegevens worden opgeslagen in APC.memcached
- sessiegegevens worden opgeslagen in Memcached.redis
- sessiegegevens worden opgeslagen in Redis.rangschikking
- sessiegegevens worden opgeslagen in een PHP-array. Houd er rekening mee dat het array-sessiestuurprogramma persistentie niet ondersteunt en meestal alleen wordt gebruikt in console-opdrachten.De meeste Laravel-gebruikers realiseren zich niet, maar een groot deel van de manier waarop Laravel werkt, is bij haar serviceproviders. Het zijn in wezen bootstrap-bestanden voor elk onderdeel en ze zijn voldoende geabstraheerd zodat gebruikers op welke manier dan ook componenten kunnen booten.
Een ruwe uitleg van hoe dit werkt, is hieronder:
registreren
methode wordt genoemd. Dit stelt ons in staat om welke component we willen te instantiëren. $ This-> app
), waarmee serviceproviders exemplaren van de opgeloste klassen in de afhankelijkheidscontainer kunnen pushen.App :: make
.Terug naar Sessions, laten we de SessionServiceProivider
:
/ ** * Registreer de sessiebeheerderinstantie. * * @return void * / protected function registerSessionManager () $ this-> app-> bindShared ('session', function ($ app) retourneer nieuwe SessionManager ($ app);); / ** * Registreer het sessiestuurprogramma-exemplaar. * * @return void * / protected function registerSessionDriver () $ this-> app-> bindShared ('session.store', functie ($ app) // Eerst maken we de sessiemanager die verantwoordelijk is voor de / / creatie van de verschillende sessiestuurprogramma's wanneer deze nodig zijn door het // application-exemplaar en lost ze op met een lazy load-basis. $ manager = $ app ['session']; return $ manager-> driver ();) ;
Deze twee methoden worden aangeroepen door de registreren()
functie. De eerste, registerSessionManager ()
, wordt aangeroepen om het register in eerste instantie te registreren SessionManager
. Deze klasse breidt het Manager
die ik bovenaan heb genoemd. De tweede, registerSessionDriver ()
registreert een sessie-afhandelaar voor de manager, op basis van wat we hebben geconfigureerd. Dit noemt deze methode uiteindelijk in de Verlichten \ Support \ Manager
klasse:
/ ** * Maak een nieuw stuurprogramma-exemplaar. * * @param string $ driver * @return mixed * * @throws \ InvalidArgumentException * / beschermde functie createDriver ($ driver) $ method = 'create'.ucfirst ($ driver).' Driver '; // We zullen controleren om te zien of er een maker-methode bestaat voor de betreffende driver. Als dat niet het geval is, zullen we controleren of er een aangepaste maker voor het stuurprogramma is, waarmee ontwikkelaars // drivers kunnen maken met hun eigen aangepaste driver creator Closure om het te maken. if (isset ($ this-> customCreators [$ driver])) return $ this-> callCustomCreator ($ driver); elseif (method_exists ($ this, $ method)) return $ this -> $ method (); gooi new \ InvalidArgumentException ("Driver [$ driver] niet ondersteund.");
Vanaf hier kunnen we zien dat op basis van de naam van het stuurprogramma, uit het configuratiebestand, een specifieke methode wordt genoemd. Dus, als we het hebben geconfigureerd om het te gebruiken het dossier
sessie handler, het zal deze methode in de SessionManager
klasse:
/ ** * Maak een instantie van het stuurprogramma voor de bestandssessie. * * @return \ Illuminate \ Session \ Store * / protected function createFileDriver () return $ this-> createNativeDriver (); / ** * Maak een instantie van het bestandssessie-stuurprogramma. * * @return \ Illuminate \ Session \ Store * / beschermde functie createNativeDriver () $ path = $ this-> app ['config'] ['session.files']; return $ this-> buildSession (nieuwe FileSessionHandler ($ this-> app ['files'], $ path));
De stuurprogrammaklasse wordt vervolgens geïnjecteerd in een Op te slaan
klasse, die verantwoordelijk is voor het aanroepen van de eigenlijke sessiemethoden. Hiermee kunnen we de implementatie van de. Daadwerkelijk scheiden SessionHandlerInterface
van de SPL in de drivers, de Op te slaan
klasse faciliteert het.
Laten we onze eigen Session Handler maken, een MongoDB Session-handler. Allereerst moeten we een maken MongoSessionHandler
in een nieuw geïnstalleerde Laravel-projectinstantie. (We zullen zwaar lenen van Symfony \ Component \ HttpFoundation \ Session \ Storage \ Handler \ MongoDbSessionHandler
) .:
config = $ config; $ connection_string = 'mongodb: //'; if (! empty ($ this-> config ['username']) &&! empty ($ this-> config ['password'])) $ connection_string. = "$ this-> config ['user'] : $ this-> config [ 'password'] @ "; $ connection_string. = "$ this-> config ['host']"; $ this-> connection = new Mongo ($ connection_string); $ this-> collection = $ this-> connection-> selectCollection ($ this-> config ['database'], $ this-> config ['collection']); / ** * @inheritDoc * / openbare functie open ($ savePath, $ sessionName) return true; / ** * @inheritDoc * / openbare functie close () return true; / ** * @inheritDoc * / openbare functie lezen ($ sessionId) $ session_data = $ this-> collection-> findOne (array ('_id' => $ sessionId,)); if (is_null ($ session_data)) return "; else return $ session_data ['session_data'] -> bin; / ** * @inheritDoc * / public function write ($ sessionId, $ data) $ this-> collection-> update (array ('_id' => $ sessionId), array ('$ set' => array ('session_data' => nieuwe MongoBinData ($ data, MongoBinData :: BYTE_ARRAY), 'timestamp' => nieuwe MongoDate (),)), array ('upsert' => true, 'multiple' => false)); / ** * @inheritDoc * / public function destroy ($ sessionId) $ this- > collection-> remove (array ('_id' => $ sessionId)); return true; / ** * @inheritDoc * / public function gc ($ lifetime) $ time = new MongoDate (time () - $ lifetime); $ this-> collection-> remove (array ('timestamp' => array ('$ lt' => $ time),)); return true;
Bewaar dit in de verkoper / laravel / framework / src / Illuminate / sessie
map. Voor de doeleinden van dit project plaatsen we het hier, maar idealiter zou dit bestand zich binnen zijn eigen bibliotheeknaamruimte moeten bevinden.
Vervolgens moeten we ervoor zorgen dat de Manager
klasse kan dit stuurprogramma noemen. We kunnen dit doen door gebruik te maken van de Manager :: verlengen
methode. Open verkoper / laravel / framework / src / Illuminate / sessie / SessionServiceProvider.php
en voeg de volgende code toe. Idealiter zouden we de serviceprovider moeten uitbreiden, maar dat valt buiten het bestek van deze zelfstudie.
/ ** * De call-back voor Mongo Driver instellen * * @return void * / public function setupMongoDriver () $ manager = $ this-> app ['session']; $ manager-> extend ('mongo', function ($ app) retourneer nieuwe MongoSessionHandler (array ('host' => $ app ['config'] -> get ('session.mongo.host'), 'gebruikersnaam' => $ app ['config'] -> get ('session.mongo.username'), 'password' => $ app ['config'] -> get ('session.mongo.password'), 'database' => $ app ['config'] -> get ('session.mongo.database'), 'collection' => $ app ['config'] -> get ('session.mongo.collection'))); );
Zorg ervoor dat u de update uitvoert registreren()
methode om deze methode aan te roepen:
/ ** * Registreer de serviceprovider. * * @return void * / public function register () $ this-> setupDefaultDriver (); $ This-> registerSessionManager (); $ This-> setupMongoDriver (); $ This-> registerSessionDriver ();
Vervolgens moeten we de Mongo DB-configuratie definiëren. Open app / config / session.php
en definieer de volgende configuratie-instellingen:
/ ** * Mongo DB-instellingen * / 'mongo' => array ('host' => '127.0.0.1', 'gebruikersnaam' => ", 'wachtwoord' =>", 'database' => 'laravel', 'verzameling' => 'laravel_session_collection')
Terwijl we dit bestand gebruiken, moeten we ook het bestuurder
configuratie bovenaan:
'stuurprogramma' => 'mongo'
Probeer nu de hoofdpagina te openen (meestal, localhost / Bepaalde_map / public
). Als deze pagina wordt geladen zonder de WHOOPS
pagina, dan gefeliciteerd, we hebben met succes een gloednieuwe sessie-driver gemaakt! Test het uit door enkele dummy-gegevens in te stellen voor de sessie, via Session :: set ()
en dan weer terug via echo Session :: te krijgen ()
.
De Laravel Auth-component verwerkt gebruikersverificatie voor het framework, evenals wachtwoordbeheer. Wat de Laravel-component hier heeft gedaan, is het creëren van een abstracte interpretatie van het typische gebruikersbeheersysteem dat in de meeste webtoepassingen kan worden gebruikt, waardoor de programmeur op zijn beurt eenvoudig een inlogsysteem kan implementeren. Net als de Session-component maakt het ook gebruik van de Laravel-manager. Momenteel heeft de Auth-component stuurprogramma's voor:
welsprekend
- dit maakt gebruik van Laravel's ingebouwde ORM genaamd Welsprekend
. Het maakt ook gebruik van de pre-gemaakt User.php
klasse binnen de modellen
map.databank
- deze gebruikt de database-verbinding die standaard is geconfigureerd. Het maakt gebruik van een GenericUser
klasse voor toegang tot de gebruikersgegevens.Aangezien dit dezelfde implementatie volgt als de Sessie
component, lijkt de serviceprovider erg op wat we bovenaan hebben gezien:
/ ** * Registreer de serviceprovider. * * @return void * / public function register () $ this-> app-> bindShared ('auth', function ($ app) // Nadat de authenticatieservice daadwerkelijk is aangevraagd door de ontwikkelaar // zullen we instellen een variabele in de applicatie geeft dit aan. Dit helpt ons / / te weten dat we later in de volgende gebeurtenis eventuele in de wachtrij geplaatste cookies moeten instellen. $ app ['auth.loaded'] = true; retourneer nieuwe AuthManager ($ app);) ;
Hier kunnen we zien dat het in feite een creëert AuthManager
klasse die zich afspeelt rond welke bestuurder we ook gebruiken, en ook fungeert als een fabriek ervoor. Binnen in de AuthManager
, het creëert opnieuw de juiste driver, gewikkeld rond a bewaker
klasse, die op dezelfde manier werkt als de Op te slaan
klas van Sessie
.
Zoals eerder, laten we beginnen met het maken van een MongoUserProvider
:
config = $ config; $ connection_string = 'mongodb: //'; if (! empty ($ this-> config ['username']) &&! empty ($ this-> config ['password'])) $ connection_string. = "$ this-> config ['user'] : $ this-> config [ 'password'] @ "; $ connection_string. = "$ this-> config ['host']"; $ this-> connection = new Mongo ($ connection_string); $ this-> collection = $ this-> connection-> selectCollection ($ this-> config ['database'], $ this-> config ['collection']); / ** * Een gebruiker ophalen op basis van zijn unieke ID. * * @param mixed $ identifier * @return \ Illuminate \ Auth \ UserInterface | null * / public function retrieveById ($ identifier) $ user_data = $ this-> collection-> findOne (array ('_id' => $ identifier, )); if (! is_null ($ user_data)) genereer nieuwe GenericUser ((array) $ user_data); / ** * Een gebruiker ophalen met de opgegeven inloggegevens. * * @param array $ -referenties * @return \ Illuminate \ Auth \ UserInterface | null * / public function retrieveByCredentials (array $ -referenties) // Poging om de gebruiker als eerste te zoeken, ongeacht het wachtwoord // We doen dat in de validateCredentials methode if (isset ($ credentials ['password'])) unset ($ credentials ['password']); $ user_data = $ this-> collection-> findOne ($ credentials); if (! is_null ($ user_data)) genereer nieuwe GenericUser ((array) $ user_data); / ** * Valideer een gebruiker tegen de opgegeven inloggegevens. * * @param \ Illuminate \ Auth \ UserInterface $ user * @param array $ credentials * @return bool * / public function validateCredentials (UserInterface $ user, array $ credentials) if (! isset ($ credentials ['password']) ) return false; return ($ credentials ['password'] === $ user-> getAuthPassword ());
Het is belangrijk om hier te noteren dat ik niet kijk tegen een gehasht wachtwoord, dit is gedaan omwille van de eenvoud om het voor ons gemakkelijker te maken dummy data te maken en dit later te testen. In productiecode moet u ervoor zorgen dat u het wachtwoord hasht. Bekijk de Verlichten \ Auth \ DatabaseUserProvider
klas voor een goed voorbeeld hoe dit te doen.
Naderhand moeten we onze aangepaste driver callback registreren op de AuthManager
. Om dit te doen, moeten we de serviceprovider updaten registreren
methode:
/ ** * Registreer de serviceprovider. * * @return void * / public function register () $ this-> app-> bindShared ('auth', function ($ app) // Nadat de authenticatieservice daadwerkelijk is aangevraagd door de ontwikkelaar // zullen we instellen een variabele in de toepassing geeft dit aan. Dit helpt ons / / weten dat we later in de volgende nadering cookies in de wachtrij moeten zetten. $ app ['auth.loaded'] = true; $ auth_manager = nieuwe AuthManager ($ app); $ auth_manager-> extend ('mongo', function ($ app) return new MongoUserProvider (array ('host' => $ app ['config'] -> get ('auth.mongo.host'), 'gebruikersnaam' => $ app ['config'] -> get ('auth.mongo.username'), 'wachtwoord' => $ app ['config'] -> get ('auth.mongo.password'), 'database' => $ app ['config'] -> get ('auth.mongo.database'), 'collection' => $ app ['config'] -> get ('auth.mongo.collection'))); ); return $ auth_manager;);
Ten slotte moeten we ook het auth.php
configuratiebestand om gebruik te maken van de Mongo-driver en om deze de juiste Mongo-configuratiewaarden te geven:
'stuurprogramma' => 'mongo', ... / ** * Mongo DB-instellingen * / 'mongo' => array ('host' => '127.0.0.1', 'gebruikersnaam' => ", 'wachtwoord' =>" , 'database' => 'laravel', 'collection' => 'laravel_auth_collection')
Het testen van dit is een beetje lastiger, om dit te doen, gebruikt u de Mongo DB CLI om een nieuwe gebruiker in de verzameling in te voegen:
mongo> gebruik laravel_auth overgeschakeld naar db laravel_auth> db.laravel_auth_collection.insert (id: 1, email: "[email protected]", wachtwoord: "test_password")> db.laravel_auth_collection.find ()> "_id" : ObjectId ("530c609f2caac8c3a8e4814f"), "id" 1, "email": "[email protected]", "password": "test_password"
Test het nu door een te proberen Auth :: validate
methode aanroep:
var_dump (Auth :: validate (array ('email' => '[email protected]', 'password' => 'test_password')));
Dit zou a moeten dumpen bool (true)
. Als dat het geval is, hebben we met succes onze eigen Auth-stuurprogramma gemaakt!
De Laravel Cache-component verwerkt caching-mechanismen voor gebruik in het kader. Zoals allebei de componenten die we hebben besproken, maakt het ook gebruik van de Laravel Manager (merkt u een patroon op?). De Cache-component heeft stuurprogramma's voor:
apc
memcached
redis
het dossier
- een op bestanden gebaseerde cache. Gegevens worden opgeslagen in de app / opslag / cache
pad.databank
- database-gebaseerde cache. Gegevens worden in rijen opgeslagen in de database. Het databaseschema wordt beschreven in de Laravel-documentatie.rangschikking
- gegevens worden in een array in de cache opgeslagen. Houd er rekening mee dat de rangschikking
cache is niet persistent en wordt bij het laden van elke pagina gewist.Aangezien dit dezelfde implementatie volgt als beide componenten die we hebben besproken, kunt u er gerust van uitgaan dat de serviceprovider redelijk vergelijkbaar is:
/ ** * Registreer de serviceprovider. * * @return void * / public function register () $ this-> app-> bindShared ('cache', function ($ app) retourneer nieuwe CacheManager ($ app);); $ this-> app-> bindShared ('cache.store', functie ($ app) return $ app ['cache'] -> driver ();); $ this-> app-> bindShared ('memcached.connector', function () retourneer nieuwe MemcachedConnector;); $ This-> registerCommands ();
De registreren()
methode maakt hier een CacheManager
, dat werkt weer als een verpakking en een fabriek voor de chauffeurs. Binnen de manager, het wikkelt de bestuurder rond een bewaarplaats
klasse, vergelijkbaar met de Op te slaan
en bewaker
klassen.
Maak het MongoStore
, welke de. moet verlengen Verlichten \ Cache \ StoreInterface
:
config = $ config; $ connection_string = 'mongodb: //'; if (! empty ($ this-> config ['username']) &&! empty ($ this-> config ['password'])) $ connection_string. = "$ this-> config ['user'] : $ this-> config [ 'password'] @ "; $ connection_string. = "$ this-> config ['host']"; $ this-> connection = new Mongo ($ connection_string); $ this-> collection = $ this-> connection-> selectCollection ($ this-> config ['database'], $ this-> config ['collection']); / ** * Een item uit de cache ophalen per sleutel. * * @param string $ key * @return mixed * / public function get ($ key) $ cache_data = $ this-> getObject ($ key); if (! $ cache_data) return null; return unserialize ($ cache_data ['cache_data']); / ** * Retourneer het hele object in plaats van alleen de cache_data * * @param string $ key * @return array | null * / beschermde functie getObject ($ key) $ cache_data = $ this-> collection-> findOne (array ('toets' => $ -toets,)); if (is_null ($ cache_data)) return null; if (isset ($ cache_data ['expire']) && time ()> = $ cache_data ['expire']) $ this-> forget ($ key); return null; return $ cache_data; / ** * Bewaar een item in de cache voor een bepaald aantal minuten. * * @param string $ key * @param mixed $ value * @param int $ minutes * @return void * / public function put ($ key, $ value, $ minutes) $ expiry = $ this-> expiration ($ minutes ); $ this-> collection-> update (array ('key' => $ key), array ('$ set' => array ('cache_data' => serialize ($ value), 'expiry' => $ expiry, ' ttl '=> ($ minutes * 60))), array (' upsert '=> true,' multiple '=> false)); / ** * Verhoog de waarde van een item in de cache. * * @param string $ key * @param mixed $ value * @return void * * @throws \ LogicException * / public function increment ($ key, $ value = 1) $ cache_data = $ this-> getObject ($ key) ; if (! $ cache_data) $ new_data = array ('cache_data' => serialize ($ value), 'expiry' => $ this-> expiration (0), 'ttl' => $ this-> expiration (0) ); else $ new_data = array ('cache_data' => serialize (unserialize ($ cache_data ['cache_data']) + $ value), 'expiry' => $ this-> expiration ((int) ($ cache_data ['ttl '] / 60)),' ttl '=> $ cache_data [' ttl ']); $ this-> collection-> update (array ('key' => $ key), array ('$ set' => $ new_data), array ('upsert' => true, 'multiple' => false)) ; / ** * Verlaag de waarde van een item in de cache. * * @param string $ key * @param mixed $ value * @return void * * @throws \ LogicException * / public function decrement ($ key, $ value = 1) $ cache_data = $ this-> getObject ($ key) ; if (! $ cache_data) $ new_data = array ('cache_data' => serialize ((0 - $ waarde)), 'expiry' => $ this-> expiration (0), 'ttl' => $ this-> verloop (0)); else $ new_data = array ('cache_data' => serialize (unserialize ($ cache_data ['cache_data']) - $ value), 'expiry' => $ this-> expiration ((int) ($ cache_data ['ttl '] / 60)),' ttl '=> $ cache_data [' ttl ']); $ this-> collection-> update (array ('key' => $ key), array ('$ set' => $ new_data), array ('upsert' => true, 'multiple' => false)) ; / ** * Bewaar een item voor onbepaalde tijd in de cache. * * @param string $ key * @param mixed $ value * @return void * / public function forever ($ key, $ value) return $ this-> put ($ key, $ value, 0); / ** * Een item uit de cache verwijderen. * * @param string $ key * @return void * / public function forget ($ key) $ this-> collection-> remove (array ('key' => $ key)); / ** * Verwijder alle items uit de cache. * * @return void * / public function flush () $ this-> collection-> remove (); / ** * Haal de vervaltijd op basis van de opgegeven minuten. * * @param int $ minutes * @return int * / protected function expiration ($ minutes) if ($ minutes === 0) return 9999999999; retourtijd () + ($ minuten * 60); / ** * Haal het cachetypevoorvoegsel op. * * @return string * / public function getPrefix () return ";
We moeten ook de Mongo-callback opnieuw toevoegen aan de manager:
/ ** * Registreer de serviceprovider. * * @return void * / public function register () $ this-> app-> bindShared ('cache', functie ($ app) $ cache_manager = nieuwe CacheManager ($ app); $ cache_manager-> extend ('mongo ', functie ($ app) retourneer nieuwe MongoStore (array (' host '=> $ app [' config '] -> get (' cache.mongo.host '),' gebruikersnaam '=> $ app [' config ' ] -> get ('cache.mongo.username'), 'wachtwoord' => $ app ['config'] -> get ('cache.mongo.password'), 'database' => $ app ['config' ] -> get ('cache.mongo.database'), 'collection' => $ app ['config'] -> get ('cache.mongo.collection')));); return $ cache_manager;) ; $ this-> app-> bindShared ('cache.store', functie ($ app) return $ app ['cache'] -> driver ();); $ this-> app-> bindShared ('memcached.connector', function () retourneer nieuwe MemcachedConnector;); $ This-> registerCommands ();
Ten slotte moeten we het cache.php
configuratiebestand:
'stuurprogramma' => 'mongo', ... / ** * Mongo DB-instellingen * / 'mongo' => array ('host' => '127.0.0.1', 'gebruikersnaam' => ", 'wachtwoord' =>" , 'database' => 'laravel', 'collection' => 'laravel_cache_collection')
Probeer nu de Cache :: zetten ()
en Cache :: te krijgen ()
methoden. Als het goed wordt gedaan, zouden we MongoDB kunnen gebruiken om de gegevens in de cache op te slaan!
In deze tutorial leerden we over het volgende:
Verlichten
, die wordt gebruikt door het Laravel-raamwerk.Hopelijk helpt dit programmeurs om hun eigen stuurprogramma's te maken en de huidige functionaliteit van het Laravel-framework uit te breiden.