Doctrine ORM e Laravel 5

Come sviluppatore PHP, potresti aver trovato il termine ORM. ORM è un modo per lavorare con i database nello stesso modo in cui si lavora con classi e oggetti. Se dovessi approfondire il modo in cui le applicazioni web sono progettate e costruite, dopo aver esplorato il loro ORM, troverai due modelli ben noti: Record attivo e Data Mapper.

Active Record fa riferimento al mapping di un oggetto a una riga del database. In effetti, ogni riga nel database è legata a un oggetto. Quando recuperi una riga dal database puoi aggiornare, eliminare o salvare usando l'oggetto stesso. È così che lavorano Eloquent e Parigi, e come è fatto in Ruby on Rails.

D'altro canto, Data Mapper è un livello di software che separa gli oggetti in memoria dal database. Con Data Mapper gli oggetti in memoria non devono sapere che è presente anche un database. Non hanno bisogno di codice di interfaccia SQL o conoscenza dello schema del database. Una di queste soluzioni è Doctrine.

Cos'è Dottrina?

Doctrine è un ORM che implementa il pattern del mapper dei dati e consente di separare in modo pulito le regole di business dell'applicazione dal livello di persistenza del database.

Alcuni dei vantaggi che ho scoperto durante l'utilizzo di Doctrine con Laravel sono:

  • Più veloce e più facile da usare.
  • Le entità sono semplici oggetti PHP.
  • Doctrine utilizza un approccio "code first", quindi è possibile creare prima le entità e quindi generare automaticamente un database. Il caso inverso è anche possibile, ma io non lo consiglio.
  • Supporta annotazioni, XML e YAML per lo schema.
  • DQL (una sostituzione per SQL) astrae i tuoi tavoli.
  • Dottrina eventi consentono di agganciare facilmente eventi di database specifici ed eseguire determinate azioni.
  • I repository sono più fedeli al modello di repository.
  • Transactional write-behind la metodologia consente a Doctrine di interagire meno con il database fino al flush () il metodo è chiamato.

Ovviamente, Doctrine ha anche degli svantaggi, ma spetta al programmatore scegliere l'ORM corretto.

Doctrine DQL

DQL sta per Doctrine Query Language. DQL ti porta il linguaggio di query oggetto, il che significa che al posto di una query relazionale tradizionale hai query in forma di oggetto.

DQL consente di scrivere query di database in modo orientato agli oggetti, utile quando è necessario interrogare il database in un modo che non può essere raggiunto (o è molto difficile) utilizzando i metodi di repository predefiniti.

Esempio di query DQL:

sql SELECT b.id come ItemId, b.title come ItemTitle, b.url come ItemUrl FROM Alireza \ Domain \ Identity \ Entities \ Menu u WHERE u.id =: id

Filtri di Doctrine

Doctrine consente di limitare i risultati della query con i filtri. Ad esempio, è possibile modificare solo le informazioni dell'utente connesso o assicurarsi che i dati del client corrente siano stati restituiti dal database. Un filtro è una soluzione automatica per ricordare condizioni specifiche per tutte le tue domande.

Doctrine fornisce limitazioni a livello SQL, quindi non è necessario mantenere la clausola in più repository del progetto. Ciò aumenta la sicurezza e rende il tuo codice più facile da leggere.

Diamo un'occhiata a un esempio:

php / ** * @ManyToOne (targetEntity = "User") * @JoinColumn (name = "user_id", referencedColumnName = "id") ** / private $ user; Come puoi vedere nell'entità Utente, il risultato di JoinColumn è limitato ai soli articoli con le condizioni di WHERE user_id =: user_id.

Impostazione di Doctrine 2

Per configurare Doctrine, è disponibile un bridge per consentire la corrispondenza con la configurazione esistente di Laravel 5. Per installare Doctrine 2 nel nostro progetto Laravel, eseguiamo il seguente comando:

il compositore di bash richiede laravel-doctrine / orm

Come al solito, il pacchetto dovrebbe essere aggiunto al app / config.php, come fornitore di servizi:

php LaravelDoctrine \ ORM \ DoctrineServiceProvider :: class,

Anche l'alias deve essere configurato:

php 'EntityManager' => LaravelDoctrine \ ORM \ Facades \ EntityManager :: class

Infine, pubblichiamo la configurazione del pacchetto con:

fornitore bash php artisan: pubblicare --tag = "config"

Doctrine non ha bisogno di configurazione del database e usa la configurazione corrente di Laravel, ma se si vuole sovrascriverlo, si dovrebbe cambiare il file di configurazione di Doctrine in Config / doctrine.php:

"php 'managers' => ['default' => ['dev' => env ('APP_DEBUG'), 'meta' => env ('DOCTRINE_METADATA', 'annotazioni'), 'connessione' => env (' DB_CONNECTION ',' mysql '),' namespaces '=> [' App '],

"Questo è tutto ciò che c'è da fare.

Cos'è un'entità?

"Entità" si riferisce a un oggetto che ha un'identità distinta. Un'entità deve avere un identificatore specifico che è unico nell'intero sistema, come un cliente o uno studente. Ci sarebbero altri oggetti, come gli indirizzi email, che non sono entità, ma oggetti valore.

Creiamo una Post Entity App / Entità / post.php:

"php namespace App \ Entity;

usa Doctrine \ ORM \ Mapping come ORM;

/ ** * @ORM \ Entity * @ORM \ Table (name = "posts") * @ORM \ HasLifecycleCallbacks () * / class Post / ** * @var intero $ id * @ORM \ Column (name = " id ", type =" intero ", unique = true, nullable = false) * @ORM \ Id * @ORM \ GeneratedValue (strategy =" AUTO ") * * / private $ id;

/ ** * @ORM \ Column (type = "string") * / private $ title; / ** * @ORM \ Column (type = "text") * / private $ body; funzione pubblica __construct ($ input) $ this-> setTitle ($ input ['title']); $ This-> setBody ($ input [ 'corpo']);  public function getId () return $ this-> id;  public function getTitle () return $ this-> title;  public function setTitle ($ title) $ this-> title = $ title;  funzione pubblica getBody () return $ this-> body;  funzione pubblica setBody ($ body) $ this-> body = $ body;  "

Le proprietà della classe devono essere uguali ai campi nella tabella del database, oppure è possibile definirli con il @Colum ( "nome" = "myfield") annotazione.

Cos'è un repository?

Il repository consente a tutto il codice di utilizzare oggetti senza dover sapere come vengono mantenuti gli oggetti. Il repository contiene tutta la conoscenza della persistenza, inclusa la mappatura dalle tabelle agli oggetti. Ciò fornisce una vista più orientata agli oggetti del livello di persistenza e rende il codice di mappatura più incapsulato.

Ora è il momento di creare il deposito nel App / Repository / PostRepo.php:

"php namespace App \ Repository; usa App \ Entity \ Post; usa Doctrine \ ORM \ EntityManager;

classe PostRepo

/ ** * @var string * / private $ class = 'App \ Entity \ Post'; / ** * @var EntityManager * / private $ em; funzione pubblica __construct (EntityManager $ em) $ this-> em = $ em;  funzione pubblica create (post $ post) $ this-> em-> persist ($ post); $ This-> em-> flush ();  aggiornamento della funzione pubblica (post $ post, $ data) $ post-> setTitle ($ data ['title']); $ Post-> setBody ($ dati [ 'corpo']); $ This-> em-> persistono ($ post); $ This-> em-> flush ();  public function PostOfId ($ id) return $ this-> em-> getRepository ($ this-> class) -> findOneBy (['id' => $ id]);  public function delete (Post $ post) $ this-> em-> remove ($ post); $ This-> em-> flush ();  / ** * creare Post * @return Post * / private function prepareData ($ data) return new Post ($ data);  

"

La dottrina EntityManager funziona come punto di accesso per la completa gestione delle tue entità. Quindi, crea il controller App / HTTP / Controller / PostController.php:

"php namespace App \ Http \ Controllers; usa App \ Repository \ PostRepo come repo; usa App \ Validation \ PostValidator;

classe PostController estende Controller private $ repo;

funzione pubblica __construct (repo $ repo) $ this-> repo = $ repo;  edit funzione pubblica ($ id = NULL) return View ('admin.index') -> with (['data' => $ this-> repo-> postOfId ($ id)]);  public function editPost () $ all = Input :: all (); $ validate = PostValidator :: validate ($ all); if (! $ validate-> passes ()) return redirect () -> back () -> withInput () -> withErrors ($ validate);  $ Id = $ this-> repo-> postOfId ($ all ['id']); se (! is_null ($ Id)) $ this-> repo-> update ($ Id, $ all); Session :: flash ('msg', 'edit success');  else $ this-> repo-> create ($ this-> repo-> perpare_data ($ all)); Session :: flash ('msg', 'aggiungi successo');  return redirect () -> back ();  public function retrieve () return View ('admin.index') -> with (['Data' => $ this-> repo-> retrieve ()]);  public function delete () $ id = Input :: get ('id'); $ data = $ this-> repo-> postOfId ($ id); se (! is_null ($ data)) $ this-> repo-> delete ($ data); Session :: flash ('msg', 'operazione Success'); return redirect () -> back ();  else return redirect () -> back () -> withErrors ('operationFails');  "La visualizzazione e il routing sono gli stessi del solito. 

Preferisco creare il mio Validator basato sulla classe Validator di Laravel. Ecco il Validator App \ convalida \ PostValidator.php:

"App dello spazio dei nomi PHP \ Convalida; usa Validatore;

class PostValidator funzione statica pubblica validate ($ input) $ rules = ['title' => 'Required | Min: 4 | Max: 80 | alpha_spaces', 'body' => 'Required',]; return Validator :: make ($ input, $ rules); "

Conclusione

Se non hai precedentemente lavorato con Doctrine 2, spero che questo articolo sia stato interessante e informativo. Laravel 5 non usa Doctrine, ma come puoi vedere, ci sono alcuni pacchetti che ci permettono di usarlo facilmente con Laravel. Ho creato una semplice app per blog con Laravel 5 e Doctrine ORM, e spero che questo possa aiutarti a creare l'app desiderata. Accolgo con favore i tuoi commenti.