You can follow this tutorial step by step yourself and end up with a simple Doctrine application. It assumed that you installed Doctrine via PEAR. To work with another setup just take a look into the :doc:`Installation help <../reference/introduction>`.
<?php
class Post
{
protected $id;
protected $title;
protected $body;
}
mysql> CREATE TABLE Post (id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255), body TEXT); mysql> DESCRIBE Post; +-------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | title | varchar(255) | YES | | NULL | | | body | text | YES | | NULL | | +-------+--------------+------+-----+---------+----------------+
Tip
Objects mapped with Doctrine are called Entities. They don't need to extend a base class and even allow constructors with required parameters.
You are responsible for implementing getters, setters and constructors of your entities yourself. This gives you full freedom to design your business objects as you wish.
.. configuration-block:: .. code-block:: php <?php /** @Entity **/ class Post { /** @Id @GeneratedValue @Column(type="integer") **/ protected $id; /** @Column(type="string") **/ protected $title; /** @Column(type="text") **/ protected $body; } .. code-block:: yaml Post: type: entity id: id: type: integer generator: strategy: AUTO fields: title: type: string body: type: text .. code-block:: xml <?xml version="1.0" ?> <doctrine-mapping> <entity name="Post"> <id name="id type="integer"> <generator strategy="AUTO" /> </id> <field name="title" type="string" /> <field name="body" type="text" /> </entity> </doctrine-mapping>
<?php
/** @Entity **/
class Post
{
// .. previous code
/**
* @ManyToOne(targetEntity="User")
**/
protected $author;
public function __construct(User $user)
{
$this->author = $user;
}
}
/** @Entity **/
class User
{
/** @Id @GeneratedValue @Column(type="integer") **/
protected $id;
/** @Column(type="string") **/
protected $name;
}
$user = new User();
$post = new Post($user);
mysql> CREATE TABLE Post (id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255), body TEXT, author_id INT); mysql> CREATE TABLE User (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255)); mysql> ALTER TABLE Post ADD FOREIGN KEY (author_id) REFERENCES User (id); mysql> DESCRIBE Post; +-----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | title | varchar(255) | YES | | NULL | | | body | text | YES | | NULL | | | author_id | int(11) | YES | MUL | NULL | | +-----------+--------------+------+-----+---------+----------------+
Tip
This means you don't have to mess with foreign keys yourself, just use references to connect objects with each other and let Doctrine handle the rest.
<?php
use Doctrine\Common\Collections\ArrayCollection;
class Post
{
// .. previous code
/**
* @OneToMany(targetEntity="Comment", mappedBy="post",
* cascade={"persist"})
**/
protected $comments;
public function __construct(User $author)
{
$this->author = $author;
$this->posts = new ArrayCollection();
}
public function addComment($text)
{
$this->comments[] = new Comment($this, $text);
}
}
/** @Entity **/
class Comment
{
/** @Id @GeneratedValue @Column(type="integer") **/
protected $id;
/** @Column(type="text") **/
protected $comment;
/**
* @ManyToOne(targetEntity="Post", inversedBy="comments")
**/
protected $post;
public function __construct(Post $post, $text)
{
$this->post = $post;
$this->comment = $text;
}
}
$post->addComment("First..");
$post->addComment("Second!");
<?php
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
require_once 'Doctrine/Common/ClassLoader.php';
$loader = new \Doctrine\Common\ClassLoader("Doctrine");
$loader->register();
$dbParams = array(
'driver' => 'pdo_mysql',
'user' => 'root',
'password' => '',
'dbname' => 'tests'
);
$path = 'path/to/entities';
$config = Setup::createAnnotationMetadataConfiguration($path, true);
$entityManager = EntityManager::create($dbParams, $config);
<?php
$entityManager->persist($user);
$entityManager->persist($post);
Warning
This does not lead to INSERT/UPDATE statements yet. You need to call EntityManager#flush()
<?php
$entityManager->flush();
Tip
Batching all write-operations against the database allows Doctrine to wrap all statements into a single transaction and benefit from other performance optimizations such as prepared statement re-use.
<?php
$post = $entityManager->find("Post", $id);
<?php
$authorRepository = $entityManager->getRepository("Author");
$author = $authorRepository->find($authorId);
$postRepository = $entityManager->getRepository("Post");
$post = $postRepository->findOneBy(array("title" => "Hello World!"));
$posts = $repository->findBy(
array("author" => $author),
array("title" => "ASC")
);
<?php
// all posts and their comment count
$dql = "SELECT p, count(c.id) AS comments " .
"FROM Post p JOIN p.comments GROUP BY p";
$results = $entityManager->createQuery($dql)->getResult();