Keeping Hyrdrated
When working with Doctrine, the returned result we would expect from a good query would either be an Object, or an array of Objects.
You will very likely have used findBy
and findOneBy
, and they are examples of Doctrine returning an Object, or an array of Objects.
So far, so good.
But what if we want to return our result set as an array, or an array of arrays?
What if we just want to return a single integer, or a string?
If we don't need to do anything beyond basic display of our data, we don't really need Doctrine to waste time re-hydrating our Objects. A plain old array, or integer, or string would work just as well, if not even better.
The Hydration Station
Hydrating my what now?
Indeed. When I first heard the term Hydration, I didn't really get it.
But, as it turns out with most things, it's a slightly confusing sounding name for a simple concept.
Hydrating objects starts to make sense when you understand the definition.
Hydration is the process of filling an empty Object with data.
Let's say we have a Topic entity, with a title
, an author
, and an id
.
When we pull that record back out of the database, we want to fill it back up with the data we have stored. We pour the data returned by the query back into the object - hydrating it.
As we saw in the previous video, we can also Partially Hydrate an object.
Hydration Modes
There are four methods of hydration supplied by Doctrine 'out of the box', and you can also create your own custom hydration modes if the following don't fit your needs:
- Query::HYDRATE_OBJECT
- Query::HYDRATE_ARRAY
- Query::HYDRATE_SCALAR
- Query::HYDRATE_SINGLE_SCALAR
- Custom hydration
We've already been through hydrating to Objects.
Query::HYDRATE_ARRAY
Hydrating to an array returns your object 'flattened' to an array. That is to say, if you had a Topic
object with id
, title
, and author
, and you returned your object as an array, your output would be usable something similar to this:
$topics = $qb->select('t')
->from('AppBundle:Topic', 't')
->getQuery()
->getResult(Query::HYDRATE_ARRAY)
;
$result[0]['id'] = 3;
$result[0]['title'] = 'my title';
$result[0]['author'] = 'joe smith';
Query::HYDRATE_SCALAR
Scalar hydration is similar to Array hydration in terms of the returned result set being an array of arrays.
The difference is in how the array properties are named - they get prefixed with whatever letter / name you gave in your DQL select
query, e.g:
$topics = $qb->select('t')
->from('AppBundle:Topic', 't')
->getQuery()
->getResult(Query::HYDRATE_SCALAR)
;
$topics[0]['t_id'] = 3;
$topics[0]['t_title'] = 'my title';
$topics[0]['t_author'] = 'joe smith';
Query::HYDRATE_SINGLE_SCALAR
And then can be useful if you need to return the value of a count
or perhaps some individual integer or such like.
You might use it something like this:
$topics = $qb->select('count(t.id)')
->from('AppBundle:Topic', 't')
->getQuery()
->getResult(Query::HYDRATE_SINGLE_SCALAR)
;
$topics === 36; // or whatever the resulting count would be
Convenience Methods
Having to use constants as demonstrated above is a little messy.
Doctrine provides us with some helpful convenience methods to remove the requirement.
As such, we can replace the ->getQuery()->getResult(CONSTANT_HERE);
with something a little more explicit:
->getResult()
->getArrayResult()
->getScalarResult()
->getSingleScalarResult()
e.g:
$topics = $qb->select('count(t.id)')
->from('AppBundle:Topic', 't')
->getQuery()
->getSingleScalarResult()
;
$topics === 36; // or whatever the resulting count would be
That's really all there is to it.
Hydration is basically a big word for something you will likely already know about, and use regularly, even if you weren't aware of it.