In questa mini serie Nettuts +, creeremo un'applicazione web da zero, mentre ci immergiamo in un nuovo framework PHP che sta rapidamente prendendo piede, chiamato Laravel.
In questa lezione, lavoreremo su una parte integrante di qualsiasi applicazione web: i Modelli. Lungo la strada, apprenderemo dell'impressionante implementazione ORM di Laravel: Eloquent.
Bentornato al nostro Applicazioni Web da Scratch con Laravel serie! Nel primo tutorial della serie, abbiamo imparato molto su Laravel e la sua filosofia:
Se non l'hai ancora letto, dovresti dare un'occhiata al tutorial precedente e dargli una lettura - questo renderà più facile capire la filosofia di Laravel e la maggior parte di ciò che discuteremo in questo tutorial.
In questa seconda parte della serie di Laravel, creeremo una parte cruciale della nostra applicazione web di test, Instapics, che è l'implementazione del modello. Senza ulteriori indugi, iniziamo!
Ho già parlato un po 'di cosa Modelli sono in uno dei miei articoli precedenti, Zend Framework di Scratch - Modelli e Integrazione di Doctrine ORM, quindi per evitare di ripetermi, scriverò il succo di ciò che ho scritto prima qui. Sentiti libero di fare riferimento all'altro tutorial e leggi di più su cosa ci sono i Modelli.
Sommario:
I modelli in Laravel o nella maggior parte dei framework sono sviluppati allo stesso modo. La differenza è che Laravel ci offre un modo semplice per costruire questi modelli, fornendoci metodi di uso generale di cui la maggior parte dei modelli avrebbe bisogno: il ORM eloquente.
Un ORM è un mappatore di oggetti relazionale e Laravel ne ha uno che amerai assolutamente! Si chiama "Eloquent", perché consente di lavorare con gli oggetti e le relazioni del database usando una sintassi eloquente ed espressiva.
L'ORM di Eloquent è l'implementazione ORM integrata di Laravel. A mio parere, è una delle migliori implementazioni ORM che abbia mai visto fino ad ora, rivaleggiando persino con Doctrine ORM. È incredibilmente elegante, facendo uso di convenzioni standard del settore per ridurre la configurazione.
Ad esempio, l'utilizzo di un modello Eloquent presuppone che la tabella che il modello sta rappresentando abbia un id
campo. Il id
è la chiave primaria per qualsiasi record e viene utilizzata dalla maggior parte dei metodi di Eloquent.
Un'altra cosa che Eloquent presuppone correttamente è che il nome della tua tabella sia la forma plurale del tuo modello. Ad esempio, il tuo Utente
il modello farà riferimento al utenti
tavolo. Poiché questo potrebbe non essere sempre lo standard per alcuni, Laravel offre un modo per ignorarlo: basta usare il $ tavolo
bandiera:
la classe User estende Eloquent public static $ table = 'my_users';
Questo istruirà Laravel a non utilizzare la convenzione e utilizzerà invece la tabella specificata.
Infine, Laravel può anche automatizzare la creazione e l'aggiornamento di timestamp per noi. Per fare ciò, aggiungi un created_at
e / o updated_at
colonna nella tabella e impostare il $ timestamp
bandiera nel modello:
la classe User estende Eloquent public static $ timestamps = true;
Eloquent vedrà la bandiera e imposterà automaticamente il created_at
campo sulla creazione e aggiorna il updated_at
campo ogni volta che viene aggiornato un record. Molto carino, eh?
Recuperare i record è un gioco da ragazzi con i metodi di recupero di Eloquent. Ad esempio, è necessario trovare un record utente specifico? Basta fare:
$ user = User :: find ($ user_id);
Questo restituisce a Utente
modello su cui puoi fare operazioni! Hai bisogno di usare i condizionali? Immaginiamo di voler recuperare un utente tramite indirizzo email. Per portare a termine questo compito, potresti fare qualcosa come:
$ user = User :: where ('email', '=', $ email) -> first ();
In alternativa, puoi utilizzare i metodi dinamici di Laravel:
$ user = User :: where_email ($ email) -> first ();
L'inserimento e l'aggiornamento di modelli tramite Eloquent possono essere eseguiti in tre passaggi.
$ user = new User (); // o ottiene un utente esistente $ user = User :: get ($ user_id);
$ user-> email = '[email protected]'; $ user-> password = 'test1234';
$ User-> save ();
Eloquent rende il processo di definizione delle relazioni e il recupero di modelli correlati semplici e intuitivi.
Accidenti, lo fa! Eloquent supporta tre tipi di relazioni:
Per definire una relazione tra i modelli, è necessario creare un metodo in entrambi i modelli che "descriva" le loro relazioni. Ad esempio, diciamo a Utente
Ha uno
Profilo utente
. Puoi farlo definendo a profilo utente
metodo nel Utente
modello:
la classe User estende Eloquent public function user_profile () return $ this-> has_one ('User_Profile');
Perché Utente
è il nostro modello "dominante" qui (cioè un utente ha un profilo, e non un profilo ha un utente), definiamo che un Profilo utente
appartiene a
un Utente
:
classe User_Profile estende Eloquent public function user () return $ this-> belongs_to ('User');
Una volta che abbiamo definito queste relazioni, possiamo quindi fare:
/ * Ottieni l'oggetto User_Profile di un utente Esegue due query SQL: SELECT * FROM 'users' WHERE 'id' = $ user_id SELECT * FROM 'user_profiles' WHERE 'user_id' = $ user_id * / $ user = User :: find ($ user_id); $ user_profile = $ user-> user_profile; / * Possiamo anche farlo al contrario * / $ user_profile = User_Profile :: where ('user_id', '=', $ user_id) -> first (); $ user = $ user_profile-> user;
Una cosa che vale la pena notare qui è un'altra convenzione: Eloquent presuppone che la chiave esterna utilizzata in Profilo utente
è il nome della tabella di riferimento + _ID
. Di nuovo, se vuoi cambiare questo comportamento, puoi sovrascriverlo:
la classe User estende Eloquent public function user_profile () return $ this-> has_one ('User_Profile', 'user_profile_user_id');
Diciamo che vogliamo definire la relazione tra a Utente
e il suo Foto
uploads. Questo è un Uno-a-molti relazione, a differenza del Utente
-a-Profilo utente
relazione che era Uno a uno. Lo sappiamo Utente
ha molti
Foto
caricamenti, quindi:
l'utente della classe estende Eloquent public function photos () return $ this-> has_many ('Photo'); ... classe Photo estende Eloquent public function user () return $ this-> belongs_to ('User');
La principale differenza qui con Ha uno
è la funzione che useremo per recuperare a Utente
Le foto ora restituiranno un schieramento di Foto
oggetti. Quindi, se volessimo recuperare tutto a Utente
Le foto di, potremmo fare:
$ foto = Utente :: trova ($ user_id) -> foto; foreach ($ foto come $ foto) ...
No, riferendosi a fotografie
come una proprietà non è un errore di battitura. Laravel ci regala questo bel pezzetto di zucchero. Potremmo anche fare:
$ foto = Utente :: trova ($ user_id) -> photos () -> get ();
Questo è un po 'complicato, ma una volta implementato, lo rende facile da gestire Molti-a-molti relazioni tra modelli. Immaginiamo, per esempio, che tu, di nuovo, abbia un Utente
modello, e ciascuno di questi utenti può avere più gruppi
. UN Gruppo
può anche avere più utenti
. Utilizzeremo tre tabelle per rappresentare queste relazioni particolari:
La convenzione sulla struttura della tabella che Eloquent cercherà sarà qualcosa del genere:
Un'altra convenzione da notare qui è che il tavolo intermedio, group_user
, sono i nomi singolari delle due tabelle che sta connettendo, disposte in ordine alfabetico con un carattere di sottolineatura. Come sempre, siamo liberi di scavalcare questo.
Ecco come apparirà il codice all'interno di ciascuno dei modelli per queste tre tabelle:
classe User estende Eloquent public function groups () // se vogliamo sovrascrivere la convenzione di denominazione predefinita // per la tabella intermedia, possiamo farlo in questo modo: // return $ this-> has_many_and_belongs_to ('Group', ' group_listings'); restituire $ this-> has_many_and_belongs_to ('Group'); ... class Group estende Eloquent public function users () // se vogliamo sovrascrivere la convenzione di denominazione predefinita // per la tabella intermedia, possiamo farlo in questo modo: // return $ this-> has_many_and_belongs_to ('User ',' group_listings '); restituire $ this-> has_many_and_belongs_to ('User'); ... class Group_User estende Eloquent public function group () return $ this-> has_one ('Group'); public function user () return $ this-> has_one ('User');
Con questo, possiamo quindi sfruttare le funzioni di relazione di Eloquent:
// Ottieni gruppi di utenti $ groups = User :: find ($ user_id) -> groups; // Ottieni tutti gli utenti in un gruppo $ users = Group :: find ($ group_id) -> users;
Proseguendo con la nostra applicazione web, Instapics, iniziamo creando il database della nostra applicazione. Per fare ciò, annotiamo le funzionalità desiderate dell'applicazione:
Da ciò, possiamo dedurre le tabelle del database di cui avremo bisogno:
Andiamo avanti e creare queste tabelle. Per questo progetto, userò MySQL; sentiti libero di copiare e incollare questi comandi.
CREATE DATABASE 'instapics'; USA 'instapics'; CREATE TABLE 'instapics'. 'Users' ('id' INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 'email' VARCHAR (100) NOT NULL, 'password' VARCHAR (100) NOT NULL, 'created_at' DATETIME NOT NULL, 'updated_at' DATETIME NOT NULL, PRIMARY KEY ('id'), UNICO INDICE 'Index_email' ('email')) ENGINE = InnoDB SET CARATTERE utf8 COLLATE utf8_general_ci; CREATE TABLE 'instapics'. 'User_profiles' ('id' INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 'user_id' INTEGER UNSIGNED NOT NULL, 'name' TEXT NOT NULL, 'profile_photo' TESTO NON NULL, PRIMARY KEY ('id'), UNICO INDICE 'Index_user_id' ('user_id'), CONSTRAINT 'FK_user_profiles_user_id' FOREIGN KEY 'FK_user_profiles_user_id' ('user_id') REFERENCES 'users' ('id') ON DELETE CASCADE ON UPDATE CASCADE) ENGINE = InnoDB SET CARATTERE utf8 COLLATE utf8_general_ci; CREATE TABLE 'instapics'. 'Relationships' ('id' INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 'follower_id' INTEGER UNSIGNED NOT NULL, 'follows_id' INTEGER UNSIGNED NOT NULL, 'created_at' DATETIME NOT NULL, 'updated_at' DATETIME NOT NULL, PRIMARY KEY ('id'), INDICE UNICO 'Index_follower_id_followed_id' ('follower_id', 'followed_id'), CONSTRAINT 'FK_relationships_follower_id' FOREIGN KEY 'FK_relationships_follower_id' ('follower_id') REFERENCES 'users' ('id') ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT 'FK_relationships_followed_id' FOREIGN KEY 'FK_relationships_followed_id' ('followed_id') REFERENCES 'users' ('id') ON DELETE CASCADE ON UPDATE CASCADE) ENGINE = InnoDB SET CARATTERE utf8 COLLATE utf8_general_ci; CREATE TABLE 'instapics'. 'Photos' ('id' INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 'user_id' INTEGER UNSIGNED NOT NULL, 'location' TEXT NOT NULL, 'description' TEXT NOT NULL, 'created_at' DATETIME NOT NULL, 'updated_at 'DATETIME NOT NULL, PRIMARY KEY (' id '), CONSTRAINT' FK_photos_user_id 'FOREIGN KEY' FK_photos_user_id '(' user_id ') REFERENCES' users '(' id ') ON DELETE CASCADE ON UPDATE CASCADE) ENGINE = InnoDB SET CARATTERE utf8 COLLATE utf8_general_ci; CREATE TABLE 'instapics'. 'Photo_comments' ('id' INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 'user_id' INTEGER UNSIGNED NOT NULL, 'photo_id' INTEGER UNSIGNED NOT NULL, 'message' TESTO NON NULL, 'created_at' DATETIME NOT NULL, ' updated_at 'DATETIME NOT NULL, PRIMARY KEY (' id '), CONSTRAINT' FK_photo_comments_user_id 'FOREIGN KEY' FK_photo_comments_user_id '(' user_id ') REFERENCES' users '(' id ') ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT' FK_photo_comments_photo_id 'FOREIGN KEY 'FK_photo_comments_photo_id' ('photo_id') REFERENCES 'foto' ('id') ON DELETE CASCADE ON UPDATE CASCADE) ENGINE = InnoDB SET CARATTERE utf8 COLLATE utf8_general_ci;
In alternativa, puoi utilizzare le migrazioni, ma le esamineremo in una lezione futura.
Prima di fare qualsiasi cosa con i modelli Laravel, dobbiamo configurare la configurazione del nostro database di installazione di Laravel. Aperto application / config / database.php, per trovare alcune di queste impostazioni:
vero
registrerà tutti i tempi di interrogazione SQL nei log di Laravel. Lascia questo come vero
per adesso.PDO :: FETCH_CLASS
e dovrebbe essere lasciato così.$ connessioni
array appena sottopgsql
, sqlite
, mysql
o SQLSRV
Redis
libreria, è possibile impostare le informazioni sul server qui.Ai fini di questo tutorial, useremo MySQL. Il tuo database.php il file dovrebbe apparire in questo modo (ho rimosso i commenti, ma dovrebbero essere a posto per mantenerli):
return array ('profile' => true, 'fetch' => PDO :: FETCH_CLASS, 'default' => 'mysql', 'connections' => array ('mysql' => array ('driver' => 'mysql ',' host '=>' localhost ',' database '=>' instapics ',' username '=>' root ',' password '=>' (yourpassword) ',' charset '=>' utf8 ',' prefisso '=> ",),),' redis '=> array (' default '=> array (' host '=>' 127.0.0.1 ',' port '=> 6379,' database '=> 0), ));
Inizia creando un modello Laravel all'interno del applicazione / modelli cartella. Creare user.php dentro e aggiungi il seguente codice:
l'utente della classe estende Eloquent
Ora, basato sulla nostra recensione di ciò che il Utente
Le relazioni sono, abbiamo bisogno di codificare i metodi di relazione per tutti loro:
class User estende Eloquent // impostando $ timestamp su true in modo che Eloquent // imposti automaticamente i valori created_at // e updated_at public static $ timestamp = true; public function user_profile () return $ this-> has_one ('User_Profile'); public function followers () return $ this-> has_many_and_belongs_to ('User', 'relationships', 'follows_id', 'follower_id'); public function following () return $ this-> has_many_and_belongs_to ('User', 'relationships', 'follower_id', 'followed_id'); public function photos () return $ this-> has_many ('Photo'); public function photo_comment () return $ this-> has_many ('Photo_Comment');
Notevolmente, facciamo uso di alcune funzionalità avanzate Molti-a-Molti qui, a causa della struttura della tabella del nostro modello di follower (cioè il utenti
i riferimenti della tabella relazioni
tabella che fa riferimento al utenti
tavolo di nuovo). Il has_many_and_belongs_to
la funzione ha la seguente firma del metodo:
/ ** * Ottieni la query per una relazione molti-a-molti. * * @param stringa $ modello * @param stringa $ tabella * @param stringa $ esterna * @param stringa $ altra * @return Relazione * / funzione pubblica has_many_and_belongs_to ($ modello, $ tabella = null, $ foreign = null, $ altro = null)
Questo in realtà ci consente di creare un modello che ha una relazione molti-a-molti con sé stesso (ad esempio, gli utenti seguono altri utenti). Noi usiamo seguaci
e a seguire
i nomi dei metodi su Utente
modello per consentirci di ottenere i follower di un utente o ottenere tutti gli utenti che un singolo utente sta seguendo, rispettivamente.
Seguendo il Utente
modello, crea gli altri modelli. Al termine, dovresti avere:
Questi file si troveranno nel repository Git del tutorial, quindi se preferisci scaricarli, puoi trovarli qui: https://github.com/nikkobautista/laravel-tutorial
Iniziamo ad usare i nostri modelli creando alcune delle funzioni utente di cui avremo bisogno nell'applicazione. Primo: registrazione dell'utente. Dal tutorial precedente, abbiamo già creato un Modulo di registrazione / accesso sulla home page. In questo momento, non sta facendo nulla, ma colleghiamo a Utente
controllore, autenticare
azione. Creare application / controller / user.php con il seguente codice:
class User_Controller estende Base_Controller public function action_authenticate ()
Aperto application / views / home / index.blade.php e cerca il modulo di accesso. Aggiorna il modulo su Linea 18 presentare al action_authenticate ()
metodo: