I denne Nettuts + mini-serien bygger vi et webprogram fra grunnen, mens du dykker inn i et flott nytt PHP-rammeverk som raskt tar opp damp, kalt Laravel.
I denne leksjonen jobber vi på en integrert del av et hvilket som helst webprogram: Modeller. Underveis lærer vi om Laravels fantastiske ORM-implementering: Eloquent.
Velkommen tilbake til vår Webprogrammer fra grunnen til Laravel serie! I den første opplæringen av serien lærte vi mye om Laravel og dens filosofi:
Hvis du ikke har lest det ennå, bør du ta en titt på den forrige opplæringen og gi den en lesning - dette vil gjøre det lettere å forstå filosofien bak Laravel og det meste av det vi diskuterer i denne opplæringen.
I denne andre delen av Laravel-serien skal vi bygge en avgjørende del av testprogrammet vårt, Instapics, som er modellimplementeringen. Uten at du kommer til å, la oss komme i gang!
Jeg har allerede snakket litt om hva modeller er i en av mine tidligere artikler, Zend Framework fra Scratch-Models og Integrating Doctrine ORM, for å unngå å gjenta meg selv, skal jeg skrive innholdet av det jeg skrev før her. Du er velkommen til å referere til den andre opplæringen og lese mer om hvilke modeller som er der.
Sammendrag:
Modeller i Laravel, eller i de fleste rammer, er utviklet på samme måte. Forskjellen er at Laravel gir oss en enkel måte å bygge disse modellene ved å gi oss generelle metoder som de fleste modeller trenger - Eloquent ORM.
En ORM er en objektrelasjonsmapper, og Laravel har en som du absolutt vil elske! Den heter "Eloquent", fordi den lar deg arbeide med databasobjektene og relasjonene dine ved hjelp av en veltalende og uttrykksfulle syntaks.
Eloquent ORM er Laravels innebygde ORM-implementering. Etter min mening er det en av de beste ORM-implementasjonene jeg har sett så langt - rivaling selv Lære ORM. Det er utrolig elegant, og bruker standardkonvensjoner for å redusere konfigurasjonen.
For eksempel antar man ved bruk av en Eloquent-modell at tabellen modellen representerer, har en id
felt. De id
er den primære nøkkelen for enhver plate, og brukes av de fleste av Eloquents metoder.
En annen ting som Eloquent påtar seg, er at tabellnavnet ditt er flertallsformen til modellen din. For eksempel, din Bruker
modellen vil referere til brukere
bord. Siden dette kanskje ikke alltid er standard for noen, gir Laravel en måte å overstyre dette: bruk bare $ table
flagg:
klassen Brukeren utvider Eloquent offentlig statisk $ table = 'my_users';
Dette vil instruere Laravel om ikke å bruke konvensjonen og i stedet bruke den angitte tabellen.
Til slutt kan Laravel også automatisere opprettelsen og oppdateringen av tidsstempler for oss. For å gjøre det, legg til en created_at
og / eller updated_at
kolonne i tabellen, og sett inn $ timestamp
flagg i modellen:
klassen Brukeren utvider Eloquent public static $ timestamps = true;
Eloquent vil se flagget og automatisk stille inn created_at
feltet ved opprettelse, og oppdater updated_at
feltet hver gang en plate er oppdatert. Ganske kul, hei?
Å hente poster er et snap med Eloquent's henting metoder. For eksempel må du finne en bestemt brukeroppføring? Bare gjør:
$ user = Bruker :: finn ($ user_id);
Dette returnerer a Bruker
modell som du kan gjøre operasjoner på! Trenger du å bruke conditionals? La oss forestille deg at du vil hente en bruker via e-postadresse. For å oppnå denne oppgaven kan du gjøre noe som helst:
$ user = Bruker :: hvor ('email', '=', $ email) -> første ();
Alternativt kan du bruke Laravels dynamiske metoder:
$ user = Bruker :: where_email ($ email) -> første ();
Sette inn og oppdatere modeller ved hjelp av Eloquent kan oppnås i tre trinn.
$ user = ny bruker (); // eller få en eksisterende bruker $ user = User :: get ($ user_id);
$ user-> email = '[email protected]'; $ user-> password = 'test1234';
$ Bruker-> Lagre ();
Eloquent gjør prosessen med å definere relasjoner og hente relaterte modeller enkelt og intuitivt.
Forferdelig, det gjør det! Eloquent støtter tre typer relasjoner:
For å definere et forhold mellom modeller, må du lage en metode i begge modellene som "beskriver" deres relasjoner. For eksempel, la oss si a Bruker
has_one
Brukerprofil
. Du kan gjøre det ved å definere en brukerprofil
metode i Bruker
modell:
klassen Brukeren utvider Eloquent offentlig funksjon user_profile () return $ this-> has_one ('User_Profile');
Fordi Bruker
er vår "dominerende" modell her (dvs. en bruker har en profil, og ikke en profil har en bruker), definerer vi at a Brukerprofil
tilhører
en Bruker
:
klasse User_Profile utvider Eloquent public function user () return $ this-> belongs_to ('User');
Når vi har definert dette forholdet, kan vi da gjøre:
/ * Få Bruker_Profile-objektet til en Bruker Dette kjører to SQL-spørringer: VELG * FRA 'brukere' hvor 'id' = $ user_id VELG * FRA 'user_profiles' WHERE 'user_id' = $ user_id * / $ user = Bruker :: finn ($ user_id); $ user_profile = $ user-> user_profile; / * Vi kan også gjøre det omvendt * / $ user_profile = User_Profile :: where ('user_id', '=', $ user_id) -> first (); $ user = $ user_profile-> bruker;
En ting verdt å merke seg her er en annen konvensjon: Eloquent forutsetter at den utenlandske nøkkelen brukes i Brukerprofil
er referansetabellens navn + _id
. Igjen, hvis du vil endre denne oppførselen, kan du overstyre den:
klassen Brukeren utvider Eloquent offentlig funksjon user_profile () return $ this-> has_one ('User_Profile', 'user_profile_user_id');
La oss si at vi vil definere forholdet mellom a Bruker
og hans Bilde
opplastinger. Dette er en En-til-mange forhold, i motsetning til Bruker
-til-Brukerprofil
forhold som var En-til-en. Vi vet den Bruker
har mange
Bilde
opplastinger, så:
klassen brukeren utvider eloquent public function photos () return $ this-> has_many ('foto'); ... klasse Foto utvider Eloquent public function user () return $ this-> belongs_to ('User');
Hovedforskjellen her med has_one
er det den funksjonen vi skal bruke for å hente a Bruker
bilder vil nå returnere en matrise av Bilde
objekter. Så, hvis vi ønsket å hente alle a Bruker
bilder vi kunne gjøre:
$ photos = Bruker :: finn ($ user_id) -> bilder; foreach ($ bilder som $ bilde) ...
Nei, med henvisning til bilder
som en eiendom er ikke en skrivefeil. Laravel gir oss denne fine bit sukker. Vi kan også gjøre:
$ photos = User :: find ($ user_id) -> photos () -> get ();
Denne er litt vanskelig, men når den er implementert, gjør den det lett å håndtere Mange-til-mange forhold mellom modellene. La oss for eksempel forestille deg at du igjen har en Bruker
modell, og hver av disse brukerne kan ha flere grupper
. EN Gruppe
kan også ha flere brukere
. Vi bruker tre tabeller for å representere disse spesielle forhold:
Tabellstrukturen konvensjonen Eloquent vil se etter, vil være noe slikt:
En annen konvensjon å merke seg her er at mellombordet, GROUP_USER
, er de enslige navnene på de to tabellene som den kobler sammen, ordnet alfabetisk med et understreke. Som alltid er vi fri til å tilsidesette dette.
Slik ser koden ut i hver av modellene for disse tre tabellene:
klassen brukeren utvider eloquent public function groups () // hvis vi ønsket å overstyre standard navngivningskonvensjonen // for mellomtabellen, kan vi gjøre det slik: // returnere $ this-> has_many_and_belongs_to ('Group' group_listings'); returnere $ this-> has_many_and_belongs_to ('Group'); ... klassegruppe utvider Eloquent public function users () // hvis vi ønsket å overstyre standard navngivningskonvensjonen // for mellomtabellen, kan vi gjøre det slik: // returnere $ this-> has_many_and_belongs_to ('Bruker ',' group_listings '); returnere $ this-> has_many_and_belongs_to ('User'); ... klasse Group_User utvider Eloquent public function group () return $ this-> has_one ('Group'); offentlig funksjon bruker () return $ this-> has_one ('bruker');
Med dette på plass kan vi da dra nytte av Eloquents forholdsfunksjoner:
// Få brukerens grupper $ groups = User :: find ($ user_id) -> groups; // Få alle brukere i en gruppe $ users = Group :: find ($ group_id) -> brukere;
Fortsetter med vårt webprogram, Instapics, la oss begynne med å lage databasen av vår søknad. For å gjøre det, la oss skrive ned de ønskede funksjonene i programmet:
Herfra kan vi utlede databasetabellene vi trenger:
La oss gå videre og lage disse tabellene. For dette prosjektet skal jeg bruke MySQL; vær så snill å kopiere og lime inn disse kommandoene.
CREATE DATABASE 'instapics'; BRUK 'instapics'; CREATE TABLE 'instapics'. 'Brukere' ('id' INTEGER UNSIGNED IKKE NULL AUTO_INCREMENT, 'email' VARCHAR (100) IKKE NULL, 'passord' VARCHAR (100) IKKE NULL, 'created_at' DATETID IKKE NULL, 'updated_at' DATETIME IKKE NULL, PRIMARY KEY ('id'), UNIQUE INDEX 'Index_email' ('email')) MOTOR = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE TABLE 'instapics'. 'User_profiles' ('id' INTEGER UNSIGNED IKKE NULL AUTO_INCREMENT, 'user_id' INTEGER UNSIGNED IKKE NULL, 'navn' TEKST IKKE NULL, 'profile_photo' TEKST IKKE NULL, PRIMARY KEY ('id'), UNIQUE INDEX 'Index_user_id' ('user_id'), CONSTRAINT 'FK_user_profiles_user_id' Utenlands nøkkel 'FK_user_profiles_user_id' ('user_id') REFERANSER 'brukere' ('id') DELETE CASCADE ON UPDATE CASCADE) MOTOR = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE TABLE 'instapics'. 'Relations' ('id' INTEGER UNSIGNED IKKE NULL AUTO_INCREMENT, 'follower_id' INTEGER UNSIGNED IKKE NULL, 'followed_id' INTEGER UTSIGNERT IKKE NULL, 'created_at' DATETID IKKE NULL, 'updated_at' DATETID IKKE NULL, PRIMARY KEY ('id'), UNIQUE INDEX 'Index_follower_id_followed_id' ('follower_id', 'followed_id'), CONSTRAINT 'FK_relationships_follower_id' Utenlandske nøkkelen 'FK_relationships_follower_id' ('follower_id') REFERANSER 'brukere' ('id') OM DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT 'FK_relationships_followed_id' FOREIGN KEY 'FK_relationships_followed_id' ('followed_id') REFERANSER 'brukere' ('ID') OM DELETE CASCADE ON UPDATE CASCADE) MOTOR = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE TABLE 'instapics'. 'Photos' ('id' INTEGER UNSIGNED IKKE NULL AUTO_INCREMENT, 'user_id' INTEGER UNSIGNED IKKE NULL, 'plassering' TEKST IKKE NULL, 'beskrivelse' TEKST IKKE NULL, 'created_at' DATETID NOT NULL, 'updated_at 'DATOID IKKE NULL, PRIMÆR NØKKEL (' ID '), KONSTRAINT' FK_photos_user_id 'Utenlandsnøkkel' FK_photos_user_id '(' user_id ') REFERANSER' Brukernes '(' ID ') DELETE CASCADE PÅ OPPDATERING CASCADE) MOTOR = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE TABLE 'instapics'. 'Photo_comments' ('id' INTEGER UNSIGNED IKKE NULL AUTO_INCREMENT, 'user_id' INTEGER UNSIGNED IKKE NULL, 'photo_id' INTEGER UNSIGNED NOT NULL, 'melding' TEKST IKKE NULL, 'created_at' DATETIME NOT NULL, ' updated_at 'DATETID IKKE NULL, PRIMARY KEY (' id '), CONSTRAINT' FK_photo_comments_user_id 'Utenlandsnøkkel' FK_photo_comments_user_id '(' user_id ') REFERANSER' brukere '(' id ') PÅ DELETE CASCADE OM OPPDATERING CASCADE, CONSTRAINT' FK_photo_comments_photo_id 'UDENLANDSKE KEY 'FK_photo_comments_photo_id' ('photo_id') REFERANSER 'photos' ('id') PÅ DELETE CASCADE ON UPDATE CASCADE) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
Alternativt kan du bruke migrasjoner, men vi vurderer dem i en fremtidig leksjon.
Før du gjør noe med Laravel-modeller, må vi konfigurere Laravel-installasjonens databasekonfigurasjon. Åpen application / konfig / database.php, for å finne noen av disse innstillingene:
ekte
vil logge alle SQL querie tider inn i Laravel loggene. La dette være som ekte
for nå.PUD :: FETCH_CLASS
og bør bli igjen som så.$ tilkoblinger
array like nedenforpgsql
, SQLite
, mysql
eller sqlsrv
Redis
bibliotek, kan du konfigurere serverinformasjonen her.I forbindelse med denne opplæringen bruker vi MySQL. Din database.php filen skal se slik ut (jeg fjernet kommentarene, men de burde være fine å beholde):
returnere array ('profile' => true, 'fetch' => PDO :: FETCH_CLASS, 'standard' => 'mysql', 'connections' => array ('mysql' => array ('driver' => 'mysql ',' host '=' 'localhost', 'database' => 'instapics', 'brukernavn' => 'root', 'passord' => '(passordet ditt)', 'charset' => 'utf8' prefix '=> ",),),' redis '=> array (' default '=> array (' vert '=>' 127.0.0.1 ',' port '=> 6379,' database '=> 0) ));
Begynn med å lage en Laravel-modell inne i applikasjons / modeller mappe. Skape user.php inne, og legg til følgende kode:
klassen bruker strekker seg utallige
Nå, basert på vår gjennomgang av hva Bruker
relasjoner er, vi må kodes forholdsmetodene for dem alle:
klassen brukeren utvider eloquent // setting $ timestamp til true så eloquent // vil automatisk sette created_at // og updated_at verdier offentlig statisk $ timestamps = true; offentlig funksjon user_profile () return $ this-> has_one ('User_Profile'); folkeavhengige følgere () return $ this-> has_many_and_belongs_to ('User', 'relations', 'followed_id', 'follower_id'); offentlig funksjon etter () return $ this-> has_many_and_belongs_to ('Bruker', 'relasjoner', 'følger_id', 'followed_id'); offentlige funksjonsfotografier () return $ this-> has_many ('Photo'); offentlig funksjon photo_comment () return $ this-> has_many ('Photo_Comment');
Bemerkelsesverdig gjør vi bruk av noen avanserte mange til mange funksjonaliteter her, på grunn av tabellstrukturen til vår tilhengermodell (dvs. brukere
tabell refererer til forhold
bord som refererer til brukere
bord igjen). De has_many_and_belongs_to
funksjonen har følgende metode signatur:
/ ** * Få spørringen for et mange til mange forhold. * * @param streng $ modell * @param streng $ tabell * @param streng $ utenlandsk * @param streng $ andre * @return Forhold * / offentlig funksjon har_many_and_belongs_to ($ modell, $ table = null, $ utenlandsk = null, $ andre = null)
Dette lar oss faktisk lage en modell som har et mange til mange forhold til seg selv (det vil si brukere følger andre brukere). Vi bruker etterfølgere
og følgende
Metodenavn på Bruker
modell slik at vi kan få brukerens tilhenger eller få alle brukerne som en enkelt bruker følger, henholdsvis.
Følger Bruker
modell, opprett de andre modellene. Når du er ferdig, bør du ha:
Disse filene kommer til å være i opplærings Git-arkiv, så hvis du foretrekker å laste dem ned, kan du finne dem her: https://github.com/nikkobautista/laravel-tutorial
La oss begynne å bruke våre modeller ved å lage noen av brukerfunksjonene vi trenger i programmet. Først opp: Brukerregistrering. Fra den forrige opplæringen har vi allerede opprettet en Registrerings- / påmeldingsskjema på hjemmesiden. Akkurat nå gjør det ikke noe, men la oss koble det til en Bruker
kontrolleren, autentisere
handling. Skape application / kontrollere / user.php med følgende kode:
klasse User_Controller utvider Base_Controller offentlig funksjon action_authenticate ()
Åpen application / synspunkter / home / index.blade.php og se etter innloggingsskjemaet. Oppdater skjemaet på Linje 18 å sende til action_authenticate ()
metode: