Slik programmerer du med Yii2 ActiveRecord

Hva du skal skape

Hvis du spør, "Hva er Yii?" sjekk ut min tidligere opplæring: Introduksjon til Yii Framework, som vurderer fordelene med Yii og inneholder en oversikt over endringene i Yii 2.0, utgitt i oktober 2014.

I denne programmeringen med Yii2-serien, veileder jeg lesere i bruk av Yii2 Framework for PHP. I dagens veiledning vil jeg gå deg gjennom å bruke YiS objektrelasjonelle kartlegging, kjent som ORM, for å jobbe med databaser. Det kalles Active Record og er et viktig aspekt ved programmering database applikasjoner effektivt i Yii.

Yii tilbyr forskjellige måter å jobbe med databasen programmatisk, for eksempel direkte spørringer og en spørringsbygger, men ved hjelp av Active Record tilbyr du et komplett sett med fordeler for objektorientert database programmering. Arbeidet ditt blir mer effektivt, sikrere, fungerer innenfor Yii's modellvisningskontrollerarkitektur, og er bærbart bør du bestemme deg for å bytte databaseplattformer (for eksempel MySQL til PostgreSQL).

Følg med da jeg detaljerer grunnlaget for Active Record i Yii.

Bare en påminnelse, jeg deltar i kommentar tråder nedenfor. Jeg er spesielt interessert hvis du har forskjellige tilnærminger, flere ideer, eller ønsker å foreslå emner for fremtidige opplæringsprogrammer. Hvis du har et spørsmål eller et emneforslag, vennligst legg inn under. Du kan også nå meg på Twitter @ reifman direkte.

Hva er Active Record?

Yii's modellvisningskontroller er en av sine viktigste fordeler. Active Record gir en objektorientert løsning for å jobbe med databasene dine, som er tett integrert med Yii-modeller. Ifølge Wikipedia var det generelle begrepet Active Record "oppkalt av Martin Fowler i sin 2003-bok Mønster av Enterprise Application Architecture."

Yii dokumentasjonen oppsummerer dette kortfattet:

En Active Record-klasse er knyttet til en databasetabell, en Active Record-forekomst tilsvarer en rad i den tabellen, og en Egenskap av en Active Record-forekomst representerer verdien av en bestemt kolonne i den raden. I stedet for å skrive røde SQL-setninger, ville du få tilgang til Active Record-attributter og ringe Active Record-metoder for å få tilgang til og manipulere dataene som er lagret i databasetabeller.

Integrasjonen av Active Record-mønsteret i Yii er en stor styrke i rammen, men vanlig for de fleste rammer som Ruby on Rails. 

Denne abstraksjonen fra modeller til databastabeller gjør det mulig å utføre den tunge løftingen av sikkerhet overalt, f.eks. bryte ned SQL-injeksjonsforespørsler.

YiS Active Record-støtte gir også overførbarhet over en rekke databaser. Du kan bytte databaser uten å måtte endre mye kode:

  • MySQL 4.1 eller nyere
  • PostgreSQL 7.3 eller nyere
  • SQLite 2 og 3
  • Microsoft SQL Server 2008 eller senere
  • CUBRID 9.3 eller senere
  • Oracle
  • Sfinks: via yii \ sphinx \ ActiveRecord, krever yii2-sfinks forlengelse
  • ElasticSearch: via yii \ elasticsearch \ ActiveRecord, krever yii2-elasticsearch forlengelse

Og følgende NoSQL databaser:

  • Redis 2.6.12 eller senere: via yii \ redis \ ActiveRecord, krever yii2-Redis forlengelse
  • MongoDB 1.3.0 eller senere: via yii \ mongodb \ ActiveRecord, krever yii2-mongodb forlengelse

Lære det grunnleggende

I den tidligere episoden, Slik programmerer du med Yii2: Arbeide med databasen og aktiv post, gikk jeg gjennom å opprette databasen din, hvordan Yii kobles til den for hver økt, ved hjelp av en migrering for å opprette databasetabeller, og ved hjelp av Gii (Yii's nyttige kode stillasgenerator) for å lage standardmodellkode. Hvis du ikke er kjent med noe av dette, kan du lese den episoden.

I denne episoden vil jeg fokusere mer på å utnytte Active Record i koden din.

Deklarere en Active Record Class i en modell

Først, la meg vurdere hvordan å transformere en Yii-modell for å utnytte Active Record. Jeg bruker en eksempelmodell jeg opprettet i serien Build Your Startup. Den serien guider deg gjennom hvordan jeg bygger oppstart, møteplanlegger, i Yii2.

Jeg skal bruke eksemplet på en enkel modell jeg opprettet kalt Launch, noe som gjør at besøkende på hjemmesiden kan gi sin e-postadresse hvis de vil bli varslet når produktet er ute av forhåndsvisning og fullt utgitt.

Å bruke Active Record med en modell er ganske enkelt; Legg merke til klasse lansering strekker seg \ yii \ db \ ActiveRecord:

Det er det.

Bygg forespørsler

La oss se på noen vanlige Active Record-spørringer. 

Individuelle poster

Hvis du har en plate-ID, ofte fra en spørringsparameter fra en kontroller, er det enkelt å finne opptaket du vil ha:

offentlig funksjon actionSomething ($ id) $ model = Launch :: findOne ($ id);

Dette er identisk med:

$ model = Start: finn () -> hvor (['id' => $ id]) -> ett ();

Du kan også forlenge -> der array med flere felt eller boolske forhold:

$ model = Launch :: find () -> hvor (['id' => $ id, 'status' => Lansering :: ACTIVE_REQUEST]) ... // tilsvarende $ model = Launch :: find (['id' => $ id) -> ogWhere (['status' => Launch :: ACTIVE_REQUEST]) -> ellerWhere (['status' => Launch :: FUTURE_REQUEST]) ... 

Flere poster

Her er et eksempel på å finne alle poster som samsvarer med et bestemt status sortert etter $ id:

$ people = Launch :: find () -> hvor (['status' => Launch :: STATUS_REQUEST]) -> orderBy ('id') -> all ();

De -> Alt (); finner alle poster i stedet for bare en. Variabelen $ mennesker returneres som en rekke modellobjekter. Alternativt, når det ikke er noen betingelser, kan du få tilgang til alle poster med -> FindAll ();

Tilbakestiller en array

Ved hjelp av indexBy returnerer en rekke elementer indeksert av deres id:

$ people = Launch :: find () -> indexBy ('id') -> all ();

Alternativt kan du returnere en assosiativ array med -> AsArray ():

$ people = Launch :: find () -> asArray () -> all ();

Merk: Yiis dokumentasjon sier, "Mens denne metoden sparer minne og forbedrer ytelsen, er det nærmere det nedre DB-abstraksjonslaget, og du vil miste de fleste Active Record-funksjonene."

Tellende poster

Du kan også returnere bare en telle fra en spørring:

$ count = Launch :: find () -> hvor (['status' => Launch :: STATUS_REQUEST]) -> count ();

Jeg bruker teller mye i møteplanleggeren for statistikk for eksempel; Les mer i vår Dashboard-episode:

// beregne $ count_meetings_completed $ hd-> count_meetings_completed = Møte :: finn () -> hvor (['status' => Møte :: STATUS_COMPLETED]) -> ogWhere ('created_at<'.$since)->telle();; // beregne $ count_meetings_expired $ hd-> count_meetings_expired = Møte :: finn () -> hvor (['status' => Møte :: STATUS_EXPIRED]) -> ogWhere ('created_at<'.$since)->telle();; // beregne $ count_meetings_planning $ hd-> count_meetings_planning = Møte :: finn () -> hvor ('status<'.Meeting::STATUS_COMPLETED)->andWhere ( 'created_at<'.$since)->telle();; // beregne $ count_places $ hd-> count_places = Plasser :: finn () -> hvor ('created_at>'. $ etter) -> ogWhere ('created_at<'.$since)->telle();

Å få tilgang til dataene

Når du har bedt om data, for eksempel en individuell modell, er det enkelt å få tilgang til dataene som et modellobjekt:

$ model = Launch :: findOne ($ id); $ id = $ modell-> id; $ email = $ model-> email;

Jeg behandler ofte arrayer på denne måten:

$ users = Bruker :: findAll (); foreach ($ brukere som $ u) $ id = $ u-> id; $ email = $ u-> e-post;

Massiv oppgave

Du kan også raskt tilordne en matrise til en modellpost via ActiveRecord:

$ values ​​= ['name' => 'James', 'email' => '[email protected]',]; $ kunde = ny kunde (); $ kunde-> attributter = $ verdier; $ Kunde> Lagre ();

Dette brukes ofte til å fylle modelldata etter skjemainnlevering:

hvis (isset ($ _ POST ['FormName'])) $ model-> attributes = $ _POST ['FormName']; hvis ($ modell-> lagre ()) // håndtere suksess

Eller du kan bruke -> Belastning () for dette:

hvis ($ modell-> last (Yii :: $ app-> forespørsel-> post ()) && $ modell-> lagre ()) ...

Yii Gii stillas kode generator er flott å generere modeller ved hjelp av ActiveRecord som gjør mye av dette for deg, f.eks. modeller, kontrollører, skjemaer, visninger, etc..

Lagre data

Som du kan se over, er det også enkelt å lagre data med Active Record. I dette eksemplet fra Yii-dokumentasjonen, opprettes og lagres en ny plate, og deretter lastes en plate av ID, og ​​oppdateringer lagres:

// Sett inn en ny rad med data $ customer = Ny kunde (); $ kunde-> navn = 'james'; $ kunde-> email = '[email protected]'; $ Kunde> Lagre (); // oppdater en eksisterende datarad $ customer = kunde :: findOne (123); $ kunde-> email = '[email protected]'; $ Kunde> Lagre ();

Slette poster

Å slette en plate er enda enklere:

$ u = Bruker: findOne (99); $ U-> slett ();

Oppdaterer tellere

Yii tilbyr også enkle motstrøk. La oss si en brukerplanlegger et annet møte, og jeg sporer hvor mange i brukerbordet:

$ u = Bruker: findOne (99); $ U-> updateCounters ([ 'meeting_count' => 1]); // ekvivalent med // UPDATE 'User' SET 'meeting_count' = 'meeting_count' + 1 hvor 'id' = 99 

relasjoner

Koble tabeller over indekser er en av Active Records mest kraftige funksjoner. For eksempel, i møteplanleggeren kan hvert møte ha 0 eller flere møteplasser. Meeting.php-modellen definerer et relasjonelt ActiveQuery for dette:

* @property MeetingPlace [] $ meetingPlaces / ** * @return \ yii \ db \ ActiveQuery * / offentlig funksjon getMeetingPlaces () return $ this-> hasMany (MeetingPlace :: className (), ['meeting_id' => 'id ']); 

Deretter kan jeg få tilgang til alle møtes steder med $ møteplasser eiendom. Nedenfor laster jeg et møte og itererer over alt møteplasser ganske enkelt som om det var et innebygd utvalg av underobjekter:

$ MTG = Meeting :: finne () -> der ([ 'id' => $ MEETING_ID]) -> en (); foreach ($ mtg-> meetingPlaces as $ mp) ...

Selvfølgelig er dette avhengig av å opprette en fremmednøkkel når du lager bordet i sin migrasjon:

$ this-> createTable ('meeting_place', ['id' => Skjema :: TYPE_PK, 'meeting_id' => Skjema :: TYPE_INTEGER. 'IKKE NULL', 'place_id' => Skjema :: TYPE_INTEGER . 'NOT NULL', 'suggested_by' => Skjema :: TYPE_BIGINT. 'IKKE NULL', 'status' => Skjema :: TYPE_SMALLINT. 'IKKE NULL DEFAULT 0', 'created_at' => Skjema :: TYPE_INTEGER. 'IKKE NULL ',' updated_at '=> Skjema :: TYPE_INTEGER.' NOT NULL ',], $ tableOptions); $ this-> addForeignKey ('fk_meeting_place_meeting', 'meeting meetingplace', 'meeting_id', '% meeting', 'id', 'CASCADE', 'CASCADE'); 

Hva blir det neste

Jeg håper dette ga en enkel introduksjon til noen av Active Records awesomeness. Det inkluderer også livssykluser, transaksjoner og låsing, som jeg kan skrive om i fremtiden. Hvis du vil hoppe videre, tilbyr Yii2 to flotte områder for å lære mer i dokumentasjonen: Yii2 Guide til Active Record og Yii2 Active Record funksjonelle spesifikasjoner. Dette er velskrevne introduksjoner.

Se etter kommende opplæringsprogrammer i Programmering med Yii2-serien når vi fortsetter å dykke inn i ulike aspekter av rammen. Du vil kanskje også sjekke ut nevnte Building Your Startup med PHP-serien.

Hvis du vil vite når neste Yii2 opplæring kommer, følg meg @ reifman på Twitter eller sjekk min instruktørside. 

Relaterte linker

  • Slik programmerer du med Yii2: Arbeider med databasen og Active Record (Envato Tuts +)
  • Yii2 Guide til aktiv plate
  • Yii2 Active Record Funksjonsbeskrivelse
  • Active Record Pattern (Wikipedia)
  • Yii2 Developer Exchange, min Yii2 ressurs side