Hur man programmerar med Yii2 ActiveRecord

Vad du ska skapa

Om du frågar, "Vad är Yii?" kolla in min tidigare handledning: Introduktion till Yii Framework, som granskar fördelarna med Yii och innehåller en översikt över förändringarna i Yii 2.0, som släpptes i oktober 2014.

I denna programmering med Yii2-serien guidar jag läsare som använder Yii2 Framework for PHP. I dagens handledning går jag igenom dig genom att använda YiS objektrelationella kartläggning, kallad ORM, för att arbeta med databaser. Det heter Active Record och är en viktig aspekt av programmeringsdatabasprogrammen effektivt i Yii.

Yii erbjuder olika sätt att arbeta med din databas programmatiskt, t.ex. direktfrågor och en frågebyggare, men med Active Record kan du erbjuda en komplett uppsättning fördelar för objektorienterad databasprogrammering. Ditt arbete blir effektivare, säkrare, fungerar inom Yii: s modellvisningskontrollarkitektur och är bärbar om du väljer att byta databasplattformar (t.ex. MySQL till PostgreSQL).

Följ med när jag redogör för grunderna för Active Record inom Yii.

Bara en påminnelse, jag deltar i kommentera trådarna nedan. Jag är särskilt intresserad om du har olika tillvägagångssätt, ytterligare idéer, eller vill föreslå ämnen för framtida handledning. Om du har en fråga eller ett ämne förslag, vänligen posta nedan. Du kan också nå mig på Twitter @ reifman direkt.

Vad är Active Record?

Yii's modellvisningskontroller är en av dess viktigaste fördelar. Active Record ger en objektorienterad lösning för att arbeta med dina databaser som är nära integrerade med Yii-modeller. Enligt Wikipedia var den allmänna termen Active Record "namngiven av Martin Fowler i sin 2003-bok Mönster av Enterprise Application Architecture."

Yii dokumentationen sammanfattar detta kortfattat:

En Active Record-klass är associerad med en databastabell, en Active Record-instans motsvarar en rad i den tabellen och en attribut av en Active Record-instans representerar värdet för en viss kolumn i den raden. I stället för att skriva råa SQL-satser, skulle du få tillgång till Active Record-attribut och ringa Active Record-metoder för att komma åt och manipulera data som lagras i databastabeller.

Integrationen av Active Record-mönstret i Yii är en stor styrka av ramverket, men vanlig för de flesta ramar som Ruby on Rails. 

Denna abstraktion från modeller till databastabeller möjliggör ramverket att utföra den tunga lyftningen av säkerhet överallt, t.ex. bryta ner SQL-injektionsfrågor.

YiS Active Record-stöd ger också bärbarhet över ett antal databaser. Du kan byta databaser utan att behöva byta mycket kod:

  • MySQL 4.1 eller senare
  • PostgreSQL 7,3 eller senare
  • SQLite 2 och 3
  • Microsoft SQL Server 2008 eller senare
  • CUBRID 9.3 eller senare
  • Orakel
  • Sfinx: via yii \ sphinx \ ActiveRecord, kräver yii2-sphinx förlängning
  • ElasticSearch: via yii \ elasticsearch \ ActiveRecord, kräver yii2-elasticsearch förlängning

Och följande NoSQL-databaser:

  • Redis 2.6.12 eller senare: via yii \ redis \ ActiveRecord krävs det yii2-redis förlängning
  • MongoDB 1.3.0 eller senare: via yii \ mongodb \ ActiveRecord, krävs yii2-mongodb förlängning

Lär dig grunderna

I det tidigare avsnittet, hur man programmerar med Yii2: arbetar med databasen och aktiva inspelningen, gick jag igenom skapandet av din databas, hur Yii ansluter till den för varje session, använder en migrering för att skapa databastabeller och använder Gii (Yii hjälpkod ställningsgenerator) för att skapa standardmodellkod. Om du inte är bekant med något av detta, granska det avsnittet.

I det här avsnittet fokuserar jag mer på att utnyttja Active Record i din kod.

Deklarera en Active Record Class i en modell

Först, låt mig granska hur man ska förvandla en Yii-modell för att utnyttja Active Record. Jag använder en exempelmodell som jag skapade i serien Building Your Startup. Den serien leder dig igenom hur jag bygger min uppstart, mötesplanerare, i Yii2.

Jag använder exemplet på en enkel modell som jag skapade kallad Starta, vilket gör det möjligt för hemsida besökare att skicka sin e-postadress om de vill bli underrättad när produkten är förhandsvisning och helt utsläppt.

Att använda Active Record med en modell är ganska enkelt; märker Klasslanseringen sträcker sig \ yii \ db \ ActiveRecord:

Det är allt.

Bygga frågor

Låt oss titta på några vanliga Active Record-frågor. 

Individuella poster

Om du har ett post-ID, ofta från en frågeparameter från en kontroller, är det enkelt att hitta den post som du vill ha:

public function actionSomething ($ id) $ model = Launch :: findOne ($ id);

Detta är identiskt med:

$ model = Starta: hitta () -> var (['id' => $ id]) -> ett ();

Du kan också förlänga -> där array med fler fält eller boolesiska förhållanden:

$ model = Starta: hitta () -> var (['id' => $ id, 'status' => Starta :: ACTIVE_REQUEST]) ... // motsvarar $ model = Starta (['id' => $ id) -> ochVär (['status' => Starta :: ACTIVE_REQUEST]) -> ellerWhere (['status' => Starta :: FUTURE_REQUEST]) ... 

Flera poster

Här är ett exempel på att hitta alla poster som matchar en specifik status sorterade efter $ id:

$ people = Starta: hitta () -> var (['status' => Starta :: STATUS_REQUEST]) -> orderBy ('id') -> alla ();

De -> Alla (); hittar alla poster istället för endast en. Variabeln $ folk returneras som en rad modellobjekt. Alternativt, när det inte finns några villkor, kan du komma åt alla poster med -> FindAll ();

Återkommer en array

Använder sig av indexBy returnerar en rad poster indexerade av deras id:

$ people = Starta :: hitta () -> indexBy ('id') -> alla ();

Alternativt kan du returnera en associativ array med -> AsArray ():

$ people = Starta: hitta () -> asArray () -> alla ();

Notera: Yii dokumentation säger, "Medan den här metoden sparar minne och förbättrar prestanda, ligger det närmare det nedre DB-abstraktionsskiktet och du kommer att förlora de flesta aktiva funktionerna."

Räkning av poster

Du kan också returnera bara en räkna från en fråga:

$ count = Starta: hitta () -> var (['status' => Starta :: STATUS_REQUEST]) -> count ();

Jag använder mycket i mötesplanerare för statistik till exempel; lära dig mer i vårt Dashboard-avsnitt:

// beräkna $ count_meetings_completed $ hd-> count_meetings_completed = Möte :: hitta () -> var (['status' => Möte :: STATUS_COMPLETED]) -> ochWhere ('created_at<'.$since)->räkna();; // beräkna $ count_meetings_expired $ hd-> count_meetings_expired = Möte :: hitta () -> var (['status' => Möte :: STATUS_EXPIRED]) -> ochWhere ('created_at<'.$since)->räkna();; // beräkna $ count_meetings_planning $ hd-> count_meetings_planning = Möte :: hitta () -> var ('status<'.Meeting::STATUS_COMPLETED)->andWhere ( 'created_at<'.$since)->räkna();; // beräkna $ count_places $ hd-> count_places = Placera :: hitta () -> var ('created_at>'. $ after) -> ochWhere ('created_at<'.$since)->räkna();

Åtkomst till data

När du har frågat data, till exempel en enskild modell, är det enkelt att komma åt data som ett modellobjekt:

$ model = Starta :: hitta en ($ id); $ id = $ modell-> id; $ email = $ model-> email;

Jag hanterar ofta arrays så här:

$ users = User :: findAll (); foreach ($ användare som $ u) $ id = $ u-> id; $ email = $ u-> email;

Massiv uppgift

Du kan också snabbt tilldela en array till en modellrekord via ActiveRecord:

$ values ​​= ['name' => 'James', 'email' => '[email protected]',]; $ kund = ny kund (); $ kund-> attribut = $ värden; $ Kund> Spara ();

Detta används ofta för att fylla modelldata efter formulärinsändning:

om (isset ($ _ POST ['FormName'])) $ model-> attribut = $ _POST ['FormName']; om ($ modell-> spara ()) // hantera framgång

Eller du kan använda -> Load () för detta:

om ($ modell-> ladda (Yii :: $ app-> request-> post ()) && $ model-> spara ()) ...

Yiis Gii ställnings kodgenerator är utmärkt för att generera modeller med ActiveRecord som gör mycket av det här för dig, t.ex. modeller, kontroller, former, visningar, etc..

Spara data

Som du kan se ovan är det också enkelt att spara data med Active Record. I det här exemplet från Yii-dokumentationen skapas och sparas en ny post, och sedan laddas en post av id, och uppdateringar sparas:

// infoga en ny rad data $ customer = ny kund (); $ kund-> name = 'James'; $ kund-> email = '[email protected]'; $ Kund> Spara (); // Uppdatera en befintlig rad data $ customer = Kund :: findOne (123); $ kund-> email = '[email protected]'; $ Kund> Spara ();

Radera poster

Att radera en post är ännu enklare:

$ u = Användare :: hitta En (99); $ U-> Delete ();

Uppdatering av räknare

Yii erbjuder även enkla räknevärden. Låt oss säga ett användarplan ett annat möte, och jag spårar hur många i användartabellen:

$ u = Användare :: hitta En (99); $ U-> updateCounters ([ 'meeting_count' => 1]); // motsvarar // UPDATE 'User' SET 'meeting_count' = 'meeting_count' + 1 VAR 'id' = 99 

relationer

Att ansluta tabeller över index är en av Active Records mest kraftfulla funktioner. I mötesplaneraren kan till exempel varje möte ha 0 eller mer mötesplatser. Meeting.php-modellen definierar en relationell ActiveQuery för detta:

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

Då kan jag få tillgång till alla mötesplatser med $ mötesplatser fast egendom. Nedan laddar jag ett möte och itererar över alla dess mötesplatser ganska enkelt som om det var en inbyggd rad underobjekt:

$ Mtg = Meeting :: hitta () -> där ([ 'id' => $ MEETING_ID]) -> en (); foreach ($ mtg-> meetingPlaces as $ mp) ...

Det här är givetvis beroende av att du skapar en främmande nyckel när du skapar bordet i dess migrering:

$ this-> createTable ('meeting_place', ['id' => Schema :: TYPE_PK, 'meeting_id' => Schema :: TYPE_INTEGER. 'INTE NULL', 'place_id' => Schema :: TYPE_INTEGER 'NOT NULL', 'suggested_by' => Schema :: TYPE_BIGINT. 'INTE NULL', 'status' => Schema :: TYPE_SMALLINT. 'INTE NULLSTÄLLD 0', 'created_at' => Schema :: TYPE_INTEGER. 'INTE NULL ',' updated_at '=> Schema :: TYPE_INTEGER.' NOT NULL ',], $ tableOptions); $ this-> addForeignKey ("fk_meeting_place_meeting", "meeting meetingplace", "meeting_id", "meeting meeting", "id", "CASCADE", "CASCADE"); 

Vad kommer härnäst

Jag hoppas det gav en enkel introduktion till några av Active Records awesomeness. Det inkluderar också livscykler, transaktioner och låsning, som jag kan skriva om i framtiden. Om du vill hoppa framåt, erbjuder Yii2 två stora områden för att lära dig mer i dokumentationen: Yii2 Guide till Active Record och Yii2 Active Record funktionella specifikationer. Dessa är välskrivna introduktioner.

Titta på kommande handledningar i Programmering med Yii2-serien när vi fortsätter att dyka in i olika aspekter av ramen. Du kanske också vill kolla in ovan nämnda Building Your Startup With PHP-serien.

Om du vill veta när nästa Yii2 handledning kommer, följ mig @reifman på Twitter eller kolla min instruktörssida. 

relaterade länkar

  • Hur man programmerar med Yii2: Arbetar med databasen och aktiva inspelningen (Envato Tuts +)
  • Yii2 Guide till aktiv inspelning
  • Yii2 Active Record Funktionsspecifikation
  • Aktivt inspelningsmönster (Wikipedia)
  • Yii2 Developer Exchange, min Yii2 resurs webbplats