Hoe te programmeren met Yii2 ActiveRecord

Wat je gaat creëren

Als je vraagt: "Wat is Yii?" bekijk mijn eerdere tutorial: Introductie tot het Yii Framework, die de voordelen van Yii herziet en een overzicht van de veranderingen in Yii 2.0 bevat, uitgebracht in oktober 2014.

In deze serie Programming With Yii2 begeleid ik lezers in gebruik van het Yii2 Framework voor PHP. In de tutorial van vandaag zal ik je helpen om Yii's object-relationele mapping, bekend als ORM, te gebruiken voor het werken met databases. Het heet Active Record en is een belangrijk aspect van het efficiënt programmeren van databaseapplicaties in Yii.

Yii biedt verschillende manieren om met uw database programmatisch te werken, zoals directe query's en een querybuilder, maar het gebruik van Active Record biedt een complete set voordelen voor objectgeoriënteerde databaseprogrammering. Uw werk wordt efficiënter, veiliger, werkt binnen de modelweergavecontrollerarchitectuur van Yii en is draagbaar als u besluit om van databaseplatform te wisselen (bijvoorbeeld MySQL naar PostgreSQL).

Volg dit terwijl ik de basisprincipes van Active Record in Yii detaileer.

Ter herinnering, ik neem wel deel aan de commentaarthreads hieronder. Ik ben vooral geïnteresseerd in verschillende benaderingen, aanvullende ideeën of onderwerpen voor toekomstige zelfstudies. Als u een vraag of een suggestie voor een onderwerp heeft, kunt u hieronder berichten plaatsen. Je kunt me ook rechtstreeks op Twitter @reifman bereiken.

Wat is actief record?

De modelaanzicht-controller van Yii is een van de belangrijkste voordelen. Active Record biedt een objectgerichte oplossing voor het werken met uw databases, die nauw is geïntegreerd met Yii-modellen. Volgens Wikipedia was de algemene term Active Record "door Martin Fowler in zijn boek uit 2003 genoemd Patronen van Enterprise Application Architecture."

De Yii-documentatie vat dit beknopt samen:

Een Active Record-klasse is gekoppeld aan een databasetabel, een Active Record-instantie komt overeen met een rij van die tabel en een attribuut van een Active Record-instantie vertegenwoordigt de waarde van een bepaalde kolom in die rij. In plaats van onbewerkte SQL-instructies te schrijven, krijgt u toegang tot Active Record-kenmerken en worden Active Record-methoden aangeroepen voor toegang tot en manipulatie van de gegevens die zijn opgeslagen in databasetabellen.

De integratie van de Active Record-patronen in Yii is een grote sterkte van het framework, maar gebruikelijk voor de meeste frameworks zoals Ruby on Rails. 

Deze abstractie van modellen naar databasetabellen maakt het mogelijk dat het raamwerk overal de zware opheffing van beveiliging uitvoert, b.v. het doorzoeken van SQL-injectievragen.

Yii's Active Record-ondersteuning biedt ook overdraagbaarheid via een aantal databases. U kunt van database wisselen zonder dat u waarschijnlijk veel code hoeft te wijzigen:

  • MySQL 4.1 of hoger
  • PostgreSQL 7.3 of hoger
  • SQLite 2 en 3
  • Microsoft SQL Server 2008 of hoger
  • CUBRID 9.3 of nieuwer
  • Orakel
  • Sfinx: via yii \ sphinx \ ActiveRecord, vereist de yii2-sphinx uitbreiding
  • ElasticSearch: via yii \ elasticsearch \ ActiveRecord, vereist de yii2-elasticsearch uitbreiding

En de volgende NoSQL-databases:

  • Redis 2.6.12 of nieuwer: via yii \ redis \ ActiveRecord, vereist de yii2-redis uitbreiding
  • MongoDB 1.3.0 of later: via yii \ mongodb \ ActiveRecord, vereist de yii2-MongoDB uitbreiding

De basisprincipes leren

In de eerdere aflevering How to Program With Yii2: werken met de database en het actieve record, heb ik door het maken van uw database gelopen, hoe Yii er verbinding mee maakt voor elke sessie, een migratie gebruikt om databasetabellen te maken en Gii (de nuttige code van Yii) steiger generator) om standaard modelcode te creëren. Als je niet bekend bent met een van deze, bekijk dan die aflevering.

In deze aflevering zal ik me meer richten op het gebruik van Active Record in uw code.

Een actieve recordklasse in een model declareren

Laat me eerst bekijken hoe een Yii-model kan worden omgezet in Active Record. Ik gebruik een voorbeeldmodel dat ik heb gemaakt in de reeks Building Your Startup. Die serie leidt je door hoe ik mijn startup, Meeting Planner, in Yii2 aan het bouwen ben.

Ik gebruik het voorbeeld van een eenvoudig model dat ik heb gemaakt met de naam Launch, waarmee bezoekers van de homepage hun e-mailadres kunnen opgeven als ze een melding willen ontvangen wanneer het product geen preview heeft en volledig is vrijgegeven.

Het gebruik van Active Record met een model is vrij eenvoudig; let op de class Launch breidt \ yii \ db \ ActiveRecord uit:

Dat is het.

Query's bouwen

Laten we eens kijken naar enkele veelvoorkomende Active Record-query's. 

Individuele records

Als u een record-ID hebt, vaak uit een queryparameter van een controller, kunt u eenvoudig de gewenste record vinden:

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

Dit is identiek aan:

$ model = Start: find () -> where (['id' => $ id]) -> one ();

Je kunt ook het -> waarbij array met meer velden of booleaanse condities:

$ model = Start: find () -> where (['id' => $ id, 'status' => Launch :: ACTIVE_REQUEST]) ... // equivalent aan $ model = Launch :: find () -> waar (['id' => $ id) -> enWaar (['status' => Launch :: ACTIVE_REQUEST]) -> orWhere (['status' => Launch :: FUTURE_REQUEST]) ... 

Meerdere records

Hier is een voorbeeld van het vinden van alle records die overeenkomen met een specifiek staat gesorteerd op $ id:

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

De -> Alle (); vindt alle records in plaats van slechts één. De variabele $ mensen wordt geretourneerd als een array van modelobjecten. Als er geen voorwaarden zijn, kunt u ook alle records openen met -> Findall ();

Een array retourneren

Gebruik makend van indexBy geeft een reeks items geretourneerd door hun terug ID kaart:

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

Als alternatief kunt u een associatieve array retourneren met -> AsArray ():

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

Notitie: De documentatie van Yii zegt: "Hoewel deze methode geheugen bespaart en de prestaties verbetert, bevindt deze zich dichter bij de onderste DB-abstractielaag en verliest u de meeste Active Record-functies."

Records tellen

U kunt ook alleen een tellen uit een zoekopdracht:

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

Ik gebruik veel in Meeting Planner voor statistieken bijvoorbeeld; lees meer in onze Dashboard-aflevering:

// bereken $ count_meetings_completed $ hd-> count_meetings_completed = Meeting :: find () -> where (['status' => Meeting :: STATUS_COMPLETED]) -> andWhere ('created_at<'.$since)->optellen () ;; // bereken $ count_meetings_expired $ hd-> count_meetings_expired = Meeting :: find () -> where (['status' => Meeting :: STATUS_EXPIRED]) -> andWhere ('created_at<'.$since)->optellen () ;; // bereken $ count_meetings_planning $ hd-> count_meetings_planning = Meeting :: find () -> where ('status<'.Meeting::STATUS_COMPLETED)->andWhere ( 'created_at<'.$since)->optellen () ;; // bereken $ count_places $ hd-> count_places = Plaats :: find () -> where ('created_at>'. $ after) -> andWhere ('created_at<'.$since)->optellen ();

Toegang tot de gegevens

Nadat u gegevens hebt opgevraagd, zoals een afzonderlijk model, is het eenvoudig om de gegevens als een modelobject te bekijken:

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

Ik verwerk arrays vaak op deze manier:

$ users = User :: findAll (); foreach ($ gebruikers als $ u) $ id = $ u-> id; $ email = $ u-> email;

Enorme toewijzing

U kunt ook snel een array aan een modelrecord toewijzen via ActiveRecord:

$ values ​​= ['name' => 'James', 'email' => '[email protected]',]; $ klant = nieuwe klant (); $ klant-> attributen = $ waarden; $ Klant-> save ();

Dit wordt vaak gebruikt voor het invullen van modelgegevens na het indienen van een formulier:

if (isset ($ _ POST ['FormName'])) $ model-> attributen = $ _POST ['FormName']; if ($ model-> save ()) // handle success

Of je kunt gebruiken -> Load () voor deze:

if ($ model-> load (Yii :: $ app-> request-> post ()) && $ model-> save ()) ...

Yii's Gii steigercodegenerator is geweldig in het genereren van modellen met ActiveRecord die veel van dit voor u doen, bijvoorbeeld modellen, controllers, formulieren, views, enz.

Gegevens opslaan

Zoals u hierboven kunt zien, is het eenvoudig om gegevens te bewaren met Active Record. In dit voorbeeld van de Yii-documentatie wordt een nieuw record gemaakt en opgeslagen - en vervolgens wordt een record per ID geladen en worden updates opgeslagen:

// voeg een nieuwe rij gegevens in $ customer = new Customer (); $ klant-> naam = 'James'; $ customer-> email = '[email protected]'; $ Klant-> save (); // update een bestaande rij met gegevens $ customer = Customer :: findOne (123); $ customer-> email = '[email protected]'; $ Klant-> save ();

Records verwijderen

Het verwijderen van een record is nog eenvoudiger:

$ u = Gebruiker: findOne (99); $ U-> delete ();

Tellers bijwerken

Yii biedt ook eenvoudige tellerincrementen. Laten we zeggen dat een gebruiker een nieuwe afspraak plant en ik volg hoeveel in de gebruikerstabel:

$ u = Gebruiker: findOne (99); $ U-> updateCounters ([ 'meeting_count' => 1]); // equivalent aan // UPDATE 'Gebruiker' SET 'meeting_count' = 'meeting_count' + 1 WHERE 'id' = 99 

Relaties

Het verbinden van tabellen met indexen is een van de krachtigste mogelijkheden van Active Record. In Meeting Planner heeft elke vergadering bijvoorbeeld 0 of meer Ontmoetingsplaatsen. Het Meeting.php-model definieert hiervoor een relationele ActiveQuery:

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

Dan heb ik toegang tot alle plaatsen van een vergadering met de $ ontmoetingsplaatsen eigendom. Hieronder laad ik een vergadering en herhaal ik deze ontmoetingsplaatsen vrij gemakkelijk alsof het een ingebouwde array van subobjecten was:

$ MTG = Ontmoeting :: find () -> waarin ([ 'id' => $ MEETING_ID]) -> één (); foreach ($ mtg-> meetingPlaces as $ mp) ...

Dit is natuurlijk afhankelijk van het maken van een externe sleutel wanneer u de tabel in zijn migratie maakt:

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

Wat is het volgende

Ik hoop dat dit een eenvoudige inleiding bood tot een aantal van de ontzagwekkende prestaties van Active Record. Het omvat ook Life Cycles, Transactions en Locking, waarover ik in de toekomst misschien zal schrijven. Als u vooruit wilt springen, biedt Yii2 twee geweldige gebieden om meer te leren in de documentatie: Yii2 Guide to Active Record en Yii2 Active Record functionele specificaties. Dit zijn goed geschreven introducties.

Kijk uit naar komende tutorials in de Programming With Yii2-serie terwijl we doorgaan met duiken in verschillende aspecten van het framework. Misschien wil je ook de eerder genoemde Building Your Startup With PHP-serie bekijken.

Als je wilt weten wanneer de volgende Yii2-tutorial aankomt, volg me dan @reifman op Twitter of bekijk mijn instructeurpagina. 

Gerelateerde Links

  • Hoe te programmeren met Yii2: werken met de database en het actieve record (Envato Tuts +)
  • Yii2 Gids voor actief record
  • Yii2 Actieve record functionele specificatie
  • Actief opnamepatroon (Wikipedia)
  • Yii2 Developer Exchange, mijn Yii2-bronsite