Skip to content

Latest commit

 

History

History
300 lines (221 loc) · 7.89 KB

in-ten-quick-steps.rst

File metadata and controls

300 lines (221 loc) · 7.89 KB

Doctrine explained in 10 quick steps

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>`.

1. Allows you to map PHP Objects to database tables

<?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.

2. Using Annotations, XML or YAML for Metadata Mapping

.. 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>


3. Object References map to Foreign keys

<?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.

4. Collections handle sets of objects references

<?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!");

5. Easy to setup for the default configuration case

<?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);

6. The EntityManager needs to know about your new objects

<?php

$entityManager->persist($user);
$entityManager->persist($post);

Warning

This does not lead to INSERT/UPDATE statements yet. You need to call EntityManager#flush()

7. EntityManager#flush() batches SQL INSERT/UPDATE/DELETE statements

<?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.

8. You can fetch objects from the database through the EntityManager

<?php

$post = $entityManager->find("Post", $id);

9. ..or through a Repository

<?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")
);

10. Or complex finder scenarios with the Doctrine Query Language

<?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();