-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tweaking Doctrine book chapter #3490
Changes from 11 commits
485b529
1ec68fe
22bb029
13edbcc
c95a68d
88aa347
2c68f04
2af5c60
18cbacd
034d69a
f7ec98c
c98a3da
7acc0d2
91a18cd
8bb3195
20ba9e0
79e2216
7af962c
b4dd1a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -517,6 +517,16 @@ of the bundle: | |
If you're following along with this example, you'll need to create a | ||
route that points to this action to see it work. | ||
|
||
.. tip:: | ||
|
||
This page shows working with Doctrine within a controller. You may also | ||
want to work with Doctrine elsewhere in your application. The | ||
:method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::getDoctrine` | ||
method of the controller returns the ``doctrine`` service, you can work with | ||
this in the same way elsewhere by injecting this into your own | ||
services. See :doc:`/book/service_container` for more on creating | ||
your own services. | ||
|
||
Take a look at the previous example in more detail: | ||
|
||
* **lines 9-12** In this section, you instantiate and work with the ``$product`` | ||
|
@@ -728,65 +738,18 @@ a controller, do the following:: | |
|
||
$products = $query->getResult(); | ||
|
||
The ``getResult()`` method returns an array of results. | ||
|
||
If you're comfortable with SQL, then DQL should feel very natural. The biggest | ||
difference is that you need to think in terms of "objects" instead of rows | ||
in a database. For this reason, you select *from* ``AcmeStoreBundle:Product`` | ||
and then alias it as ``p``. | ||
|
||
The ``getResult()`` method returns an array of results. If you're querying | ||
for just one object, you can use the ``getSingleResult()`` method instead:: | ||
|
||
$product = $query->getSingleResult(); | ||
|
||
.. caution:: | ||
|
||
The ``getSingleResult()`` method throws a ``Doctrine\ORM\NoResultException`` | ||
exception if no results are returned and a ``Doctrine\ORM\NonUniqueResultException`` | ||
if *more* than one result is returned. If you use this method, you may | ||
need to wrap it in a try-catch block and ensure that only one result is | ||
returned (if you're querying on something that could feasibly return | ||
more than one result):: | ||
|
||
$query = $em->createQuery('SELECT ...') | ||
->setMaxResults(1); | ||
|
||
try { | ||
$product = $query->getSingleResult(); | ||
} catch (\Doctrine\Orm\NoResultException $e) { | ||
$product = null; | ||
} | ||
// ... | ||
in a database. For this reason, you select *from* the ``AcmeStoreBundle:Product`` | ||
*object* and then alias it as ``p``. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We still need to show how to get a single result. But, I think we should remove this big There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, what do you think (I haven't read it recently, so I'm not 100% sure) about moving the "Query Builder" section above the DQL section? I tend to use (and recommend) the query builder normally. If we showed that first, the DQL section could then be a bit of an afterthought - like "Oh, and if you want to control things a bit more yourself, you can use this DQL thing". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
The DQL syntax is incredibly powerful, allowing you to easily join between | ||
entities (the topic of :ref:`relations <book-doctrine-relations>` will be | ||
covered later), group, etc. For more information, see the official Doctrine | ||
`Doctrine Query Language`_ documentation. | ||
|
||
.. sidebar:: Setting Parameters | ||
|
||
Take note of the ``setParameter()`` method. When working with Doctrine, | ||
it's always a good idea to set any external values as "placeholders", | ||
which was done in the above query: | ||
|
||
.. code-block:: text | ||
|
||
... WHERE p.price > :price ... | ||
|
||
You can then set the value of the ``price`` placeholder by calling the | ||
``setParameter()`` method:: | ||
|
||
->setParameter('price', '19.99') | ||
|
||
Using parameters instead of placing values directly in the query string | ||
is done to prevent SQL injection attacks and should *always* be done. | ||
If you're using multiple parameters, you can set their values at once | ||
using the ``setParameters()`` method:: | ||
|
||
->setParameters(array( | ||
'price' => '19.99', | ||
'name' => 'Foo', | ||
)) | ||
|
||
Using Doctrine's Query Builder | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
|
@@ -819,10 +782,10 @@ Custom Repository Classes | |
|
||
In the previous sections, you began constructing and using more complex queries | ||
from inside a controller. In order to isolate, test and reuse these queries, | ||
it's a good idea to create a custom repository class for your entity and | ||
it's a good practise to create a custom repository class for your entity and | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. US spelling :) |
||
add methods with your query logic there. | ||
|
||
To do this, add the name of the repository class to your mapping definition. | ||
To do this, add the name of the repository class to your mapping definition: | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know that it needs to be so long, but do you think we should keep this block? It seems like a pretty obvious feature, but it is pretty important to get right (for security) and I don't think we mention it anywhere else. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Readded a small tip directive in 20ba9e0 |
||
.. configuration-block:: | ||
|
||
|
@@ -1300,7 +1263,7 @@ Configuration | |
|
||
Doctrine is highly configurable, though you probably won't ever need to worry | ||
about most of its options. To find out more about configuring Doctrine, see | ||
the Doctrine section of the :doc:`reference manual </reference/configuration/doctrine>`. | ||
the Doctrine section of the :doc:`config reference </reference/configuration/doctrine>`. | ||
|
||
Lifecycle Callbacks | ||
------------------- | ||
|
@@ -1312,7 +1275,7 @@ stages of the lifecycle of an entity (e.g. the entity is inserted, updated, | |
deleted, etc). | ||
|
||
If you're using annotations for your metadata, start by enabling the lifecycle | ||
callbacks. This is not necessary if you're using YAML or XML for your mapping: | ||
callbacks. This is not necessary if you're using YAML or XML for your mapping. | ||
|
||
.. code-block:: php-annotations | ||
|
||
|
@@ -1375,20 +1338,8 @@ the current date, only when the entity is first persisted (i.e. inserted): | |
|
||
Now, right before the entity is first persisted, Doctrine will automatically | ||
call this method and the ``createdAt`` field will be set to the current date. | ||
|
||
This can be repeated for any of the other lifecycle events, which include: | ||
|
||
* ``preRemove`` | ||
* ``postRemove`` | ||
* ``prePersist`` | ||
* ``postPersist`` | ||
* ``preUpdate`` | ||
* ``postUpdate`` | ||
* ``postLoad`` | ||
* ``loadClassMetadata`` | ||
|
||
For more information on what these lifecycle events mean and lifecycle callbacks | ||
in general, see Doctrine's `Lifecycle Events documentation`_ | ||
For more information on other lifecycle events and lifecycle callbacks in | ||
general, see Doctrine's `Lifecycle Events documentation`_. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 for removing the list. But let's rephrase now a little to really advertise directly that there are others.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done in 79e2216 |
||
|
||
.. sidebar:: Lifecycle Callbacks and Event Listeners | ||
|
||
|
@@ -1403,185 +1354,15 @@ in general, see Doctrine's `Lifecycle Events documentation`_ | |
or subscriber and give it access to whatever resources you need. For | ||
more information, see :doc:`/cookbook/doctrine/event_listeners_subscribers`. | ||
|
||
Doctrine Extensions: Timestampable, Sluggable, etc. | ||
--------------------------------------------------- | ||
|
||
Doctrine is quite flexible, and a number of third-party extensions are available | ||
that allow you to easily perform repeated and common tasks on your entities. | ||
These include thing such as *Sluggable*, *Timestampable*, *Loggable*, *Translatable*, | ||
and *Tree*. | ||
|
||
For more information on how to find and use these extensions, see the cookbook | ||
article about :doc:`using common Doctrine extensions </cookbook/doctrine/common_extensions>`. | ||
|
||
.. _book-doctrine-field-types: | ||
|
||
Doctrine Field Types Reference | ||
------------------------------ | ||
|
||
Doctrine comes with a large number of field types available. Each of these | ||
maps a PHP data type to a specific column type in whatever database you're | ||
using. The following types are supported in Doctrine: | ||
|
||
* **Strings** | ||
|
||
* ``string`` (used for shorter strings) | ||
* ``text`` (used for larger strings) | ||
|
||
* **Numbers** | ||
|
||
* ``integer`` | ||
* ``smallint`` | ||
* ``bigint`` | ||
* ``decimal`` | ||
* ``float`` | ||
|
||
* **Dates and Times** (use a `DateTime`_ object for these fields in PHP) | ||
|
||
* ``date`` | ||
* ``time`` | ||
* ``datetime`` | ||
* ``datetimetz`` | ||
|
||
* **Other Types** | ||
|
||
* ``boolean`` | ||
* ``object`` (serialized and stored in a ``CLOB`` field) | ||
* ``array`` (serialized and stored in a ``CLOB`` field) | ||
* ``blob`` (mapped to a resource stream) | ||
* ``simple_array`` (serialized using :phpfunction:`implode()` and :phpfunction:`explode()`, | ||
with a comma as delimiter, and stored in a ``CLOB`` field) | ||
* ``json_array`` (serialized using :phpfunction:`json_encode()` and :phpfunction:`json_decode()`, | ||
and stored in a ``CLOB`` field) | ||
* ``guid`` | ||
|
||
For more information, see Doctrine's `Mapping Types documentation`_. | ||
|
||
Field Options | ||
~~~~~~~~~~~~~ | ||
|
||
Each field can have a set of options applied to it. The available options | ||
include ``type`` (defaults to ``string``), ``name``, ``length``, ``unique`` | ||
and ``nullable``. Take a few examples: | ||
|
||
.. configuration-block:: | ||
|
||
.. code-block:: php-annotations | ||
|
||
/** | ||
* A string field with length 255 that cannot be null | ||
* (reflecting the default values for the "type", "length" | ||
* and *nullable* options) | ||
* | ||
* @ORM\Column() | ||
*/ | ||
protected $name; | ||
|
||
/** | ||
* A string field of length 150 that persists to an "email_address" column | ||
* and has a unique index. | ||
* | ||
* @ORM\Column(name="email_address", unique=true, length=150) | ||
*/ | ||
protected $email; | ||
|
||
.. code-block:: yaml | ||
|
||
fields: | ||
# A string field length 255 that cannot be null | ||
# (reflecting the default values for the "length" and *nullable* options) | ||
# type attribute is necessary in YAML definitions | ||
name: | ||
type: string | ||
|
||
# A string field of length 150 that persists to an "email_address" column | ||
# and has a unique index. | ||
email: | ||
type: string | ||
column: email_address | ||
length: 150 | ||
unique: true | ||
|
||
.. code-block:: xml | ||
|
||
<!-- | ||
A string field length 255 that cannot be null | ||
(reflecting the default values for the "length" and *nullable* options) | ||
type attribute is necessary in XML definitions | ||
--> | ||
<field name="name" type="string" /> | ||
<field name="email" | ||
type="string" | ||
column="email_address" | ||
length="150" | ||
unique="true" | ||
/> | ||
|
||
.. note:: | ||
|
||
There are a few more options not listed here. For more details, see | ||
Doctrine's `Property Mapping documentation`_ | ||
|
||
.. index:: | ||
single: Doctrine; ORM console commands | ||
single: CLI; Doctrine ORM | ||
|
||
Console Commands | ||
---------------- | ||
|
||
The Doctrine2 ORM integration offers several console commands under the | ||
``doctrine`` namespace. To view the command list you can run the console | ||
without any arguments: | ||
|
||
.. code-block:: bash | ||
|
||
$ php app/console | ||
|
||
A list of available commands will print out, many of which start with the | ||
``doctrine:`` prefix. You can find out more information about any of these | ||
commands (or any Symfony command) by running the ``help`` command. For example, | ||
to get details about the ``doctrine:database:create`` task, run: | ||
|
||
.. code-block:: bash | ||
|
||
$ php app/console help doctrine:database:create | ||
|
||
Some notable or interesting tasks include: | ||
|
||
* ``doctrine:ensure-production-settings`` - checks to see if the current | ||
environment is configured efficiently for production. This should always | ||
be run in the ``prod`` environment: | ||
|
||
.. code-block:: bash | ||
|
||
$ php app/console doctrine:ensure-production-settings --env=prod | ||
|
||
* ``doctrine:mapping:import`` - allows Doctrine to introspect an existing | ||
database and create mapping information. For more information, see | ||
:doc:`/cookbook/doctrine/reverse_engineering`. | ||
|
||
* ``doctrine:mapping:info`` - tells you all of the entities that Doctrine | ||
is aware of and whether or not there are any basic errors with the mapping. | ||
|
||
* ``doctrine:query:dql`` and ``doctrine:query:sql`` - allow you to execute | ||
DQL or SQL queries directly from the command line. | ||
|
||
.. note:: | ||
|
||
To be able to load data fixtures to your database, you will need to have | ||
the DoctrineFixturesBundle bundle installed. To learn how to do it, | ||
read the ":doc:`/bundles/DoctrineFixturesBundle/index`" entry of the | ||
documentation. | ||
|
||
.. tip:: | ||
|
||
This page shows working with Doctrine within a controller. You may also | ||
want to work with Doctrine elsewhere in your application. The | ||
:method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::getDoctrine` | ||
method of the controller returns the ``doctrine`` service, you can work with | ||
this in the same way elsewhere by injecting this into your own | ||
services. See :doc:`/book/service_container` for more on creating | ||
your own services. | ||
using. To see a list of all available types and more information, see | ||
Doctrine's `Mapping Types documentation`_. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd also like to add one more sentence, though I'm very happy about all of the things you've removed!
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did a bit of rephrasing in 7af962c |
||
|
||
Summary | ||
------- | ||
|
@@ -1598,21 +1379,21 @@ that allow you to take different actions as objects go through their persistence | |
lifecycle. | ||
|
||
For more information about Doctrine, see the *Doctrine* section of the | ||
:doc:`cookbook </cookbook/index>`, which includes the following articles: | ||
:doc:`cookbook </cookbook/index>`. Some usefull articles might be: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useful |
||
|
||
* :doc:`/bundles/DoctrineFixturesBundle/index` | ||
* :doc:`/cookbook/doctrine/common_extensions` | ||
* :doc:`/cookbook/doctrine/console` | ||
* :doc:`/bundles/DoctrineFixturesBundle/index` | ||
* :doc:`/bundles/DoctrineMongoDBBundle/index` | ||
|
||
.. _`Doctrine`: http://www.doctrine-project.org/ | ||
.. _`MongoDB`: http://www.mongodb.org/ | ||
.. _`Basic Mapping Documentation`: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html | ||
.. _`Query Builder`: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/query-builder.html | ||
.. _`Doctrine Query Language`: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html | ||
.. _`Association Mapping Documentation`: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html | ||
.. _`DateTime`: http://php.net/manual/en/class.datetime.php | ||
.. _`Mapping Types Documentation`: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#doctrine-mapping-types | ||
.. _`Property Mapping documentation`: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#property-mapping | ||
.. _`Property Mapping`: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#property-mapping | ||
.. _`Lifecycle Events documentation`: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#lifecycle-events | ||
.. _`Reserved SQL keywords documentation`: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#quoting-reserved-words | ||
.. _`Persistent classes`: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#persistent-classes | ||
.. _`Property Mapping`: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#property-mapping |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
.. index:: | ||
single: Doctrine; ORM console commands | ||
single: CLI; Doctrine ORM | ||
|
||
Console Commands | ||
---------------- | ||
|
||
The Doctrine2 ORM integration offers several console commands under the | ||
``doctrine`` namespace. To view the command list you can use the ``list`` | ||
command: | ||
|
||
.. code-block:: bash | ||
|
||
$ php app/console list doctrine | ||
|
||
A list of available commands will print out. You can find out more information | ||
about any of these commands (or any Symfony command) by running the ``help`` | ||
command. For example, to get details about the ``doctrine:database:create`` | ||
task, run: | ||
|
||
.. code-block:: bash | ||
|
||
$ php app/console help doctrine:database:create | ||
|
||
Some notable or interesting tasks include: | ||
|
||
* ``doctrine:ensure-production-settings`` - checks to see if the current | ||
environment is configured efficiently for production. This should always | ||
be run in the ``prod`` environment: | ||
|
||
.. code-block:: bash | ||
|
||
$ php app/console doctrine:ensure-production-settings --env=prod | ||
|
||
* ``doctrine:mapping:import`` - allows Doctrine to introspect an existing | ||
database and create mapping information. For more information, see | ||
:doc:`/cookbook/doctrine/reverse_engineering`. | ||
|
||
* ``doctrine:mapping:info`` - tells you all of the entities that Doctrine | ||
is aware of and whether or not there are any basic errors with the mapping. | ||
|
||
* ``doctrine:query:dql`` and ``doctrine:query:sql`` - allow you to execute | ||
DQL or SQL queries directly from the command line. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a potential re-word. I originally thought we could make it a bit shorter (this is shorter, but not by much). Feel free to use this, or adapt it even further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha, just realized that you were just moving this - and that these were my (probably) original words. Well, anyways, let's hope I'm a bit better at writing than a few years ago ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was written by richard millar a year ago d376c72 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've used a mix of your and the original text
c98a3da