From e0d706219ba2a6660e2900e568cb96b4f418ae90 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 16 Mar 2013 20:36:09 +0100 Subject: [PATCH] Start reorganizing documentation with focus on simplicity. --- docs/en/index.rst | 18 +- docs/en/reference/advanced-configuration.rst | 432 +++++++++++++++ docs/en/reference/configuration.rst | 551 ++----------------- docs/en/reference/installation.rst | 17 +- docs/en/tutorials/in-ten-quick-steps.rst | 296 ---------- 5 files changed, 484 insertions(+), 830 deletions(-) create mode 100644 docs/en/reference/advanced-configuration.rst delete mode 100644 docs/en/tutorials/in-ten-quick-steps.rst diff --git a/docs/en/index.rst b/docs/en/index.rst index f0f94c3c1..da89cf227 100644 --- a/docs/en/index.rst +++ b/docs/en/index.rst @@ -25,22 +25,15 @@ of contents `. Getting Started --------------- +* **Setup**: + :doc:`Installation & Configuration ` | + :doc:`Commandline Tools ` + * **Tutorial**: :doc:`Code First ` | :doc:`Model First ` | :doc:`Database First ` -* **Introduction**: - :doc:`In 10 quick steps ` | - :doc:`Architecture ` - -* **Setup**: - :doc:`Installation ` | - :doc:`Configuration ` | - :doc:`Tools ` - -* :doc:`Limitations and knowns issues ` - Mapping Objects onto a Database ------------------------------- @@ -75,6 +68,9 @@ Working with Objects Advanced Topics --------------- + * :doc:`Architecture ` + * :doc:`Advanced Configuration ` + * :doc:`Limitations and knowns issues ` * :doc:`Transactions and Concurrency ` * :doc:`Filters ` * :doc:`NamingStrategy ` diff --git a/docs/en/reference/advanced-configuration.rst b/docs/en/reference/advanced-configuration.rst new file mode 100644 index 000000000..5c8ad01d1 --- /dev/null +++ b/docs/en/reference/advanced-configuration.rst @@ -0,0 +1,432 @@ +Advanced Configuration +====================== + +The configuration of the EntityManager requires a +``Doctrine\ORM\Configuration`` instance as well as some database +connection parameters. This example shows all the potential +steps of configuration. + +.. code-block:: php + + setMetadataCacheImpl($cache); + $driverImpl = $config->newDefaultAnnotationDriver('/path/to/lib/MyProject/Entities'); + $config->setMetadataDriverImpl($driverImpl); + $config->setQueryCacheImpl($cache); + $config->setProxyDir('/path/to/myproject/lib/MyProject/Proxies'); + $config->setProxyNamespace('MyProject\Proxies'); + + if ($applicationMode == "development") { + $config->setAutoGenerateProxyClasses(true); + } else { + $config->setAutoGenerateProxyClasses(false); + } + + $connectionOptions = array( + 'driver' => 'pdo_sqlite', + 'path' => 'database.sqlite' + ); + + $em = EntityManager::create($connectionOptions, $config); + +.. note:: + + Do not use Doctrine without a metadata and query cache! + Doctrine is optimized for working with caches. The main + parts in Doctrine that are optimized for caching are the metadata + mapping information with the metadata cache and the DQL to SQL + conversions with the query cache. These 2 caches require only an + absolute minimum of memory yet they heavily improve the runtime + performance of Doctrine. The recommended cache driver to use with + Doctrine is `APC `_. APC provides you with + an opcode-cache (which is highly recommended anyway) and a very + fast in-memory cache storage that you can use for the metadata and + query caches as seen in the previous code snippet. + +Configuration Options +--------------------- + +The following sections describe all the configuration options +available on a ``Doctrine\ORM\Configuration`` instance. + +Proxy Directory (***REQUIRED***) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + setProxyDir($dir); + $config->getProxyDir(); + +Gets or sets the directory where Doctrine generates any proxy +classes. For a detailed explanation on proxy classes and how they +are used in Doctrine, refer to the "Proxy Objects" section further +down. + +Proxy Namespace (***REQUIRED***) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + setProxyNamespace($namespace); + $config->getProxyNamespace(); + +Gets or sets the namespace to use for generated proxy classes. For +a detailed explanation on proxy classes and how they are used in +Doctrine, refer to the "Proxy Objects" section further down. + +Metadata Driver (***REQUIRED***) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + setMetadataDriverImpl($driver); + $config->getMetadataDriverImpl(); + +Gets or sets the metadata driver implementation that is used by +Doctrine to acquire the object-relational metadata for your +classes. + +There are currently 4 available implementations: + + +- ``Doctrine\ORM\Mapping\Driver\AnnotationDriver`` +- ``Doctrine\ORM\Mapping\Driver\XmlDriver`` +- ``Doctrine\ORM\Mapping\Driver\YamlDriver`` +- ``Doctrine\ORM\Mapping\Driver\DriverChain`` + +Throughout the most part of this manual the AnnotationDriver is +used in the examples. For information on the usage of the XmlDriver +or YamlDriver please refer to the dedicated chapters +``XML Mapping`` and ``YAML Mapping``. + +The annotation driver can be configured with a factory method on +the ``Doctrine\ORM\Configuration``: + +.. code-block:: php + + newDefaultAnnotationDriver('/path/to/lib/MyProject/Entities'); + $config->setMetadataDriverImpl($driverImpl); + +The path information to the entities is required for the annotation +driver, because otherwise mass-operations on all entities through +the console could not work correctly. All of metadata drivers +accept either a single directory as a string or an array of +directories. With this feature a single driver can support multiple +directories of Entities. + +Metadata Cache (***RECOMMENDED***) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + setMetadataCacheImpl($cache); + $config->getMetadataCacheImpl(); + +Gets or sets the cache implementation to use for caching metadata +information, that is, all the information you supply via +annotations, xml or yaml, so that they do not need to be parsed and +loaded from scratch on every single request which is a waste of +resources. The cache implementation must implement the +``Doctrine\Common\Cache\Cache`` interface. + +Usage of a metadata cache is highly recommended. + +The recommended implementations for production are: + + +- ``Doctrine\Common\Cache\ApcCache`` +- ``Doctrine\Common\Cache\MemcacheCache`` +- ``Doctrine\Common\Cache\XcacheCache`` +- ``Doctrine\Common\Cache\RedisCache`` + +For development you should use the +``Doctrine\Common\Cache\ArrayCache`` which only caches data on a +per-request basis. + +Query Cache (***RECOMMENDED***) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + setQueryCacheImpl($cache); + $config->getQueryCacheImpl(); + +Gets or sets the cache implementation to use for caching DQL +queries, that is, the result of a DQL parsing process that includes +the final SQL as well as meta information about how to process the +SQL result set of a query. Note that the query cache does not +affect query results. You do not get stale data. This is a pure +optimization cache without any negative side-effects (except some +minimal memory usage in your cache). + +Usage of a query cache is highly recommended. + +The recommended implementations for production are: + + +- ``Doctrine\Common\Cache\ApcCache`` +- ``Doctrine\Common\Cache\MemcacheCache`` +- ``Doctrine\Common\Cache\XcacheCache`` +- ``Doctrine\Common\Cache\RedisCache`` + +For development you should use the +``Doctrine\Common\Cache\ArrayCache`` which only caches data on a +per-request basis. + +SQL Logger (***Optional***) +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + setSQLLogger($logger); + $config->getSQLLogger(); + +Gets or sets the logger to use for logging all SQL statements +executed by Doctrine. The logger class must implement the +``Doctrine\DBAL\Logging\SQLLogger`` interface. A simple default +implementation that logs to the standard output using ``echo`` and +``var_dump`` can be found at +``Doctrine\DBAL\Logging\EchoSQLLogger``. + +Auto-generating Proxy Classes (***OPTIONAL***) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: php + + setAutoGenerateProxyClasses($bool); + $config->getAutoGenerateProxyClasses(); + +Gets or sets whether proxy classes should be generated +automatically at runtime by Doctrine. If set to ``FALSE``, proxy +classes must be generated manually through the doctrine command +line task ``generate-proxies``. The strongly recommended value for +a production environment is ``FALSE``. + +Development vs Production Configuration +--------------------------------------- + +You should code your Doctrine2 bootstrapping with two different +runtime models in mind. There are some serious benefits of using +APC or Memcache in production. In development however this will +frequently give you fatal errors, when you change your entities and +the cache still keeps the outdated metadata. That is why we +recommend the ``ArrayCache`` for development. + +Furthermore you should have the Auto-generating Proxy Classes +option to true in development and to false in production. If this +option is set to ``TRUE`` it can seriously hurt your script +performance if several proxy classes are re-generated during script +execution. Filesystem calls of that magnitude can even slower than +all the database queries Doctrine issues. Additionally writing a +proxy sets an exclusive file lock which can cause serious +performance bottlenecks in systems with regular concurrent +requests. + +Connection Options +------------------ + +The ``$connectionOptions`` passed as the first argument to +``EntityManager::create()`` has to be either an array or an +instance of ``Doctrine\DBAL\Connection``. If an array is passed it +is directly passed along to the DBAL Factory +``Doctrine\DBAL\DriverManager::getConnection()``. The DBAL +configuration is explained in the +`DBAL section <./../../../../../dbal/2.0/docs/reference/configuration/en>`_. + +Proxy Objects +------------- + +A proxy object is an object that is put in place or used instead of +the "real" object. A proxy object can add behavior to the object +being proxied without that object being aware of it. In Doctrine 2, +proxy objects are used to realize several features but mainly for +transparent lazy-loading. + +Proxy objects with their lazy-loading facilities help to keep the +subset of objects that are already in memory connected to the rest +of the objects. This is an essential property as without it there +would always be fragile partial objects at the outer edges of your +object graph. + +Doctrine 2 implements a variant of the proxy pattern where it +generates classes that extend your entity classes and adds +lazy-loading capabilities to them. Doctrine can then give you an +instance of such a proxy class whenever you request an object of +the class being proxied. This happens in two situations: + +Reference Proxies +~~~~~~~~~~~~~~~~~ + +The method ``EntityManager#getReference($entityName, $identifier)`` +lets you obtain a reference to an entity for which the identifier +is known, without loading that entity from the database. This is +useful, for example, as a performance enhancement, when you want to +establish an association to an entity for which you have the +identifier. You could simply do this: + +.. code-block:: php + + getReference('MyProject\Model\Item', $itemId); + $cart->addItem($item); + +Here, we added an Item to a Cart without loading the Item from the +database. If you invoke any method on the Item instance, it would +fully initialize its state transparently from the database. Here +$item is actually an instance of the proxy class that was generated +for the Item class but your code does not need to care. In fact it +**should not care**. Proxy objects should be transparent to your +code. + +Association proxies +~~~~~~~~~~~~~~~~~~~ + +The second most important situation where Doctrine uses proxy +objects is when querying for objects. Whenever you query for an +object that has a single-valued association to another object that +is configured LAZY, without joining that association in the same +query, Doctrine puts proxy objects in place where normally the +associated object would be. Just like other proxies it will +transparently initialize itself on first access. + +.. note:: + + Joining an association in a DQL or native query + essentially means eager loading of that association in that query. + This will override the 'fetch' option specified in the mapping for + that association, but only for that query. + + +Generating Proxy classes +~~~~~~~~~~~~~~~~~~~~~~~~ + +Proxy classes can either be generated manually through the Doctrine +Console or automatically by Doctrine. The configuration option that +controls this behavior is: + +.. code-block:: php + + setAutoGenerateProxyClasses($bool); + $config->getAutoGenerateProxyClasses(); + +The default value is ``TRUE`` for convenient development. However, +this setting is not optimal for performance and therefore not +recommended for a production environment. To eliminate the overhead +of proxy class generation during runtime, set this configuration +option to ``FALSE``. When you do this in a development environment, +note that you may get class/file not found errors if certain proxy +classes are not available or failing lazy-loads if new methods were +added to the entity class that are not yet in the proxy class. In +such a case, simply use the Doctrine Console to (re)generate the +proxy classes like so: + +.. code-block:: php + + $ ./doctrine orm:generate-proxies + +Autoloading Proxies +------------------- + +When you deserialize proxy objects from the session or any other storage +it is necessary to have an autoloading mechanism in place for these classes. +For implementation reasons Proxy class names are not PSR-0 compliant. This +means that you have to register a special autoloader for these classes: + +.. code-block:: php + + addDriver($xmlDriver, 'Doctrine\Tests\Models\Company'); + $chain->addDriver($yamlDriver, 'Doctrine\Tests\ORM\Mapping'); + +Based on the namespace of the entity the loading of entities is +delegated to the appropriate driver. The chain semantics come from +the fact that the driver loops through all namespaces and matches +the entity class name against the namespace using a +``strpos() === 0`` call. This means you need to order the drivers +correctly if sub-namespaces use different metadata driver +implementations. + + +Default Repository (***OPTIONAL***) +----------------------------------- + +Specifies the FQCN of a subclass of the EntityRepository. +That will be available for all entities without a custom repository class. + +.. code-block:: php + + setDefaultRepositoryClassName($fqcn); + $config->getDefaultRepositoryClassName(); + +The default value is ``Doctrine\ORM\EntityRepository``. +Any repository class must be a subclass of EntityRepository otherwise you got an ORMException + +Setting up the Console +---------------------- + +Doctrine uses the Symfony Console component for generating the command +line interface. You can take a look at the ``vendor/bin/doctrine.php`` +script and the ``Doctrine\ORM\Tools\Console\ConsoleRunner`` command +for inspiration how to setup the cli. + +In general the required code looks like this: + +.. code-block:: php + + setCatchExceptions(true); + $cli->setHelperSet($helperSet); + Doctrine\ORM\Tools\Console\ConsoleRunner::addCommands($cli); + $cli->run(); + diff --git a/docs/en/reference/configuration.rst b/docs/en/reference/configuration.rst index 6cb839b34..4835b9cb2 100644 --- a/docs/en/reference/configuration.rst +++ b/docs/en/reference/configuration.rst @@ -1,77 +1,36 @@ -Configuration -============= +Installation and Configuration +============================== -Bootstrapping Doctrine is a relatively simple procedure that -roughly exists of four steps: +Doctrine can be installed with `Composer `_. For +older versions we still have `PEAR packages +`_. -- `Installation ` -- Making sure Doctrine class files can be loaded on demand. -- Obtaining an EntityManager instance. -- Optional: Configuration of the Console Tool +Define the following requirement in your ``composer.json`` file: + +:: + + { + "require": { + "doctrine/orm": "*" + } + } + +Then call ``composer install`` from your command line. If you don't know +how Composer works, check out their `Getting Started +`_ to set up. Class loading ------------- -Composer -^^^^^^^^ - Autoloading is taken care of by Composer. You just have to include the composer autoload file in your project: .. code-block:: php ` section. + .. note:: - You can learn more about the connection configuration in the + You can learn more about the database connection configuration in the `Doctrine DBAL connection configuration reference `_. -Full Configuration Example -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The configuration of the EntityManager requires a -``Doctrine\ORM\Configuration`` instance as well as some database -connection parameters. This example shows all the potential -steps of configuration. - -.. code-block:: php - - setMetadataCacheImpl($cache); - $driverImpl = $config->newDefaultAnnotationDriver('/path/to/lib/MyProject/Entities'); - $config->setMetadataDriverImpl($driverImpl); - $config->setQueryCacheImpl($cache); - $config->setProxyDir('/path/to/myproject/lib/MyProject/Proxies'); - $config->setProxyNamespace('MyProject\Proxies'); - - if ($applicationMode == "development") { - $config->setAutoGenerateProxyClasses(true); - } else { - $config->setAutoGenerateProxyClasses(false); - } - - $connectionOptions = array( - 'driver' => 'pdo_sqlite', - 'path' => 'database.sqlite' - ); - - $em = EntityManager::create($connectionOptions, $config); - -.. note:: - - Do not use Doctrine without a metadata and query cache! - Doctrine is optimized for working with caches. The main - parts in Doctrine that are optimized for caching are the metadata - mapping information with the metadata cache and the DQL to SQL - conversions with the query cache. These 2 caches require only an - absolute minimum of memory yet they heavily improve the runtime - performance of Doctrine. The recommended cache driver to use with - Doctrine is `APC `_. APC provides you with - an opcode-cache (which is highly recommended anyway) and a very - fast in-memory cache storage that you can use for the metadata and - query caches as seen in the previous code snippet. - -Configuration Options ---------------------- - -The following sections describe all the configuration options -available on a ``Doctrine\ORM\Configuration`` instance. - -Proxy Directory (***REQUIRED***) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: php - - setProxyDir($dir); - $config->getProxyDir(); - -Gets or sets the directory where Doctrine generates any proxy -classes. For a detailed explanation on proxy classes and how they -are used in Doctrine, refer to the "Proxy Objects" section further -down. - -Proxy Namespace (***REQUIRED***) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: php - - setProxyNamespace($namespace); - $config->getProxyNamespace(); - -Gets or sets the namespace to use for generated proxy classes. For -a detailed explanation on proxy classes and how they are used in -Doctrine, refer to the "Proxy Objects" section further down. - -Metadata Driver (***REQUIRED***) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: php - - setMetadataDriverImpl($driver); - $config->getMetadataDriverImpl(); - -Gets or sets the metadata driver implementation that is used by -Doctrine to acquire the object-relational metadata for your -classes. - -There are currently 4 available implementations: - - -- ``Doctrine\ORM\Mapping\Driver\AnnotationDriver`` -- ``Doctrine\ORM\Mapping\Driver\XmlDriver`` -- ``Doctrine\ORM\Mapping\Driver\YamlDriver`` -- ``Doctrine\ORM\Mapping\Driver\DriverChain`` - -Throughout the most part of this manual the AnnotationDriver is -used in the examples. For information on the usage of the XmlDriver -or YamlDriver please refer to the dedicated chapters -``XML Mapping`` and ``YAML Mapping``. - -The annotation driver can be configured with a factory method on -the ``Doctrine\ORM\Configuration``: - -.. code-block:: php - - newDefaultAnnotationDriver('/path/to/lib/MyProject/Entities'); - $config->setMetadataDriverImpl($driverImpl); - -The path information to the entities is required for the annotation -driver, because otherwise mass-operations on all entities through -the console could not work correctly. All of metadata drivers -accept either a single directory as a string or an array of -directories. With this feature a single driver can support multiple -directories of Entities. - -Metadata Cache (***RECOMMENDED***) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: php - - setMetadataCacheImpl($cache); - $config->getMetadataCacheImpl(); - -Gets or sets the cache implementation to use for caching metadata -information, that is, all the information you supply via -annotations, xml or yaml, so that they do not need to be parsed and -loaded from scratch on every single request which is a waste of -resources. The cache implementation must implement the -``Doctrine\Common\Cache\Cache`` interface. - -Usage of a metadata cache is highly recommended. - -The recommended implementations for production are: - - -- ``Doctrine\Common\Cache\ApcCache`` -- ``Doctrine\Common\Cache\MemcacheCache`` -- ``Doctrine\Common\Cache\XcacheCache`` -- ``Doctrine\Common\Cache\RedisCache`` - -For development you should use the -``Doctrine\Common\Cache\ArrayCache`` which only caches data on a -per-request basis. - -Query Cache (***RECOMMENDED***) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: php - - setQueryCacheImpl($cache); - $config->getQueryCacheImpl(); - -Gets or sets the cache implementation to use for caching DQL -queries, that is, the result of a DQL parsing process that includes -the final SQL as well as meta information about how to process the -SQL result set of a query. Note that the query cache does not -affect query results. You do not get stale data. This is a pure -optimization cache without any negative side-effects (except some -minimal memory usage in your cache). - -Usage of a query cache is highly recommended. - -The recommended implementations for production are: - - -- ``Doctrine\Common\Cache\ApcCache`` -- ``Doctrine\Common\Cache\MemcacheCache`` -- ``Doctrine\Common\Cache\XcacheCache`` -- ``Doctrine\Common\Cache\RedisCache`` - -For development you should use the -``Doctrine\Common\Cache\ArrayCache`` which only caches data on a -per-request basis. - -SQL Logger (***Optional***) -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: php - - setSQLLogger($logger); - $config->getSQLLogger(); - -Gets or sets the logger to use for logging all SQL statements -executed by Doctrine. The logger class must implement the -``Doctrine\DBAL\Logging\SQLLogger`` interface. A simple default -implementation that logs to the standard output using ``echo`` and -``var_dump`` can be found at -``Doctrine\DBAL\Logging\EchoSQLLogger``. - -Auto-generating Proxy Classes (***OPTIONAL***) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: php - - setAutoGenerateProxyClasses($bool); - $config->getAutoGenerateProxyClasses(); - -Gets or sets whether proxy classes should be generated -automatically at runtime by Doctrine. If set to ``FALSE``, proxy -classes must be generated manually through the doctrine command -line task ``generate-proxies``. The strongly recommended value for -a production environment is ``FALSE``. - -Development vs Production Configuration ---------------------------------------- - -You should code your Doctrine2 bootstrapping with two different -runtime models in mind. There are some serious benefits of using -APC or Memcache in production. In development however this will -frequently give you fatal errors, when you change your entities and -the cache still keeps the outdated metadata. That is why we -recommend the ``ArrayCache`` for development. - -Furthermore you should have the Auto-generating Proxy Classes -option to true in development and to false in production. If this -option is set to ``TRUE`` it can seriously hurt your script -performance if several proxy classes are re-generated during script -execution. Filesystem calls of that magnitude can even slower than -all the database queries Doctrine issues. Additionally writing a -proxy sets an exclusive file lock which can cause serious -performance bottlenecks in systems with regular concurrent -requests. - -Connection Options ------------------- - -The ``$connectionOptions`` passed as the first argument to -``EntityManager::create()`` has to be either an array or an -instance of ``Doctrine\DBAL\Connection``. If an array is passed it -is directly passed along to the DBAL Factory -``Doctrine\DBAL\DriverManager::getConnection()``. The DBAL -configuration is explained in the -`DBAL section <./../../../../../dbal/2.0/docs/reference/configuration/en>`_. - -Proxy Objects -------------- - -A proxy object is an object that is put in place or used instead of -the "real" object. A proxy object can add behavior to the object -being proxied without that object being aware of it. In Doctrine 2, -proxy objects are used to realize several features but mainly for -transparent lazy-loading. - -Proxy objects with their lazy-loading facilities help to keep the -subset of objects that are already in memory connected to the rest -of the objects. This is an essential property as without it there -would always be fragile partial objects at the outer edges of your -object graph. - -Doctrine 2 implements a variant of the proxy pattern where it -generates classes that extend your entity classes and adds -lazy-loading capabilities to them. Doctrine can then give you an -instance of such a proxy class whenever you request an object of -the class being proxied. This happens in two situations: - -Reference Proxies -~~~~~~~~~~~~~~~~~ - -The method ``EntityManager#getReference($entityName, $identifier)`` -lets you obtain a reference to an entity for which the identifier -is known, without loading that entity from the database. This is -useful, for example, as a performance enhancement, when you want to -establish an association to an entity for which you have the -identifier. You could simply do this: - -.. code-block:: php - - getReference('MyProject\Model\Item', $itemId); - $cart->addItem($item); - -Here, we added an Item to a Cart without loading the Item from the -database. If you invoke any method on the Item instance, it would -fully initialize its state transparently from the database. Here -$item is actually an instance of the proxy class that was generated -for the Item class but your code does not need to care. In fact it -**should not care**. Proxy objects should be transparent to your -code. - -Association proxies -~~~~~~~~~~~~~~~~~~~ - -The second most important situation where Doctrine uses proxy -objects is when querying for objects. Whenever you query for an -object that has a single-valued association to another object that -is configured LAZY, without joining that association in the same -query, Doctrine puts proxy objects in place where normally the -associated object would be. Just like other proxies it will -transparently initialize itself on first access. - -.. note:: - - Joining an association in a DQL or native query - essentially means eager loading of that association in that query. - This will override the 'fetch' option specified in the mapping for - that association, but only for that query. - - -Generating Proxy classes -~~~~~~~~~~~~~~~~~~~~~~~~ - -Proxy classes can either be generated manually through the Doctrine -Console or automatically by Doctrine. The configuration option that -controls this behavior is: - -.. code-block:: php - - setAutoGenerateProxyClasses($bool); - $config->getAutoGenerateProxyClasses(); - -The default value is ``TRUE`` for convenient development. However, -this setting is not optimal for performance and therefore not -recommended for a production environment. To eliminate the overhead -of proxy class generation during runtime, set this configuration -option to ``FALSE``. When you do this in a development environment, -note that you may get class/file not found errors if certain proxy -classes are not available or failing lazy-loads if new methods were -added to the entity class that are not yet in the proxy class. In -such a case, simply use the Doctrine Console to (re)generate the -proxy classes like so: - -.. code-block:: php - - $ ./doctrine orm:generate-proxies - -Autoloading Proxies -------------------- - -When you deserialize proxy objects from the session or any other storage -it is necessary to have an autoloading mechanism in place for these classes. -For implementation reasons Proxy class names are not PSR-0 compliant. This -means that you have to register a special autoloader for these classes: - -.. code-block:: php - - addDriver($xmlDriver, 'Doctrine\Tests\Models\Company'); - $chain->addDriver($yamlDriver, 'Doctrine\Tests\ORM\Mapping'); - -Based on the namespace of the entity the loading of entities is -delegated to the appropriate driver. The chain semantics come from -the fact that the driver loops through all namespaces and matches -the entity class name against the namespace using a -``strpos() === 0`` call. This means you need to order the drivers -correctly if sub-namespaces use different metadata driver -implementations. - - -Default Repository (***OPTIONAL***) ------------------------------------ - -Specifies the FQCN of a subclass of the EntityRepository. -That will be available for all entities without a custom repository class. - -.. code-block:: php - - setDefaultRepositoryClassName($fqcn); - $config->getDefaultRepositoryClassName(); - -The default value is ``Doctrine\ORM\EntityRepository``. -Any repository class must be a subclass of EntityRepository otherwise you got an ORMException - -Setting up the Console ----------------------- - -Doctrine uses the Symfony Console component for generating the command -line interface. You can take a look at the ``bin/doctrine.php`` -script and the ``Doctrine\ORM\Tools\Console\ConsoleRunner`` command -for inspiration how to setup the cli. - -If you installed Doctrine 2 through Composer, then the Doctrine command is -available to you in the bin-dir, by default at ``vendor/bin/doctrine-orm``. - -In general the required code looks like this: - -.. code-block:: php - - setCatchExceptions(true); - $cli->setHelperSet($helperSet); - Doctrine\ORM\Tools\Console\ConsoleRunner::addCommands($cli); - $cli->run(); - diff --git a/docs/en/reference/installation.rst b/docs/en/reference/installation.rst index c403decaa..8b732ad60 100644 --- a/docs/en/reference/installation.rst +++ b/docs/en/reference/installation.rst @@ -1,18 +1,5 @@ Installation ============ -Doctrine was installable in many different ways, however `Composer `_ turned out to be one of the best things for PHP in a long time. -This is why we moved all installation to use Composer only. - -Define the following requirement in your ``composer.json`` file: - -:: - - { - "require": { - "doctrine/orm": "*" - } - } - -Then run the composer command and you are done. Continue with the -:doc:`Configuration `. +The installation chapter has moved to `Installation and Configuration +`_. diff --git a/docs/en/tutorials/in-ten-quick-steps.rst b/docs/en/tutorials/in-ten-quick-steps.rst deleted file mode 100644 index 0d16278d7..000000000 --- a/docs/en/tutorials/in-ten-quick-steps.rst +++ /dev/null @@ -1,296 +0,0 @@ -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 Composer. -For more information take a look at the :doc:`Installation help -<../reference/introduction>`. - -1. Allows you to map PHP Objects to database tables ---------------------------------------------------- - -.. code-block:: php - - 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 - - - - - - - - - - - - - -3. Object References map to Foreign keys ----------------------------------------- - -.. code-block:: php - - 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 ------------------------------------------------- - -.. code-block:: php - - author = $author; - $this->comments = 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 ---------------------------------------------------- - -.. code-block:: php - - '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 ---------------------------------------------------------- - -.. code-block:: php - - 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 --------------------------------------------------------------------- - -.. code-block:: php - - 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 --------------------------------------------------------------------- - -.. code-block:: php - - find("Post", $id); - -9. ..or through a Repository ----------------------------- - -.. code-block:: php - - 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 ----------------------------------------------------------------- - -.. code-block:: php - - createQuery($dql)->getResult();