Come programmare con Yii2 ActiveRecord

Cosa starai creando

Se stai chiedendo "Cos'è Yii?" guarda il mio tutorial precedente: Introduzione al framework Yii, che rivede i vantaggi di Yii e include una panoramica delle modifiche in Yii 2.0, rilasciata nell'ottobre 2014.

In questa serie di programmazione con Yii2, guido i lettori all'uso di Yii2 Framework per PHP. Nel tutorial di oggi, ti guiderò attraverso l'uso del mapping relazionale agli oggetti di Yii, noto come ORM, per lavorare con i database. Si chiama Active Record ed è un aspetto chiave della programmazione delle applicazioni di database in modo efficiente in Yii.

Yii offre diversi modi di lavorare con il database in modo programmatico, come le query dirette e un generatore di query, ma l'utilizzo di Active Record offre una serie completa di vantaggi per la programmazione di database orientata agli oggetti. Il tuo lavoro diventa più efficiente, più sicuro, funziona all'interno dell'architettura del controller di visualizzazione del modello di Yii ed è portabile se decidi di cambiare piattaforma di database (ad esempio, da MySQL a PostgreSQL).

Segui come dettaglio le basi di Active Record all'interno di Yii.

Solo un promemoria, parteciperò alle discussioni dei commenti qui sotto. Sono particolarmente interessato se hai approcci diversi, idee aggiuntive o vuoi suggerire argomenti per futuri tutorial. Se hai una domanda o un suggerimento sull'argomento, per favore pubblica qui sotto. Puoi anche raggiungermi su Twitter direttamente @reifman.

Cos'è il record attivo?

Il controller della vista modello di Yii è uno dei suoi principali vantaggi. Active Record fornisce una soluzione orientata agli oggetti per lavorare con i tuoi database che è strettamente integrato con i modelli Yii. Secondo Wikipedia, il termine generico Active Record è stato "nominato da Martin Fowler nel suo libro del 2003 Modelli di architettura di applicazioni aziendali."

La documentazione Yii riassume questo conciso:

Una classe di record attivo è associata a una tabella di database, un'istanza di record attivo corrisponde a una riga di tale tabella e a attributo di un'istanza Record attivo rappresenta il valore di una particolare colonna in quella riga. Invece di scrivere istruzioni SQL non elaborate, è necessario accedere agli attributi di Active Record e chiamare i metodi Active Record per accedere e manipolare i dati memorizzati nelle tabelle del database.

L'integrazione del pattern Active Record in Yii è una grande forza del framework, ma comune a molti framework come Ruby on Rails. 

Questa astrazione dai modelli alle tabelle di database consente al framework di eseguire il pesante sollevamento della sicurezza ovunque, ad es. abbattere le query di SQL injection.

Il supporto Active Record di Yii offre anche la portabilità su una serie di database. Puoi cambiare i database senza la necessità di dover modificare molto codice:

  • MySQL 4.1 o successivo
  • PostgreSQL 7.3 o successivo
  • SQLite 2 e 3
  • Microsoft SQL Server 2008 o versioni successive
  • CUBRID 9.3 o successivo
  • Oracolo
  • Sfinge: tramite yii \ sphinx \ ActiveRecord, richiede il yii2-sfinge estensione
  • ElasticSearch: tramite yii \ elasticsearch \ ActiveRecord, richiede il comando yii2-elasticsearch estensione

E i seguenti database NoSQL:

  • Redis 2.6.12 o successivo: tramite yii \ redis \ ActiveRecord, richiede il comando yii2-Redis estensione
  • MongoDB 1.3.0 o successivo: tramite yii \ mongodb \ ActiveRecord, richiede il comando yii2-MongoDB estensione

Imparare le basi

Nell'episodio precedente, Come programmare con Yii2: Lavorare con il database e il record attivo, sono passato attraverso la creazione del database, come Yii si collega ad esso per ogni sessione, usando una migrazione per creare tabelle di database e usando Gii (il codice utile di Yii generatore di scaffolding) per creare il codice del modello predefinito. Se non conosci nulla di ciò, ti preghiamo di rivedere quell'episodio.

In questo episodio, mi concentrerò maggiormente sull'utilizzo di Active Record nel tuo codice.

Dichiarazione di una classe di record attivo in un modello

Innanzitutto, vorrei esaminare come trasformare un modello Yii per sfruttare Active Record. Userò un modello di esempio che ho creato nella serie Building Your Startup. Quella serie ti guida attraverso come sto costruendo la mia startup, Meeting Planner, in Yii2.

Userò l'esempio di un modello semplice che ho creato chiamato Launch, che consente ai visitatori della home page di fornire il loro indirizzo email se vogliono essere avvisati quando il prodotto è fuori dall'anteprima e completamente rilasciato.

Usare Active Record con un modello è abbastanza semplice; notare il la classe Launch estende \ yii \ db \ ActiveRecord:

Questo è tutto.

Costruzione di query

Diamo un'occhiata ad alcune comuni query di Active Record. 

Record individuali

Se si dispone di un ID record, spesso da un parametro di query di un controller, è facile trovare il record desiderato:

funzione pubblica actionSomething ($ id) $ model = Launch :: findOne ($ id);

Questo è identico a:

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

Puoi anche estendere il -> dove array con più campi o condizioni booleane:

$ model = Launch :: find () -> dove (['id' => $ id, 'status' => Launch :: ACTIVE_REQUEST]) ... // equivalente a $ model = Launch :: find () -> dove (['id' => $ id) -> andWhere (['status' => Launch :: ACTIVE_REQUEST]) -> orWhere (['status' => Launch :: FUTURE_REQUEST]) ... 

Record multipli

Ecco un esempio di trovare tutti i record che corrispondono a uno specifico stato ordinato per $ id:

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

Il -> Tutti (); trova tutti i record invece di uno solo. La variabile $ persone viene restituito come una matrice di oggetti del modello. In alternativa, quando non ci sono condizioni, puoi accedere a tutti i record con -> FindAll ();

Restituire una matrice

utilizzando indexBy restituisce una serie di elementi indicizzati dal loro id:

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

In alternativa, è possibile restituire un array associativo con -> AsArray ():

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

Nota: La documentazione di Yii dice: "Mentre questo metodo salva la memoria e migliora le prestazioni, è più vicino al livello di astrazione DB inferiore e perderai la maggior parte delle funzionalità di Active Record."

Conteggio dei record

Puoi anche restituire solo a contare da una query:

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

Ad esempio, ad esempio, conta molto in Meeting Planner per le statistiche; scopri di più nel nostro episodio di Dashboard:

// calcola $ count_meetings_completed $ hd-> count_meetings_completed = Meeting :: find () -> dove (['status' => Meeting :: STATUS_COMPLETED]) -> andWhere ('created_at<'.$since)->contare();; // calcola $ count_meetings_expired $ hd-> count_meetings_expired = Meeting :: find () -> dove (['status' => Meeting :: STATUS_EXPIRED]) -> andWhere ('created_at<'.$since)->contare();; // calcola $ count_meetings_planning $ hd-> count_meetings_planning = Meeting :: find () -> where ('stato<'.Meeting::STATUS_COMPLETED)->andwhere ( 'created_at<'.$since)->contare();; // calcola $ count_places $ hd-> count_places = Place :: find () -> where ('created_at>'. $ after) -> andWhere ('created_at<'.$since)->contare();

Accesso ai dati

Dopo aver interrogato i dati, ad esempio un singolo modello, è facile accedere ai dati come oggetto modello:

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

Elabora spesso array in questo modo:

$ users = User :: findAll (); foreach ($ utenti come $ u) $ id = $ u-> id; $ email = $ u-> email;

Assegnazione massiccia

È inoltre possibile assegnare rapidamente un array a un record del modello tramite ActiveRecord:

$ values ​​= ['name' => 'James', 'email' => '[email protected]',]; $ cliente = nuovo cliente (); $ cliente-> attributi = $ valori; $ Customer> save ();

Questo è spesso usato per popolare i dati del modello dopo l'invio di un modulo:

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

O puoi usare -> Load () per questo:

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

Il generatore di codici di scaffalatura Gii di Yii è ottimo per generare modelli che utilizzano ActiveRecord e che fanno molto per te, ad es. modelli, controllori, moduli, viste, ecc.

Salvataggio dei dati

Come puoi vedere sopra, anche il salvataggio dei dati con Active Record è facile. In questo esempio della documentazione Yii, un nuovo record viene creato e salvato, quindi un record viene caricato dall'ID e gli aggiornamenti vengono salvati:

// inserisce una nuova riga di dati $ customer = new Customer (); $ cliente-> nome = 'James'; $ cliente-> email = '[email protected]'; $ Customer> save (); // aggiorna una riga di dati esistente $ customer = Customer :: findOne (123); $ cliente-> email = '[email protected]'; $ Customer> save ();

Eliminazione di record

Cancellare un record è ancora più semplice:

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

Aggiornamento dei contatori

Yii offre anche facili incrementi del contatore. Supponiamo che un utente pianifichi un altro incontro e che tenga traccia di quanti nella tabella utente:

$ u = Utente :: findOne (99); $ U-> updateCounters ([ 'meeting_count' => 1]); // equivalente a // UPDATE 'User' SET 'meeting_count' = 'meeting_count' + 1 WHERE 'id' = 99 

Relazioni

La connessione delle tabelle tra gli indici è una delle funzionalità più potenti di Active Record. Ad esempio, in Meeting Planner, ciascuna riunione può avere 0 o più MeetingPlaces. Il modello Meeting.php definisce ActiveQuery relazionale per questo:

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

Quindi, posso accedere a tutti i luoghi di una riunione con il $ meetingPlaces proprietà. Sotto, carico una riunione e iteriamo su tutte le sue meetingPlaces abbastanza facilmente come se fosse un array integrato di sottooggetti:

$ MTG = Meeting :: find () -> dove ([ 'id' => $ meeting_id]) -> uno (); foreach ($ mtg-> meetingPlaces as $ mp) ...

Naturalmente, questo si basa sulla creazione di una chiave esterna quando si crea la tabella nella sua migrazione:

$ this-> createTable ('% meeting_place', ['id' => Schema :: TYPE_PK, 'meeting_id' => Schema :: TYPE_INTEGER. 'NOT NULL', 'place_id' => Schema :: TYPE_INTEGER . 'NOT NULL', 'suggested_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'); 

Qual'è il prossimo

Spero che questo abbia fornito una facile introduzione ad alcune delle meraviglie di Active Record. Include anche Cicli di vita, Transazioni e Blocco, di cui potrei scrivere in futuro. Se vuoi fare un salto avanti, Yii2 offre due grandi aree per imparare di più nella sua documentazione: Yii2 Guida alle specifiche funzionali di Active Record e Yii2 Active Record. Queste sono introduzioni ben scritte.

Guarda le prossime esercitazioni nella serie Programming with Yii2 mentre continuiamo a esplorare i diversi aspetti del framework. Si consiglia inoltre di controllare la già citata Creazione di avvio con serie PHP.

Se vuoi sapere quando arriverà il prossimo tutorial di Yii2, seguimi @reifman su Twitter o controlla la mia pagina di istruttore. 

Link correlati

  • Come programmare con Yii2: lavorare con il database e il record attivo (Envato Tuts +)
  • Yii2 Guida al registro attivo
  • Specifica funzionale Yii2 Active Record
  • Active Record Pattern (Wikipedia)
  • Yii2 Developer Exchange, il mio sito di risorse Yii2