[Part 3] - The Blog Model: Using Doctrine 2 and Data Fixtures¶
Overview¶
Questo capitolo inizierà esplorando il modello blog. Il modello sarà implementato usando Doctrine 2 Object Relation Mapper (ORM). Doctrine 2 ci fornisce la persistenza per i nostri oggetti PHP. Fornisce inoltre un linguaggio SQL proprietario chiamato Query Language Doctrine (DQL). Oltre a Doctrine 2, sarà introdotto anche il concetto di Fixtures dati. Questo è un meccanismo per popolare il nostro database di prova nello sviluppo con dati di test adeguati. Alla fine di questo capitolo avrete definito il modello blog, aggiornato il database per riflettere il nuovo modello, e creato un insieme di dati. Avrete anche costruito le basi della pagina di blog show.
Doctrine 2: The Model¶
Per far funzionare il nostro blog abbiamo bisogno di un modo per rendere persistenti i dati. Doctrine 2 fornisce una libreria ORM progettata esattamente per questo scopo.Database Abstraction Layer ci dà l'astrazione di archiviazione tramite la DOP PHP. Questo ci permette di utilizzare un numero di storage engine diversi tra cui MySQL, PostgreSQL e SQLite. Useremo MySQL per il nostro motore di archiviazione, ma qualsiasi altro motore potrebbe essere facilmente usato..
Nota
Se non si ha familiarità con ORM, spiegheremo il principio di base . Nella definizione di Wikipedia si legge:
"Object-relational mapping (ORM, O / RM, e O / R mapping) in software per computer è una tecnica di programmazione per la conversione dei dati tra sistemi di tipo incompatibili in linguaggi orientati agli oggetti di programmazione. Ciò crea, in effetti, un "database oggetto virtuale" che può essere usato all'interno del linguaggio di programmazione ".
Ciò che fa l'ORM facilita il lavoro traducendo i dati da un database relazionale come MySQL PHP in oggetti che possiamo manipolare. Questo ci permette di incapsulare le funzionalità di una tabella all'interno di una classe. Pensate a una tabella utente, probabilmente ha campi come nome utente, password, first_name, cognome, email e nato. Con un ORM questo diventa una classe con membri username, password, first_name, ecc, che ci permette di chiamare metodi quali getUsername () e setPassword () . ORM vanno ben oltre questo, però, sono anche in grado di recuperare tabelle correlate , sia allo stesso tempo, come noi recuperiamo l'oggetto utente, o altrimenti in seguito. Ora consideriamo il nostro utente ha alcuni amici ad esso collegati. Questo sarebbe una tabella amici, memorizzare la chiave primaria della tabella utente all'interno di esso. Utilizzando l' ORM ora potremmo effettuare una chiamata come $ user-> getFriends () per recuperare gli oggetti della tabella amici. Se questo non bastasse, l'ORM si occupa anche della persistenza in modo da poter creare oggetti in PHP, chiamare un metodo come save () e lasciare che l' ORM con i dettagli effettivamente persista i dati nel database. Qui useremo la libreria di Doctrine 2 ORM, si avrà molto più familiarità con ciò che è un ORM nell'andare avanti in questo tutorial.
Nota
Tu potresti optare per usare Doctrine 2 Object Document Mapper (ODM) library. Ci sono un certo numero di varianti in questa biblioteca per implementazioni di MongoDB e CouchDB . Vedere la pagina Doctrine Projects per ulteriori informazioni.
C'è anche cookbook che spiega come impostare un ODM con Symfony2.
L'Entità Blog ¶
Inizieremo con la creazione della classe Blog con le sue entità . Abbiamo già introdotto le entità nel capitolo precedente, quando abbiamo creato l'entità per Enquiry. Poiché lo scopo di un'entità è di contenere i dati, ha perfettamente senso usarne una per rappresentare una voce di blog. Con la definizione di un'entità non stiamo introducendo automaticamente i dati nel database ma come saranno mappati . Lo abbiamo visto con la nostra Enquiry entità, laddove i dati contenuti nel entità servivono appena per inviarli al webmaster.
Creare un nuovo file si in src / Blogger / BlogBundle / Entity / Blog.php e incollare il seguente codice .
<?php
// src/Blogger/BlogBundle/Entity/Blog.php
namespace Blogger\BlogBundle\Entity;
class Blog
{
protected $title;
protected $author;
protected $blog;
protected $image;
protected $tags;
protected $comments;
protected $created;
protected $updated;
}
Come potete vedere questa è una classe PHP semplice. Non si estende a nessun parent. Ciascuno degli elementi è dichiarato come protetto in modo che siamo in grado di accedervi quando si opera su un oggetto di questa classe. Potremmo dichiarare i getter e setter per questi attributi, ma Doctrine 2 fornisce un task per fare questo. Dopo tutto, la scrittura di accesso non è il più esaltante dei compiti di codifica.
Prima di poter eseguire questo compito, è necessario informare Doctrine 2 di come le entità della classe Blog dovrebbero essere mappate al database. L'informazione viene specificata con metadati utilizzando Doctrine 2 mappature. I metadati possono essere specificati in diversi formati, tra cui YAML , PHP , XML e annotazioni . Useremo Annotazioni in questo tutorial. E 'importante notare che non tutti i membri in seno al soggetto devono essere mantenuti, in modo da non fornire metadati per questi. Questo ci dà la flessibilità di scegliere solo i membri che abbiamo bisogno con Doctrine 2 per mapparli al database. Sostituire il contenuto della classe Blog in src / Blogger / BlogBundle / Entity / Blog.php con il seguente.
<?php
// src/Blogger/BlogBundle/Entity/Blog.php
namespace Blogger\BlogBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="blog")
*/
class Blog
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $title;
/**
* @ORM\Column(type="string", length=100)
*/
protected $author;
/**
* @ORM\Column(type="text")
*/
protected $blog;
/**
* @ORM\Column(type="string", length="20")
*/
protected $image;
/**
* @ORM\Column(type="text")
*/
protected $tags;
protected $comments;
/**
* @ORM\Column(type="datetime")
*/
protected $created;
/**
* @ORM\Column(type="datetime")
*/
protected $updated;
}
Per prima cosa importiamo il namespace di ORM Doctrine 2 Mapping . Questo ci permette di utilizzare le annotazioni per descrivere i metadati per l'entità. I metadati forniscono informazioni su come i membri dovrebbero essere mappato al database.
Nota
Abbiamo usato solo un piccolo sottoinsieme dei tipi previsti per la mappatura di Doctrine 2. Un elenco completo dei tipi di mappatura si possono trovare sul sito web Doctrine 2. Altri tipi di mappature saranno introdotte più avanti nel tutorial.
L'occhio attento di voi avrà notato che il membro $ comments non ha metadati allegati. Questo perché non abbiamo bisogno che questo persista, si limita a fornire una serie di commenti relativi a un post sul blog. Se pensate a questo senza pensare al database ha senso. I frammenti di codice seguenti lo dimostrano.
// Create a blog object.
$blog = new Blog();
$blog->setTitle("symblog - A Symfony2 Tutorial");
$blog->setAuthor("dsyph3r");
$blog->setBlog("symblog is a fully featured blogging website ...");
// Create a comment and add it to our blog
$comment = new Comment();
$comment->setComment("Symfony2 rocks!");
$blog->addComment($comment);
Il frammento di cui sopra dimostra il comportamento normale che si vuole da una classe blog e di comment. Internamente il metodo $ blog-> addComment () potrebbe essere implementato come segue.
class Blog
{
protected $comments = array();
public function addComment(Comment $comment)
{
$this->comments[] = $comment;
}
}
Il metodo addComment aggiunge solo un nuovo oggetto di commento al membro $ comments del blog .Il recupero dei commenti sarà semplice
class Blog
{
protected $comments = array();
public function getComments()
{
return $this->comments;
}
}
Come si può vedere il membro $ comments è solo un elenco di oggetti commentsi.Doctrine 2 non cambia come funziona. sarà in grado di popolare automaticamente questo membro $ comments con gli oggetti legati al blog oggetto.
Ora che abbiamo detto a Doctrine 2 come mappare i membri entità, siamo in grado di generare i metodi di accesso utilizzando il seguente task
$ php app/console doctrine:generate:entities Blogger
Si noterà che il file Blog Entity è stato aggiornato con i metodi di accesso. Ogni volta che facciamo un cambiamento ai metadati ORM per le nostre classi di entità siamo in grado di eseguire questo task per generare qualsiasi metodo aggiuntivo. Questo comando non apporta modifiche di accesso a quelle già esistente, in modo che i metodi di accesso esistenti non saranno mai modificati da questo comando. Questo è importante perché si può personalizzare in seguito alcune delle funzioni di accesso predefinite.
Nota
Anche se abbiamo usato le annotazioni nel nostro tutorial , è possibile convertire le informazioni di mapping in altri formati supportati utilizzando la mappatura doctrine:mapping:convert task. Per esempio il seguente task convertirà la mappatura in formato yaml..
$ php app/console doctrine:mapping:convert --namespace="Blogger\BlogBundle\Entity\Blog" yaml src/Blogger/BlogBundle/Resources/config/doctrine
Questo creerà un file in src / Blogger / BlogBundle / Resources / config / doctrine / Blogger.BlogBundle.Entity.Blog.orm.yml che conterrà le entità blog mappate in formato YAML.
Il database ¶
Creazione del database ¶
Se avete seguito il tutorial dal capitolo 1 , avresei dovuto utilizzare il configuratore web per impostare le impostazioni del database. Se no, lo avete fatto aggiornate leopzioni del database_ * l file dei parametri in app / config / parameters.ini .
E quindi il momento di creare il database utilizzando un altro task Doctrine 2. Questo task crea solo il database, non crea tutte le tabelle all'interno del database. Se un database con lo stesso nome esiste già l'operazione genererà un errore e il database esistente verrà lasciato intatto.
$ php app/console doctrine:database:create
Siamo ora pronti per creare la rappresentazione delle entità Blog nel database. Ci sono 2 modi che possiamo utilizzare per questo obiettivo. Possiamo usare il task Doctrine 2 schema per aggiornare il database oppure possiamo usare il task doctrine 2 migrazioni. Per ora useremo il task schema. Migrazioni Doctrine sarà introdotto nel capitolo seguente.
Creazione della tabella di blog ¶
Per creare la tabella blog nel nostra database possiamo i eseguire il task seguente.
$ php app/console doctrine:schema:create
Questo modo può eseguire il codice SQL necessario per generare lo schema del database per le entità blog. È inoltre possibile passare l'opzione dump-sql per estrarre la SQL. Se si visualizza il database si vede che la tabella blog è stata creata, con i campi che abbiamo impostato con le informazioni per la mappatura.
Nota
Abbiamo usato un certo numero di task di Symfony2 da riga di comando specificando l'opzione help per il singolo task si può avere un ulteriore chiarimento per esempio per doctrine:schema:create
$ php app/console doctrine:schema:create --help
Le informazioni di aiuto di uscita mostrerà l'utilizzo, e le opzioni disponibili. La maggior parte delle attività sono dotate di una serie di opzioni che possono essere impostate per personalizzare il funzionamento del task.
Integrare il modello con la vista. Visualizzazione di un blog ¶
Ora abbiamo l' entità Blog creata, e il database aggiornato per riflettere questo, possiamo iniziare a integrare il modello nella vista. Inizieremo con la costruzione della pagina Show del nostro blog.
The Show Blog Route¶
Iniziamo con la creazione di un percorso per l'azione show blog. Un blog sarà identificato dal suo ID univoco, quindi questo ID dovrà essere presente nella URL. Aggiornare il file delle rotte per BloggerBlogBundle in src / Blogger / BlogBundle / resources / config / routing.yml con la seguente
# src/Blogger/BlogBundle/Resources/config/routing.yml
BloggerBlogBundle_blog_show:
pattern: /{id}
defaults: { _controller: BloggerBlogBundle:Blog:show }
requirements:
_method: GET
id: \d+
L' ID del blog deve essere presente nell'URL, abbiamo specificato un id segnaposto. Questo significa che gli URL come http://symblog.co.uk/1 e http://symblog.co.uk/my-blog corrisponderanno . Tuttavia, sappiamo che la ID blog deve essere un numero intero (è definito in questo modo nel mapping entità) in modo che possiamo aggiungere un vincolo che specifica che questo percorso corrisponde solo quando l' id parametro contiene un numero intero. Ciò si ottiene con l'id: \d+ come requisito per il percorso. Ora solo l'esempio del primo URL corrisponderebbe, http://symblog.co.uk/my-blog non corrisponderà più a questo percorso.È anche possibile vedere una route corrispondente che eseguirà la show action del controller BloggerBlogBundle Blog. Questo controller è ancora da creare
The Show Controller Action¶
L'unione tra il modello e la vista è il controller, quindi questo è dove inizierà la creazione della pagina show. Potremmo aggiungere una nuova show action per la nostra attuale pagina di controllo, ma questa pagina si occupa di mostrare l'entità blog sarà quindi più adatto collocarla nel proprio Blog controller.
Creare un nuovo file in src / Blogger / BlogBundle / Controller / BlogController.php e incollare il seguente.
<?php
// src/Blogger/BlogBundle/Controller/BlogController.php
namespace Blogger\BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
/**
* Blog controller.
*/
class BlogController extends Controller
{
/**
* Show a blog entry
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getEntityManager();
$blog = $em->getRepository('BloggerBlogBundle:Blog')->find($id);
if (!$blog) {
throw $this->createNotFoundException('Unable to find Blog post.');
}
return $this->render('BloggerBlogBundle:Blog:show.html.twig', array(
'blog' => $blog,
));
}
}
Abbiamo creato un nuovo controller per l'entità Blog e definito la show action. Siccome abbiamo specificato un parametro id nel BloggerBlogBundle_blog_show con la regola di routing, questa verrà passata come argomento al metodo showAction. Se avessimo specificato altri parametri nella regola di routing, anche questi dovrebbero essere passati come argomenti separati.
Nota
Nell'azionedel controller si possono passare anche oggetti di Symfony\Component\HttpFoundation\Request Se tu specifichi questo come parametro . Questo può essere utile quando si tratta di form. Abbiamo già usato un form nel capitolo 2, ma non abbiamo usato questo metodo abbiamo utilizzato un metodo helper di Symfony \ Bundle \ \ Controller \ FrameworkBundle controller come segue.
// src/Blogger/BlogBundle/Controller/PageController.php
public function contactAction()
{
// ..
$request = $this->getRequest();
}
Avremmo potuto invece aver scritto questo come segue.
// src/Blogger/BlogBundle/Controller/PageController.php
use Symfony\Component\HttpFoundation\Request;
public function contactAction(Request $request)
{
// ..
}
Entrambi i metodi consentono di raggiungere lo stesso scopo. Se il controller non ha esteso la classe Symfony \ Bundle \ FrameworkBundle \ Controller \ controller l'helper non sarebbe in grado di funzionare.
Poi abbiamo bisogno di recuperare l'entità Blog dal database. Per prima cosa utilizzeremo un altro metodo di supporto della classe Symfony \ Bundle \ FrameworkBundle \ Controller \ controller per ottenere the Doctrine2 Entity Manager.Il lavoro del manager Entity è quello di gestire il recupero e la persistenza di oggetti da e verso il database.. Andiamo quindi ad utilizzare l'oggetto EntityManager per ottenere un Doctrine2 Repository per BloggerBlogBundle: Blog entità. La sintassi indicata qui è semplicemente una scorciatoia che può essere utilizzato con Doctrine 2 invece di specificare il nome completo dell'entità, cioè Blogger \ BlogBundle \ Entity \ Blog . Con l'oggetto repository chiamiamo find () passando il metodo $ id argomento. Questo metodo consente di recuperare l'oggetto con la sua chiave primaria.
Infine si controlla che l'entità è stata trovata, e passiamo questa entità verso la vista. Se nessun entità è stato trovato un createNotFoundException viene generata. Questo alla fine genera una risposta 404 Not Trovato.
Nota
L'oggetto repository consente di accedere a una serie di metodi di supporto utili compresi
// Return entities where 'author' matches 'dsyph3r'
$em->getRepository('BloggerBlogBundle:Blog')->findBy(array('author' => 'dsyph3r'));
// Return one entity where 'slug' matches 'symblog-tutorial'
$em->getRepository('BloggerBlogBundle:Blog')->findOneBySlug('symblog-tutorial');
Creeremo le nostre classi repository personalizzate nel prossimo capitolo, quando abbiamo bisogno di query più complesse.
The View¶
Ora abbiamo costruito la show action per il Blog controller possiamo concentrarsi su come visualizzare le entità Blog . Come specificato nella show action di rendere il template BloggerBlogBundle:Blog:show.html.twig Andiamo a creare questo template in src/Blogger/BlogBundle/Resouces/views/Blog/show.html.twig incolliamo il seguente codice..
{# src/Blogger/BlogBundle/Resouces/views/Blog/show.html.twig #}
{% extends 'BloggerBlogBundle::layout.html.twig' %}
{% block title %}{{ blog.title }}{% endblock %}
{% block body %}
<article class="blog">
<header>
<div class="date"><time datetime="{{ blog.created|date('c') }}">{{ blog.created|date('l, F j, Y') }}</time></div>
<h2>{{ blog.title }}</h2>
</header>
<img src="{{ asset(['images/', blog.image]|join) }}" alt="{{ blog.title }} image not found" class="large" />
<div>
<p>{{ blog.blog }}</p>
</div>
</article>
{% endblock %}
Per prima cosa andiamo ad estendere il layout principale in BloggerBlogBundle. Poi sovrascriviamo il titolo della pagina con il titolo del blog. Questo sarà utile per il SEO, il titolo della pagina del blog è più descrittivo è il titolo predefinito che viene impostato. Infine abbiamo l'override del blocco body per l'uscita delle entità Blog. E usiamo il metodo asset per il rendering dell'immagine blog. Le immagini del blog devono essere messe nella cartella web / images.
CSS¶
Andiamo ad aggiungere un po 'styling. Aggiornare il foglio di stile in src / Blogger / BlogBundle / Resouces / public / css / blog.css con il seguente.
.date { margin-bottom: 20px; border-bottom: 1px solid #ccc; font-size: 24px; color: #666; line-height: 30px }
.blog { margin-bottom: 20px; }
.blog img { width: 190px; float: left; padding: 5px; border: 1px solid #ccc; margin: 0 10px 10px 0; }
.blog .meta { clear: left; margin-bottom: 20px; }
.blog .snippet p.continue { margin-bottom: 0; text-align: right; }
.blog .meta { font-style: italic; font-size: 12px; color: #666; }
.blog .meta p { margin-bottom: 5px; line-height: 1.2em; }
.blog img.large { width: 300px; min-height: 165px; }
Nota
Nota
Se non si utilizza il metodo di collegamento simbolico per fare riferimento alle attività della cartella web/bundle è necessario eseguire nuovamente l'installazione con il task asset per copiare le modifiche apportate al CSS
$ php app/console assets:install web
noi abbiamo costruito il controller e la view per show actions andiamo a controllare la show page. Punta il tuo browser a http://symblog.dev/app_dev.php/1. Non è la pagina che ti aspettavi?

Symfony2 ha generato una risposta 404 Not Found . Questo perchè noi non abbiamo nessun dato nel database, nessuna entità con id uguale a d 1 è stata trovata..
Tu potresti semplicemente inserire una riga nella tua tabella del database, ma noi andremo ad utilizzare un metodo migliore; Data Fixtures.
Data Fixtures¶
Possiamo utilizzare fixtures per popolare il database con semplici test/dati.Andremo ad utilizzare il bundle Doctrine Fixtures extension . Il bundle Doctrine Fixtures extension non viene con la Symfony2 Standard Distribution, abbiamo bisogno di installarlo manualmente.Fortunatamente c'è un task per questo .Aprimao il file deps localizzato nella root del progetto e aggiungiamo il bundle Doctrine fixtures extension cosi come segue..
[doctrine-fixtures]
git=http://github.com/doctrine/data-fixtures.git
[DoctrineFixturesBundle]
git=http://github.com/symfony/DoctrineFixturesBundle.git
target=/bundles/Symfony/Bundle/DoctrineFixturesBundle
Quindi lanciamo il task vendor install.
$ php bin/vendors install
Questo scaricherà ogni ultima versione dei bundle nel repositories di Github e l'installerà nella posizione desiderata..
Nota
Questo per chi non ha git installato nella propria macchina. .
Download doctrine-fixtures extension: da GitHub ed estrai il file nella seguente cartella vendor/doctrine-fixtures.
Download DoctrineFixturesBundle da GitHub e estrai i file nella seguente cartella vendor/bundles/Symfony/Bundle/DoctrineFixturesBundle.
Dopo di che aggiorna il file app/autoloader.php per registrare il nuovo namespace. Siccome i DataFixtures sono anche in Doctrine\Common namespace essi devono essere specificati anche in questa directory Doctrine\Common .I Namespaces sono controllati dall'alto al basso cosi specifici namespace devono essere registrati prima di altri..
// app/autoloader.php
// ...
$loader->registerNamespaces(array(
// ...
'Doctrine\\Common\\DataFixtures' => __DIR__.'/../vendor/doctrine-fixtures/lib',
'Doctrine\\Common' => __DIR__.'/../vendor/doctrine-common/lib',
// ...
));
Ora andiamo a registrare DoctrineFixturesBundle nella kernel localizzata in app/AppKernel.php
// app/AppKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new Symfony\Bundle\DoctrineFixturesBundle\DoctrineFixturesBundle(),
// ...
);
// ...
}
Blog Fixtures¶
Ora siamo pronti per definire alcune fixtures per il nostro blogs. Create il file delle fixture in src/Blogger/BlogBundle/DataFixtures/ORM/BlogFixtures.php aggiungete il seguente contenuto.:
<?php
// src/Blogger/BlogBundle/DataFixtures/ORM/BlogFixtures.php
namespace Blogger\BlogBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Blogger\BlogBundle\Entity\Blog;
class BlogFixtures implements FixtureInterface
{
public function load(ObjectManager $manager)
{
$blog1 = new Blog();
$blog1->setTitle('A day with Symfony2');
$blog1->setBlog('Lorem ipsum dolor sit amet, consectetur adipiscing eletra electrify denim vel ports.\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ut velocity magna. Etiam vehicula nunc non leo hendrerit commodo. Vestibulum vulputate mauris eget erat congue dapibus imperdiet justo scelerisque. Nulla consectetur tempus nisl vitae viverra. Cras el mauris eget erat congue dapibus imperdiet justo scelerisque. Nulla consectetur tempus nisl vitae viverra. Cras elementum molestie vestibulum. Morbi id quam nisl. Praesent hendrerit, orci sed elementum lobortis, justo mauris lacinia libero, non facilisis purus ipsum non mi. Aliquam sollicitudin, augue id vestibulum iaculis, sem lectus convallis nunc, vel scelerisque lorem tortor ac nunc. Donec pharetra eleifend enim vel porta.');
$blog1->setImage('beach.jpg');
$blog1->setAuthor('dsyph3r');
$blog1->setTags('symfony2, php, paradise, symblog');
$blog1->setCreated(new \DateTime());
$blog1->setUpdated($blog1->getCreated());
$manager->persist($blog1);
$blog2 = new Blog();
$blog2->setTitle('The pool on the roof must have a leak');
$blog2->setBlog('Vestibulum vulputate mauris eget erat congue dapibus imperdiet justo scelerisque. Na. Cras elementum molestie vestibulum. Morbi id quam nisl. Praesent hendrerit, orci sed elementum lobortis.');
$blog2->setImage('pool_leak.jpg');
$blog2->setAuthor('Zero Cool');
$blog2->setTags('pool, leaky, hacked, movie, hacking, symblog');
$blog2->setCreated(new \DateTime("2011-07-23 06:12:33"));
$blog2->setUpdated($blog2->getCreated());
$manager->persist($blog2);
$blog3 = new Blog();
$blog3->setTitle('Misdirection. What the eyes see and the ears hear, the mind believes');
$blog3->setBlog('Lorem ipsumvehicula nunc non leo hendrerit commodo. Vestibulum vulputate mauris eget erat congue dapibus imperdiet justo scelerisque.');
$blog3->setImage('misdirection.jpg');
$blog3->setAuthor('Gabriel');
$blog3->setTags('misdirection, magic, movie, hacking, symblog');
$blog3->setCreated(new \DateTime("2011-07-16 16:14:06"));
$blog3->setUpdated($blog3->getCreated());
$manager->persist($blog3);
$blog4 = new Blog();
$blog4->setTitle('The grid - A digital frontier');
$blog4->setBlog('Lorem commodo. Vestibulum vulputate mauris eget erat congue dapibus imperdiet justo scelerisque. Nulla consectetur tempus nisl vitae viverra.');
$blog4->setImage('the_grid.jpg');
$blog4->setAuthor('Kevin Flynn');
$blog4->setTags('grid, daftpunk, movie, symblog');
$blog4->setCreated(new \DateTime("2011-06-02 18:54:12"));
$blog4->setUpdated($blog4->getCreated());
$manager->persist($blog4);
$blog5 = new Blog();
$blog5->setTitle('You\'re either a one or a zero. Alive or dead');
$blog5->setBlog('Lorem ipsum dolor sit amet, consectetur adipiscing elittibulum vulputate mauris eget erat congue dapibus imperdiet justo scelerisque.');
$blog5->setImage('one_or_zero.jpg');
$blog5->setAuthor('Gary Winston');
$blog5->setTags('binary, one, zero, alive, dead, !trusting, movie, symblog');
$blog5->setCreated(new \DateTime("2011-04-25 15:34:18"));
$blog5->setUpdated($blog5->getCreated());
$manager->persist($blog5);
$manager->flush();
}
}
Il file fixture dimostra un certo numero di caratteristiche importanti quando si utilizza Doctrine 2, compreso il modo di persistere le entità al database.
Diamo un'occhiata a come creare una voce blog.
$blog1 = new Blog();
$blog1->setTitle('A day in paradise - A day with Symfony2');
$blog1->setBlog('Lorem ipsum dolor sit d us imperdiet justo scelerisque. Nulla consectetur...');
$blog1->setImage('beach.jpg');
$blog1->setAuthor('dsyph3r');
$blog1->setTags('symfony2, php, paradise, symblog');
$blog1->setCreated(new \DateTime());
$blog1->setUpdated($this->getCreated());
$manager->persist($blog1);
// ..
$manager->flush();
Iniziamo creando un oggetto di Blog e impostiamo alcuni valori per i suoi membri. A questo punto doctrine 2 non sa nulla della Entity dell'oggetto. E' solo quando facciamo una chiamata a $manager->persist($blog1) che istruiamo Doctrine 2 come iniziare a mappare queste entità.L'oggetto $manager qui è un istanza dell'oggetto EntityManager come abbiamo visto in precedenza nel recupero dell'entità dal database È importante notare che mentre Doctrine 2 è ora consapevoli della oggetto entità, questo non è ancora mantenuto nel database. Una chiamata a $ manager-> flush () è richiesta per questo. Il metodo flush fa Doctrine 2 interagire realmente con tutti i database e gestisce l'azione dell'entità. Per prestazioni ottimali si dovrebbe usare Doctrine 2 per fare tutte le azioni in un colpo solo.. Questo è come noi abbiamo fatto con le nostre fixtures. Noi creiamo tutte le entità e chiediamo la gestione a , Doctrine 2 e quindi con flush finiamo tutte le operazioni..
Loading the fixtures¶
Siamo ora pronti per caricare le fixture nel database
$ php app/console doctrine:fixtures:load
Se diamo uno sguardo alla pagina http://symblog.dev/app_dev.php/1 vedremo un blog con tutti i dati del database..

Prova a cambiare il parametro dell' id nell'URL a 2. Dovreste vedere la voce del blog successivo.
Se provi a controllare l' URL http://symblog.dev/app_dev.php/100 tu vedrai una 404 Not Found exception . Ci si aspetterebbe questo visto che non vi è alcuna Blog entità con un ID di 100. Ora provate l'URL http://symblog.dev/app_dev.php/symfony2-blog . Perché non si ottiene un 404 Not Found exception? Questo è perchè la show action non viene eseguita. L'URL non corrisponde ad alcuna rotta nella domanda a causa del requisito \d+ che abbiamo impostato sulla rotta BloggerBlogBundle_blog_show. È per questo che si vede un No route found for "GET /symfony2-blog" exception.
Timestamps¶
Infine, in questo capitolo vedremo i 2 membri timestamp sull'entità Blog;; created and updated. La funzionalità di questi 2 componenti è comunemente indicata come comportamento Timestampable Questi membri prendono il tempo di quando un blog è stato creato e di quando viene aggiornato. Poiché non vogliamo dover impostare manualmente questi campi ogni volta per creare o aggiornare un blog, possiamo usare Doctrine 2 per aiutarci.
Doctrine 2 viene con un Event System che provvede un Lifecycle Callbacks. Possiamo usare questi eventi di callback per registrare le nostre entità e per notificare gli eventi durante la vita delle entità. Some example of events we can be notified about include before an update happens, after a persist happens and after a remove happens. In order to use Lifecycle Callbacks on our entity we need to register the entity for them. This is done using metadata on the entity. Update the Blog entity located at src/Blogger/BlogBundle/Entity/Blog.php with the following.
<?php
// src/Blogger/BlogBundle/Entity/Blog.php
// ..
/**
* @ORM\Entity
* @ORM\Table(name="blog")
* @ORM\HasLifecycleCallbacks()
*/
class Blog
{
// ..
}
Ora aggiungiamo un metodo nell' entità Blog che registra l'evento PreUpdate. Aggiungiamo anche un costruttore per impostare i valori predefiniti percreated and updated..
<?php
// src/Blogger/BlogBundle/Entity/Blog.php
// ..
/**
* @ORM\Entity
* @ORM\Table(name="blog")
* @ORM\HasLifecycleCallbacks()
*/
class Blog
{
// ..
public function __construct()
{
$this->setCreated(new \DateTime());
$this->setUpdated(new \DateTime());
}
/**
* @ORM\preUpdate
*/
public function setUpdatedValue()
{
$this->setUpdated(new \DateTime());
}
// ..
}
Registriamo l'entità Blog per essere notificata su l'evento preUpdate impostiamo il valore updated per il membro. Andiamo a ricaricare le fixtures e noteremo che created and updated membri sono impostati automaticamente..
Nota
In modo che i membri siano timestampable che è un requisito comune per le entità, vi è un bundle che supporta questo.StofDoctrineExtensionsBundle che fornisce una serie di utili estensioni Doctrine 2 tra cui Timestampable, Sluggable e ordinabili.
Vedremo come integrare questo bundle più avanti nel tutorial. I più impazienti tra di voi possono controllare il libro per un capitolo su questo argomento.
Conclusione ¶
Abbiamo coperto una serie di concetti per trattare con i modelli in Doctrine 2. Abbiamo anche guardato alla definizione di fixture dati per fornirci un modo semplice per ottenere i dati di prova idonei nel nostro sviluppo dell' applicazione e per i test.
Ora vediamo come estendere ulteriormente il modello aggiungendo l'entità commento. Si inizierà a costruire la home page e creare un repository personalizzato per fare questo. Si introdurrà anche il concetto di Doctrine Migrations e come usare i form che interagiscono con Doctrine 2 per consentire l'invio dei commenti al blog..