Au cours des dernières années, Laravel est devenu l’un des cadres les plus importants utilisés par les ingénieurs en logiciel pour créer leurs applications Web. Semblable à la popularité de CodeIgniter à son apogée, Laravel a été félicité pour sa facilité d'utilisation, sa convivialité pour les débutants et son respect des normes de l'industrie..
Une chose que peu de programmeurs utilisent, cependant, est le système à base de composants de Laravel. Depuis sa conversion en composants composites, Laravel 4 est devenu un système très modulaire, similaire à la verbosité de frameworks plus matures comme Symfony. Ceci est appelé le Éclairer
groupe de composants qui, à mon avis, ne constitue pas le framework proprement dit, mais une compilation de bibliothèques qu'un framework peut potentiellement utiliser. Le cadre actuel de Laravel est représenté par l’application de squelette de Laravel (trouvée sur le laravel / laravel
Référentiel GitHub) qui utilise ces composants pour construire une application Web.
Dans ce didacticiel, nous allons plonger dans un groupe de ces composants pour apprendre comment ils fonctionnent, comment ils sont utilisés par le framework et comment nous pouvons étendre leurs fonctionnalités..
Le composant Laravel Session gère les sessions de l'application Web. Il utilise un système basé sur des pilotes appelé Laravel Manager, qui agit à la fois comme une fabrique et une encapsuleuse quel que soit le pilote défini dans le fichier de configuration. A ce jour, le composant Session possède des pilotes pour:
fichier
- un pilote de session basé sur un fichier où les données de session sont enregistrées dans un fichier crypté.biscuit
- un pilote de session basé sur les cookies où les données de session sont cryptées dans les cookies de l'utilisateur.base de données
- les données de session sont enregistrées dans la base de données configurée pour l'application.apc
- les données de session sont enregistrées dans APC.memcached
- les données de session sont enregistrées dans Memcached.redis
- les données de session sont enregistrées dans Redis.tableau
- les données de session sont enregistrées dans un tableau PHP. Notez que le pilote de session de groupe ne prend pas en charge la persistance et n’est généralement utilisé que dans les commandes de la console..La plupart des utilisateurs de Laravel ne réalisent pas, mais une grande partie de son fonctionnement réside dans ses fournisseurs de services. Ce sont essentiellement des fichiers d'amorçage pour chaque composant et suffisamment abstraits pour que les utilisateurs puissent amorcer n'importe quel composant, de n'importe quelle manière..
Une explication approximative de la façon dont cela fonctionne est ci-dessous:
registre
méthode est appelée. Cela nous permet d’instancier le composant que nous voulons.. $ this-> app
), ce qui permettrait aux fournisseurs de services d'insérer des instances des classes résolues dans le conteneur de dépendance.App :: make
.Pour revenir aux sessions, jetons un coup d’œil sur la SessionServiceProivider
:
/ ** * Enregistrez l'instance du gestionnaire de session. * * @retour void * / protected function registerSessionManager () $ this-> app-> bindShared ('session', fonction ($ app) retourne le nouveau SessionManager ($ app);); / ** * Enregistrez l'instance du pilote de session. * * @return void * / protected function registerSessionDriver () $ this-> app-> bindShared ('session.store', function ($ app) // Tout d'abord, nous allons créer le gestionnaire de session qui est responsable du / / Création des différents pilotes de session quand ils sont requis par l'instance d'application // et résolvent-les sur une base de chargement paresseux. $ manager = $ app ['session']; return $ manager-> driver ();) ;
Ces deux méthodes sont appelées par le registre()
une fonction. Le premier, registerSessionManager ()
, est appelé à enregistrer initialement le SessionManager
. Cette classe étend la Directeur
que j'ai mentionné en haut. Le deuxième, registerSessionDriver ()
enregistre un gestionnaire de session pour le gestionnaire, en fonction de ce que nous avons configuré. Cela appelle finalement cette méthode dans le Illuminer \ Support \ Manager
classe:
/ ** * Créer une nouvelle instance de pilote. * * @param string $ driver * @return mixed * * @throws \ InvalidArgumentException * / protected function createDriver ($ driver) $ method = 'create'.ucfirst ($ driver).' Driver '; // Nous vérifierons s'il existe une méthode créateur pour le pilote donné. Sinon, nous rechercherons un créateur de pilote personnalisé, ce qui permettra aux développeurs de créer // des pilotes à l'aide de leur propre créateur de pilote personnalisé, Closure, pour le créer. if (isset ($ this-> customCreators [$ driver])) return $ this-> callCustomCreator ($ driver); elseif (method_exists ($ this, $ method)) return $ this -> $ method (); jeter new \ InvalidArgumentException ("Driver [$ driver] non supporté.");
À partir de là, nous pouvons voir que, sur la base du nom du pilote, une méthode spécifique est appelée à partir du fichier de configuration. Donc, si nous l’avons configuré pour utiliser le fichier
gestionnaire de session, il appellera cette méthode dans le SessionManager
classe:
/ ** * Crée une instance du pilote de session de fichier. * * @return \ Illuminate \ Session \ Store * / fonction protégée createFileDriver () return $ this-> createNativeDriver (); / ** * Créer une instance du pilote de session de fichier. * * @return \ Illuminate \ Session \ Store * / Fonction protégée createNativeDriver () $ path = $ this-> app ['config'] ['session.files']; return $ this-> buildSession (new FileSessionHandler ($ this-> app ['files'], $ path));
La classe de pilotes est ensuite injectée dans un le magasin
class, responsable de l'appel des méthodes de session réelles. Cela nous permet en réalité de séparer la mise en œuvre de la SessionHandlerInterface
de la SPL dans les pilotes, le le magasin
la classe le facilite.
Créons notre propre gestionnaire de session, un gestionnaire de session MongoDB. Tout d’abord, nous devrons créer un MongoSessionHandler
dans une instance de projet Laravel nouvellement installée. (Nous emprunterons énormément auprès de Symfony \ Component \ HttpFoundation \ Session \ Storage \ Handler \ MongoDbSessionHandler
):
config = $ config; $ connection_string = 'Mongodb: //'; if (! empty ($ this-> config ['nom d'utilisateur']]) &&! empty ($ this-> config ['mot de passe'])) $ connection_string. = "$ this-> config ['utilisateur'] : $ this-> config ['password'] @ "; $ connection_string. = "$ this-> config ['hôte']"; $ this-> connection = new Mongo ($ connection_string); $ this-> collection = $ this-> connection-> selectCollection ($ this-> config ['database'], $ this-> config ['collection']); / ** * @inheritDoc * / fonction publique open ($ savePath, $ sessionName) return true; / ** * @inheritDoc * / public function close () return true; / ** * @inheritDoc * / fonction publique read ($ sessionId) $ session_data = $ this-> collection-> findOne (array ('_id' => $ sessionId,)); if (is_null ($ session_data)) return "; else return $ data_session ['session_data'] -> bin; / ** * @inheritDoc * / fonction publique write ($ sessionId, $ data) $ this-> collection-> update (array ('_id' => $ sessionId), array ('$ set' => array ('session_data' => new MongoBinData ($ data, MongoBinData :: BYTE_ARRAY), 'horodatage' => new MongoDate (),)), array ('upsert' => true, 'multiple' => false)); / ** * @inheritDoc * / fonction publique destroy ($ sessionId) $ this- > collection-> remove (array ('_id' => $ sessionId)); return true; / ** * @inheritDoc * / fonction publique gc ($ à vie) $ time = new MongoDate (time () - $ à vie); $ this-> collection-> remove (array ('horodatage' => array ('$ lt' => $ time),)); return true;
Vous devriez enregistrer ceci dans le fournisseur / laravel / framework / src / Illuminate / Session
dossier. Pour les besoins de ce projet, nous le mettrons ici, mais idéalement, ce fichier devrait se trouver dans son propre espace de noms de bibliothèque..
Ensuite, nous devons nous assurer que le Directeur
la classe peut appeler ce pilote. Nous pouvons le faire en utilisant le Manager :: extend
méthode. Ouvrir fournisseur / laravel / framework / src / Illuminate / Session / SessionServiceProvider.php
et ajoutez le code suivant. Idéalement, nous devrions élargir le fournisseur de services, mais cela sort du cadre de ce tutoriel..
/ ** * Configurer le rappel du pilote Mongo * * * @retour de retour * / fonction publique setupMongoDriver () $ manager = $ this-> app ['session']; $ manager-> extend ('mongo', fonction ($ app) retourne le nouveau MongoSessionHandler (array ('hôte' => $ app ['config']] -> get ('session.mongo.host'), 'nomutilisateur' => $ app ['config'] -> get ('session.mongo.username'), 'password' => $ app ['config'] -> get ('session.mongo.password'), 'base de données' => $ app ['config'] -> get ('session.mongo.database'), 'collection' => $ app ['config'] -> get ('session.mongo.collection'))); )
Assurez-vous de mettre à jour le registre()
méthode pour appeler cette méthode:
/ ** * Enregistrez le fournisseur de services. * * @return void * / public function register () $ this-> setupDefaultDriver (); $ this-> registerSessionManager (); $ this-> setupMongoDriver (); $ this-> registerSessionDriver ();
Ensuite, nous devons définir la configuration de la base de données Mongo. Ouvrir app / config / session.php
et définissez les paramètres de configuration suivants:
/ ** * Paramètres Mongo DB * / 'mongo' => array ('host' => '127.0.0.1', 'username' => ", 'password' =>", 'database' => 'laravel', 'collection' => 'laravel_session_collection')
Pendant que nous sommes sur ce fichier, nous devrions également mettre à jour le chauffeur
configuration en haut:
'driver' => 'mongo'
Maintenant, essayez d’accéder à la page principale (généralement, localhost / un dossier / public
). Si cette page se charge sans afficher la WHOOPS
page, puis félicitations, nous avons créé avec succès un tout nouveau pilote de session! Testez-le en définissant des données factices sur la session, via Session :: set ()
puis en le renvoyant via Session :: get ()
.
Le composant Laravel Auth gère l'authentification des utilisateurs pour la structure, ainsi que la gestion des mots de passe. Le composant Laravel a créé ici une interprétation abstraite du système de gestion des utilisateurs typique, utilisable dans la plupart des applications Web, ce qui aide le programmeur à implémenter facilement un système de connexion. Comme le composant Session, il utilise également le gestionnaire Laravel. Actuellement, le composant Auth dispose de pilotes pour:
éloquent
- cela fait appel à l'ORM intégré de Laravel appelé Éloquent
. Il utilise également le pré-fait User.php
classe à l'intérieur du des modèles
dossier.base de données
- ceci utilise la connexion de base de données configurée par défaut. Il utilise un GenericUser
classe pour accéder aux données de l'utilisateur.Comme cela suit la même mise en œuvre que le Session
composant, le fournisseur de service est très similaire à ce que nous avons vu en haut:
/ ** * Enregistrez le fournisseur de services. * * @return void * / public function register () $ this-> app-> bindShared ('auth', function ($ app) // Une fois que le service d'authentification a été demandé par le développeur // nous allons définir une variable dans l’application indiquant ceci, ce qui nous aide // à savoir que nous devons définir ultérieurement les cookies en file d'attente dans l'événement after. $ app ['auth.loaded'] = true; renvoie le nouvel AuthManager ($ app);) ;
Ici, nous pouvons voir que cela crée essentiellement un AuthManager
classe qui englobe le pilote que nous utilisons, en plus d’agir en tant qu’usine. À l'intérieur de AuthManager
, il crée à nouveau le pilote approprié, enroulé autour d'un Garde
classe, qui agit de la même manière que le le magasin
classe de Session
.
Comme avant, commençons par créer un MongoUserProvider
:
config = $ config; $ connection_string = 'Mongodb: //'; if (! empty ($ this-> config ['nom d'utilisateur']]) &&! empty ($ this-> config ['mot de passe'])) $ connection_string. = "$ this-> config ['utilisateur'] : $ this-> config ['password'] @ "; $ connection_string. = "$ this-> config ['hôte']"; $ this-> connection = new Mongo ($ connection_string); $ this-> collection = $ this-> connection-> selectCollection ($ this-> config ['database'], $ this-> config ['collection']); / ** * Récupère un utilisateur par son identifiant unique. * * @param mixed $ identifier * @return \ Illuminate \ Auth \ UserInterface | null * / fonction publique retrieveById ($ identifier) $ user_data = $ this-> collection-> findOne (array ('_id' => $ identifier, )); if (! is_null ($ user_data)) retour new GenericUser ((array) $ user_data); / ** * Récupérer un utilisateur à l'aide des informations d'identification fournies. * * @param array $ credentials * @return \ Illuminate \ Auth \ UserInterface | null * / fonction publique retrieveByCredentials (array $ credentials) // Essayer de rechercher l'utilisateur en premier, peu importe le mot de passe //, nous le ferons dans le Méthode validateCredentials if (isset ($ credentials ['password']))) unset ($ credentials ['password'])); $ user_data = $ this-> collection-> findOne ($ credentials); if (! is_null ($ user_data)) retour new GenericUser ((array) $ user_data); / ** * Valider un utilisateur en fonction des informations d'identification fournies. * * @param \ Illuminate \ Auth \ UserInterface $ utilisateur * @param tableau $ informations d'identification * @return bool * / fonction publique validateCredentials (UserInterface $ utilisateur, tableau $ informations d'identification) if (! isset ($ informations d'identification ['mot de passe']) ) return false; return ($ credentials ['password'] === $ user-> getAuthPassword ());
Il est important de noter ici que je ne vérifie pas un mot de passe haché, cela a été fait pour des raisons de simplicité afin de nous permettre de créer plus facilement des données factices et de les tester plus tard. Dans le code de production, vous devez vous assurer de hacher le mot de passe. Vérifiez Illuminate \ Auth \ DatabaseUserProvider
classe pour un excellent exemple sur la façon de le faire.
Ensuite, nous devons enregistrer notre rappel de pilote personnalisé sur le AuthManager
. Pour ce faire, nous devons mettre à jour les informations du fournisseur de services. registre
méthode:
/ ** * Enregistrez le fournisseur de services. * * @return void * / public function register () $ this-> app-> bindShared ('auth', function ($ app) // Une fois que le service d'authentification a été demandé par le développeur // nous allons définir une variable dans l’application nous indiquant // que nous devons définir ultérieurement les cookies en file d'attente dans l'événement after. $ app ['auth.loaded'] = true; $ auth_manager = new AuthManager ($ app); $ auth_manager-> extend ('mongo', fonction ($ app) retourne le nouveau MongoUserProvider (array ('hôte' => $ app ['config'] -> get ('auth.mongo.host'), 'nomutilisateur' => $ app ['config'] -> get ('auth.mongo.username'), 'password' => $ app ['config'] -> get ('auth.mongo.password'), 'base de données' => $ app ['config'] -> get ('auth.mongo.database'), 'collection' => $ app ['config'] -> get ('auth.mongo.collection'))) ); return $ auth_manager;);
Enfin, nous devons également mettre à jour le auth.php
fichier de configuration pour utiliser le pilote Mongo et lui fournir les valeurs de configuration Mongo appropriées:
'driver' => 'mongo',… / ** * Paramètres de la base de données Mongo * / 'mongo' => array ('host' => '127.0.0.1', 'username' => ", 'password' =>" , 'database' => 'laravel', 'collection' => 'laravel_auth_collection')
Le test est un peu plus délicat. Pour ce faire, utilisez la CLI de Mongo DB pour insérer un nouvel utilisateur dans la collection:
mongo> use laravel_auth a basculé sur db laravel_auth> db.laravel_auth_collection.insert (id: 1, email: "[email protected]", mot de passe: "test_password")> db.laravel_auth_collection.find ()> "_id" : ObjectId ("530c609f2caac8c3a8e4814f"), "id" 1, "email": "[email protected]", "mot de passe": "mot_de_passe_test"
Maintenant, testez-le en essayant un Auth :: valider
appel de méthode:
var_dump (Auth :: validate (array ('email' => '[email protected]', 'password' => 'test_password')));
Cela devrait jeter un bool (true)
. Si tel est le cas, nous avons créé avec succès notre propre pilote Auth.!
Le composant Laravel Cache gère les mécanismes de mise en cache à utiliser dans la structure. Comme les deux composants dont nous avons parlé, il utilise également le gestionnaire Laravel (remarquez-vous un modèle?). Le composant Cache possède des pilotes pour:
apc
memcached
redis
fichier
- un cache basé sur des fichiers. Les données sont enregistrées dans le app / stockage / cache
chemin.base de données
- cache base de données. Les données sont enregistrées dans des lignes dans la base de données. Le schéma de base de données est décrit dans la documentation de Laravel.tableau
- les données sont "mises en cache" dans un tableau. Gardez à l'esprit que le tableau
le cache n'est pas persistant et est effacé à chaque chargement de page.Etant donné que cela suit la même implémentation que les deux composants dont nous avons parlé, vous pouvez sans risque supposer que le fournisseur de services est assez similaire:
/ ** * Enregistrez le fournisseur de services. * * @return void * / public function register () $ this-> app-> bindShared ('cache', fonction ($ app) retourne un nouveau cacheManager ($ app);); $ this-> app-> bindShared ('cache.store', fonction ($ app) return $ app ['cache'] -> driver ();); $ this-> app-> bindShared ('memcached.connector', function () renvoie new MemcachedConnector;); $ this-> registerCommands ();
le registre()
méthode crée ici un CacheManager
, cela agit à nouveau comme un emballage et une usine pour les pilotes. Au sein du gestionnaire, le conducteur est entouré Dépôt
classe, semblable à la le magasin
et Garde
Des classes.
Créer le MongoStore
, qui devrait étendre la Illuminer \ Cache \ StoreInterface
:
config = $ config; $ connection_string = 'Mongodb: //'; if (! empty ($ this-> config ['nom d'utilisateur']]) &&! empty ($ this-> config ['mot de passe'])) $ connection_string. = "$ this-> config ['utilisateur'] : $ this-> config ['password'] @ "; $ connection_string. = "$ this-> config ['hôte']"; $ this-> connection = new Mongo ($ connection_string); $ this-> collection = $ this-> connection-> selectCollection ($ this-> config ['database'], $ this-> config ['collection']); / ** * Récupère un élément du cache par clé. * * @param chaîne $ key * @return mixed * / fonction publique get ($ key) $ cache_data = $ this-> getObject ($ key); if (! $ cache_data) return null; return unserialize ($ cache_data ['cache_data']); / ** * Renvoie l'objet entier au lieu de juste la cache_data * * @param chaîne $ key * @return array | null * / protected function getObject ($ key) $ cache_data = $ this-> collection-> findOne (array ('key' => $ key,)); if (is_null ($ cache_data)) return null; if (isset ($ cache_data ['expire']) && time ()> = $ cache_data ['expire']) $ this-> oublier ($ key); return null; return $ cache_data; / ** * Stocke un élément dans le cache pendant un nombre de minutes donné. * * @param chaîne $ clé * @param mixte $ valeur * @param int $ minutes * @retour void * / fonction publique 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))), tableau (' upsert '=> vrai,' multiple '=> faux)); / ** * Incrémente la valeur d'un élément dans le cache. * * @param chaîne $ clé * @param mixte $ valeur * @retour void * * @throws \ LogicException * / incrément de fonction public ($ key, $ value = 1) $ cache_data = $ this-> getObject ($ key) ; if (! $ cache_data) $ new_data = array ('cache_data' => sérialiser ($ valeur), 'expiry' => $ this-> expiration (0), 'ttl' => $ this-> expiration (0) ) else $ new_data = array ('cache_data' => sérialiser (unserialize ($ cache_data ['cache_data']) + $ valeur), '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)) ; / ** * Décrémente la valeur d'un élément du cache. * * @param chaîne $ clé * @param mixte $ valeur * @retour void * * @throws \ LogicException * / fonction publique décrémentée ($ clé, $ valeur = 1) $ cache_data = $ ceci-> getObject ($ clé) ; if (! $ cache_data) $ new_data = array ('cache_data' => sérialiser ((0 - $ valeur)), 'expiry' => $ this-> expiration (0), 'ttl' => $ this-> expiration (0)); else $ new_data = array ('cache_data' => sérialiser (unserialize ($ cache_data ['cache_data']) - $ valeur), '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)) ; / ** * Stocke un élément dans le cache indéfiniment. * * @param chaîne $ clé * @param mixte $ valeur * @retour void * / fonction publique pour toujours ($ key, $ valeur) return $ this-> put ($ key, $ valeur, 0); / ** * Supprimer un élément du cache. * * @param chaine $ key * @retour void * / fonction publique oublier ($ key) $ this-> collection-> remove (array ('key' => $ key)); / ** * Supprimer tous les éléments du cache. * * @return void * / public function flush () $ this-> collection-> remove (); / ** * Obtenir l'heure d'expiration en fonction des minutes données. * * @param int $ minutes * @return int * / expiration de la fonction protégée ($ minutes) if ($ minutes === 0) retourne 9999999999; temps de retour () + ($ minutes * 60); / ** * Récupère le préfixe de la clé de cache. * * @return string * / public function getPrefix () return ";
Nous devrons également ajouter à nouveau le rappel Mongo au gestionnaire:
/ ** * Enregistrez le fournisseur de services. * * @return void * / public function register () $ this-> app-> bindShared ('cache', fonction ($ app) $ cache_manager = new CacheManager ($ app); $ cache_manager-> extend ('mongo ', fonction ($ app) retourne le nouveau MongoStore (array (' hôte '=> $ app [' config '] - - get (' cache.mongo.host '),' nomutilisateur '=> $ 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')));); retour $ cache_manager;) ; $ this-> app-> bindShared ('cache.store', fonction ($ app) return $ app ['cache'] -> driver ();); $ this-> app-> bindShared ('memcached.connector', function () renvoie new MemcachedConnector;); $ this-> registerCommands ();
Enfin, nous devrons mettre à jour le cache.php
fichier de configuration:
'driver' => 'mongo',… / ** * Paramètres de la base de données Mongo * / 'mongo' => array ('host' => '127.0.0.1', 'username' => ", 'password' =>" , 'database' => 'laravel', 'collection' => 'laravel_cache_collection')
Maintenant, essayez d'utiliser le Cache :: put ()
et Cache :: get ()
méthodes. Si cela est fait correctement, nous devrions pouvoir utiliser MongoDB pour mettre en cache les données!
Dans ce tutoriel, nous avons appris ce qui suit:
Éclairer
, qui est utilisé par le framework Laravel.Espérons que cela aide les programmeurs à créer leurs propres pilotes et à étendre les fonctionnalités actuelles du framework Laravel.