Negli ultimi anni, Laravel è diventato uno dei framework più importanti che gli ingegneri del software utilizzano per costruire le loro applicazioni web. Simile alla popolarità che CodeIgniter ha goduto nel suo periodo di massimo splendore, Laravel è stato lodato per la sua facilità d'uso, la cordialità per i principianti e la sua aderenza agli standard del settore.
Una cosa, tuttavia, che molti programmatori non sfruttano è il sistema basato su componenti di Laravel. Dalla sua conversione a componenti basati su compositori, Laravel 4 è diventato un sistema molto modulare, simile alla verbosità di framework più maturi come Symfony. Questo è chiamato il Illuminare
gruppo di componenti, che a mio parere, non è la struttura vera e propria, ma è una raccolta di librerie che un framework può potenzialmente utilizzare. L'attuale struttura di Laravel è rappresentata dall'applicazione scheletro di Laravel (che si trova sul laravel / laravel
Repository GitHub) che utilizza questi componenti per creare un'applicazione web.
In questo tutorial, ci immergeremo in un gruppo di questi componenti, imparando come funzionano, come vengono utilizzati dal framework e come possiamo estendere le loro funzionalità.
Il componente Laravel Session gestisce le sessioni per l'applicazione Web. Fa uso di un sistema basato su driver chiamato Laravel Manager, che funge da factory e wrapper per ogni driver impostato nel file di configurazione. Al momento della stesura, il componente Session ha i driver per:
file
- un driver di sessione basato su file in cui i dati di sessione vengono salvati in un file crittografato.biscotto
- un driver di sessione basato su cookie in cui i dati di sessione sono crittografati nei cookie dell'utente.Banca dati
- i dati di sessione vengono salvati in qualsiasi database configurato per l'applicazione.apc
- i dati della sessione vengono salvati in APC.memcached
- i dati della sessione vengono salvati in Memcached.Redis
- i dati della sessione vengono salvati in Redis.schieramento
- i dati di sessione vengono salvati in un array PHP. Prendi nota del fatto che il driver di sessione dell'array non supporta la persistenza e solitamente viene utilizzato solo nei comandi della console.La maggior parte degli utenti Laravel non si rende conto, ma una grande parte di come funziona Laravel, è all'interno dei suoi fornitori di servizi. Sono essenzialmente file di bootstrap per ciascun componente e sono abbastanza astratti in modo che gli utenti possano eseguire il bootstrap di qualsiasi componente, in qualsiasi modo.
Una spiegazione approssimativa di come funziona è qui sotto:
Registrare
il metodo è chiamato. Questo ci consente di istanziare qualsiasi componente desideriamo. $ This-> App
), che consentirebbe ai provider di servizi di inviare istanze delle classi risolte nel contenitore delle dipendenze.App :: make
.Tornando a Sessioni, diamo una rapida occhiata al SessionServiceProivider
:
/ ** * Registrare l'istanza del gestore di sessione. * * @return void * / protected function registerSessionManager () $ this-> app-> bindShared ('session', function ($ app) return new SessionManager ($ app);); / ** * Registrare l'istanza del driver di sessione. * * @return void * / protected function registerSessionDriver () $ this-> app-> bindShared ('session.store', function ($ app) // Innanzitutto, creeremo il session manager che è responsabile per / / creazione dei vari driver di sessione quando sono necessari dall'istanza dell'applicazione // e li risolverà su base lazy load. $ manager = $ app ['session']; return $ manager-> driver ();) ;
Questi due metodi sono chiamati da Registrare()
funzione. Il primo, registerSessionManager ()
, è chiamato a registrare inizialmente il SessionManager
. Questa classe estende il Manager
di cui ho parlato sopra. Il secondo, registerSessionDriver ()
registra un gestore di sessione per il gestore, in base a ciò che abbiamo configurato. Questo alla fine chiama questo metodo nel Illuminare \ Support \ Manager
classe:
/ ** * Crea una nuova istanza del driver. * * @param string $ driver * @return mixed * * @throws \ InvalidArgumentException * / funzione protetta createDriver ($ driver) $ method = 'create'.ucfirst ($ driver).' Driver '; // Verificheremo se esiste un metodo creatore per il driver specificato. In caso contrario, // controllerà la creazione di un driver personalizzato, che consente agli sviluppatori di creare i driver // utilizzando il proprio creatore di driver personalizzato Closure per crearlo. if (isset ($ this-> customCreators [$ driver])) return $ this-> callCustomCreator ($ driver); elseif (method_exists ($ this, $ method)) return $ this -> $ method (); lancia nuovi \ InvalidArgumentException ("Driver [$ driver] non supportato.");
Da qui, possiamo vedere che in base al nome del driver, dal file di configurazione, viene chiamato un metodo specifico. Quindi, se lo abbiamo configurato per usare il file
gestore di sessioni, chiamerà questo metodo nel SessionManager
classe:
/ ** * Creare un'istanza del driver di sessione del file. * * @return \ Illuminate \ Session \ Store * / protected function createFileDriver () return $ this-> createNativeDriver (); / ** * Creare un'istanza del driver di sessione del file. * * @return \ Illuminate \ Session \ Store * / protected function createNativeDriver () $ path = $ this-> app ['config'] ['session.files']; return $ this-> buildSession (new FileSessionHandler ($ this-> app ['files'], $ path));
La classe del conducente viene quindi iniettata in a Memorizzare
classe, che è responsabile della chiamata ai metodi di sessione effettivi. Questo ci consente di separare effettivamente l'implementazione di SessionHandlerInterface
dal SPL ai driver, il Memorizzare
la classe lo facilita.
Creiamo il nostro Session Handler, un gestore di sessioni MongoDB. Innanzitutto, dovremo creare un MongoSessionHandler
all'interno di un'istanza del progetto Laravel appena installata. (Prendiamo in prestito pesantemente da 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 * / public function open ($ savePath, $ sessionName) return true; / ** * @inheritDoc * / public function close () return true; / ** * @inheritDoc * / public function read ($ 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' => nuovo MongoBinData ($ data, MongoBinData :: BYTE_ARRAY), 'timestamp' => new MongoDate (),)), array ('upsert' => true, 'multiple' => false)); / ** * @inheritDoc * / public function destroy ($ sessionId) $ this- > collection-> remove (array ('_id' => $ sessionId)); restituisce true; / ** * @inheritDoc * / public function gc ($ lifetime) $ time = new MongoDate (time () - $ lifetime); $ this-> collection-> remove (array ('timestamp' => array ('$ lt' => $ time),)); return true;
Dovresti salvare questo nel vendor / laravel / quadro / src / Illuminate / Session
cartella. Per gli scopi di questo progetto, lo inseriremo qui, ma idealmente questo file dovrebbe trovarsi all'interno del proprio spazio dei nomi della libreria.
Quindi, dobbiamo assicurarci che il Manager
la classe può chiamare questo driver. Possiamo farlo utilizzando il Gestione :: estendere
metodo. Aperto vendor / laravel / quadro / src / Illuminate / Session / SessionServiceProvider.php
e aggiungi il seguente codice. Idealmente, dovremmo estendere il fornitore di servizi, ma questo non rientra nell'ambito di questo tutorial.
/ ** * Imposta la richiamata di Mongo Driver * * @return void * / public function setupMongoDriver () $ manager = $ this-> app ['session']; $ manager-> extend ('mongo', function ($ app) restituisce nuovo MongoSessionHandler (array ('host' => $ app ['config'] -> get ('session.mongo.host'), 'username' => $ 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'))); );
Assicurati di aggiornare il Registrare()
metodo per chiamare questo metodo:
/ ** * Registrare il fornitore di servizi. * * @return void * / public function register () $ this-> setupDefaultDriver (); $ This-> registerSessionManager (); $ This-> setupMongoDriver (); $ This-> registerSessionDriver ();
Successivamente, è necessario definire la configurazione di Mongo DB. Aperto app / config / session.php
e definire le seguenti impostazioni di configurazione:
/ ** * Impostazioni Mongo DB * / 'mongo' => array ('host' => '127.0.0.1', 'username' => ", 'password' =>", 'database' => 'laravel', 'collection' => 'laravel_session_collection')
Mentre siamo su questo file, dovremmo anche aggiornare il file autista
configurazione in alto:
'driver' => 'mongo'
Ora, prova e accedi alla pagina principale (di solito, localhost / somefolder / pubblico
). Se questa pagina viene caricata senza mostrare il WHOOPS
pagina, quindi congratulazioni, abbiamo creato con successo un nuovo driver di sessione! Provalo impostando alcuni dati fittizi sulla sessione, via Session :: set ()
e poi riecheggiando via Session :: get ()
.
Il componente Laravel Auth gestisce l'autenticazione dell'utente per il framework, nonché la gestione delle password. Ciò che il componente Laravel ha fatto qui è quello di creare un'interpretazione astratta del tipico sistema di gestione degli utenti che è utilizzabile nella maggior parte delle applicazioni web, il che a sua volta aiuta il programmatore a implementare facilmente un sistema di login. Come il componente Session, fa anche uso di Laravel Manager. Attualmente, il componente Auth ha i driver per:
eloquente
- questo fa uso dell'ORM integrato di Laravel chiamato Eloquente
. Utilizza anche il pre-made user.php
classe dentro il Modelli
cartella.Banca dati
- questo utilizza per impostazione predefinita qualsiasi connessione al database configurata. Fa uso di a GenericUser
classe per l'accesso ai dati dell'utente.Dal momento che questo segue la stessa implementazione del Sessione
componente, il fornitore di servizi è molto simile a quello che abbiamo visto in cima:
/ ** * Registrare il fornitore di servizi. * * @return void * / public function register () $ this-> app-> bindShared ('auth', function ($ app) // Una volta che il servizio di autenticazione è stato effettivamente richiesto dallo sviluppatore // imposteremo una variabile nell'applicazione che indica tale. Questo ci aiuta // sapere che abbiamo bisogno di impostare eventuali cookie in coda nell'evento after successivo. $ app ['auth.loaded'] = true; return new AuthManager ($ app);) ;
Qui, possiamo vedere che fondamentalmente crea un AuthManager
classe che avvolge qualsiasi driver che stiamo usando, oltre a fungere da fabbrica per questo. Dentro il AuthManager
, crea nuovamente il driver appropriato, avvolto attorno a Guardia
classe, che agisce allo stesso modo del Memorizzare
classe da Sessione
.
Come prima, iniziamo creando un 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']); / ** * Recupera un utente tramite il suo identificativo univoco. * * @param $ identificativo misto * @return \ Illuminate \ Auth \ UserInterface | null * / public function retrieveById ($ identificatore) $ user_data = $ this-> collection-> findOne (array ('_id' => $ identificatore, )); if (! is_null ($ user_data)) return new GenericUser ((array) $ user_data); / ** * Recupera un utente in base alle credenziali specificate. * * @param array $ credenziali * @return \ Illuminate \ Auth \ UserInterface | null * / funzione pubblica retrieveByCredentials (array $ credenziali) // Tentativo di cercare l'utente per primo indipendentemente dalla password // Lo faremo nel metodo validateCredentials if (isset ($ credentials ['password'])) unset ($ credentials ['password']); $ user_data = $ this-> collection-> findOne ($ credentials); if (! is_null ($ user_data)) return new GenericUser ((array) $ user_data); / ** * Convalida un utente rispetto alle credenziali specificate. * * @param \ Illuminate \ Auth \ UserInterface $ utente * @param array $ credenziali * @return bool * / public function validateCredentials (UserInterface $ user, array $ credentials) if (! isset ($ credentials ['password']) ) return false; return ($ credentials ['password'] === $ user-> getAuthPassword ());
È importante tenere presente che non sto controllando una password con hash, questo è stato fatto per semplicità per rendere più semplice da parte nostra la creazione di dati fittizi e testarli successivamente. Nel codice di produzione, è necessario assicurarsi di hash la password. Guarda il Illuminare \ Auth \ DatabaseUserProvider
classe per un grande esempio su come farlo.
Successivamente, dobbiamo registrare la nostra callback del driver personalizzato su AuthManager
. Per fare ciò, dobbiamo aggiornare il fornitore di servizi Registrare
metodo:
/ ** * Registrare il fornitore di servizi. * * @return void * / public function register () $ this-> app-> bindShared ('auth', function ($ app) // Una volta che il servizio di autenticazione è stato effettivamente richiesto dallo sviluppatore // imposteremo una variabile nell'applicazione che indica tale. Questo ci aiuta // sapere che è necessario impostare eventuali cookie in coda nell'evento after successivo. $ app ['auth.loaded'] = true; $ auth_manager = new AuthManager ($ app); $ auth_manager-> extend ('mongo', function ($ app) restituisce nuovo MongoUserProvider (array ('host' => $ app ['config'] -> get ('auth.mongo.host'), 'username' => $ app ['config'] -> get ('auth.mongo.username'), 'password' => $ app ['config'] -> get ('auth.mongo.password'), 'database' => $ app ['config'] -> get ('auth.mongo.database'), 'collection' => $ app ['config'] -> get ('auth.mongo.collection'))); ); return $ auth_manager;);
Infine, abbiamo anche bisogno di aggiornare il auth.php
file di configurazione per utilizzare il driver Mongo, oltre a fornire i valori di configurazione Mongo corretti:
'driver' => 'mongo', ... / ** * Impostazioni Mongo DB * / 'mongo' => array ('host' => '127.0.0.1', 'username' => ", 'password' =>" , 'database' => 'laravel', 'collection' => 'laravel_auth_collection')
Provare questo è un po 'più complicato, per farlo, usa la CLI di Mongo DB per inserire un nuovo utente nella raccolta:
mongo> usa laravel_auth passato a db laravel_auth> db.laravel_auth_collection.insert (id: 1, email: "[email protected]", password: "test_password")> db.laravel_auth_collection.find ()> "_id" : ObjectId ("530c609f2caac8c3a8e4814f"), "id" 1, "email": "[email protected]", "password": "test_password"
Ora provalo provando un Auth :: validate
chiamata al metodo:
var_dump (Auth :: validate (array ('email' => '[email protected]', 'password' => 'test_password')));
Questo dovrebbe scaricare a bool (true)
. Se lo fa, allora abbiamo creato con successo il nostro driver Auth!
Il componente Laravel Cache gestisce i meccanismi di memorizzazione nella cache per l'utilizzo nel framework. Come entrambi i componenti che abbiamo discusso, fa anche uso di Laravel Manager (stai notando uno schema?). Il componente Cache ha i driver per:
apc
memcached
Redis
file
- una cache basata su file. I dati vengono salvati nel app / stoccaggio / cache
sentiero.Banca dati
- cache basata su database. I dati vengono salvati in righe nel database. Lo schema del database è descritto nella documentazione di Laravel.schieramento
- i dati sono "memorizzati nella cache" in una matrice. Tieni presente che il schieramento
la cache non è persistente e viene cancellata ad ogni caricamento della pagina.Poiché ciò segue la stessa implementazione di entrambi i componenti discussi, è possibile presumere che il fornitore di servizi sia abbastanza simile:
/ ** * Registrare il fornitore di servizi. * * @return void * / public function register () $ this-> app-> bindShared ('cache', function ($ app) return new CacheManager ($ app);); $ this-> app-> bindShared ('cache.store', function ($ app) return $ app ['cache'] -> driver ();); $ this-> app-> bindShared ('memcached.connector', function () return new MemcachedConnector;); $ This-> registerCommands ();
Il Registrare()
il metodo qui crea a CacheManager
, che funge ancora da wrapper e factory per i driver. All'interno del manager, avvolge il driver attorno a deposito
classe, simile al Memorizzare
e Guardia
classi.
Crea il MongoStore
, che dovrebbe estendere il Illuminare \ 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']); / ** * Recupera un elemento dalla cache per chiave. * * @param stringa $ chiave * @return mista * / funzione pubblica get (chiave $) $ cache_data = $ this-> getObject (chiave $); if (! $ cache_data) return null; return unserialize ($ cache_data ['cache_data']); / ** * Restituisce l'intero oggetto invece del solo cache_data * * @param stringa $ chiave * @return array | null * / funzione protetta getObject (chiave $) $ cache_data = $ this-> collection-> findOne (array ('chiave' => $ chiave,)); if (is_null ($ cache_data)) return null; if (isset ($ cache_data ['expire']) && time ()> = $ cache_data ['expire']) $ this-> forget ($ key); return null; restituisce $ cache_data; / ** * Archivia un oggetto nella cache per un dato numero di minuti. * * @param stringa $ chiave * @param mista $ valore * @param int $ minuti * @return void * / funzione pubblica put ($ chiave, $ valore, $ minuti) $ scadenza = $ this-> scadenza ($ minuti ); $ this-> collection-> update (array ('chiave' => $ chiave), array ('$ set' => array ('cache_data' => serialize ($ value), 'expiry' => $ expiry, ' ttl '=> ($ minutes * 60))), array (' upsert '=> true,' multiple '=> false)); / ** * Incrementa il valore di un elemento nella cache. * * @param stringa $ chiave * @param mista $ valore * @return void * * @throws \ LogicException * / incremento funzione pubblica ($ chiave, $ valore = 1) $ cache_data = $ this-> getObject (chiave $) ; 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 ('chiave' => $ chiave), array ('$ set' => $ new_data), array ('upsert' => true, 'multiple' => false)) ; / ** * Decrementa il valore di un elemento nella cache. * * @param stringa $ chiave * @param mista $ valore * @return void * * @throws \ LogicException * / decremento della funzione pubblica ($ chiave, $ valore = 1) $ cache_data = $ this-> getObject (chiave $) ; if (! $ cache_data) $ new_data = array ('cache_data' => serialize ((0 - $ valore)), 'expiry' => $ this-> expiration (0), 'ttl' => $ this-> scadenza (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 ('chiave' => $ chiave), array ('$ set' => $ new_data), array ('upsert' => true, 'multiple' => false)) ; / ** * Archivia un oggetto nella cache per un tempo indefinito. * * @param string $ key * @param mixed $ value * @return void * / public function forever ($ key, $ value) return $ this-> put ($ key, $ value, 0); / ** * Rimuovi un elemento dalla cache. * * @param string $ key * @return void * / public function forget ($ key) $ this-> collection-> remove (array ('key' => $ key)); / ** * Rimuovi tutti gli elementi dalla cache. * * @return void * / public function flush () $ this-> collection-> remove (); / ** * Ottieni il tempo di scadenza in base ai minuti indicati. * * @param int $ minuti * @return int * / scadenza funzione protetta ($ minuti) if ($ minuti === 0) restituisce 9999999999; tempo di ritorno () + ($ minuti * 60); / ** * Ottieni il prefisso della chiave di cache. * * @return string * / public function getPrefix () return ";
Dovremo inoltre aggiungere nuovamente la richiamata Mongo al gestore:
/ ** * Registrare il fornitore di servizi. * * @return void * / public function register () $ this-> app-> bindShared ('cache', funzione ($ app) $ cache_manager = nuovo CacheManager ($ app); $ cache_manager-> extend ('mongo ', function ($ app) return new MongoStore (array (' host '=> $ app [' config '] -> get (' cache.mongo.host '),' username '=> $ app [' config '] ] -> get ('cache.mongo.username'), 'password' => $ app ['config'] -> get ('cache.mongo.password'), 'database' => $ app ['config'] ] -> get ('cache.mongo.database'), 'collection' => $ app ['config'] -> get ('cache.mongo.collection')));); restituisce $ cache_manager;) ; $ this-> app-> bindShared ('cache.store', function ($ app) return $ app ['cache'] -> driver ();); $ this-> app-> bindShared ('memcached.connector', function () return new MemcachedConnector;); $ This-> registerCommands ();
Infine, dovremo aggiornare il cache.php
file di configurazione:
'driver' => 'mongo', ... / ** * Impostazioni Mongo DB * / 'mongo' => array ('host' => '127.0.0.1', 'username' => ", 'password' =>" , 'database' => 'laravel', 'collection' => 'laravel_cache_collection')
Ora, tenta di usare il Cache :: put ()
e Cache :: get ()
metodi. Se fatto correttamente, dovremmo essere in grado di usare MongoDB per memorizzare i dati!
In questo tutorial, abbiamo appreso quanto segue:
Illuminare
, che viene utilizzato dal framework di Laravel.Speriamo che questo aiuti i programmatori a creare i propri driver e ad estendere le funzionalità attuali del framework Laravel.