I want to get the results in array for this code:
$person = $em->find('Person', 2);
I am using doctrine 2. I want the above result in array form. .
PHP version 5.4
The best approach is to write method in your Repository class or create query builder inline (but it is not recommended).
use Doctrine\ORM\Query;
...
$qb = $em->getRepository(Person::class)->createQueryBuilder('p');
$qb
->andWhere('p.id = :id')
->setParameter('id', $id)
;
$person = $qb->getQuery()->getResult(Query::HYDRATE_ARRAY);
Replace
$qb->getQuery()->getResult(Query::HYDRATE_ARRAY)
by
$qb->getQuery()->getOneOrNullResult(Query::HYDRATE_ARRAY)
if you need to get only one element.
I have found a solution :
$person = $em->find('Person', 2);
$personx = json_decode(json_encode((array)$person), true);
echo '<pre>';
print_r($personx);
echo '<pre>';
It is working perfectly for me.
As $person may be object with circular references, it can not be converted to array directly, but you can use serializing, like it described here
Symfony Serialize doctrine entity
Or you can do it manually:
$person_array = ['name' => $person->getName(), 'id' => $person->getId()];
Related
I have the following code in an entity repository:
$rows = $this->createQueryBuilder('t')
->select(['t.idColumn', 't.valueColumn'])
->where('t.foo = :foo')
->orderBy('t.idColumn', 'ASC')
->setParameter('foo', $foo)
->getQuery()
->getArrayResult(); // This returns [[idColumn => ..., valueColumn => ...], ...]
$data = [];
foreach ($rows as $row) {
$data[$row['idColumn']] = abs($row['valueColumn']); // Remapping to [id => value]
}
return $data;
Is there any way to get rid of the custom remapping natively? I know that you can use the indexBy parameter, but that only gets me the correct keys but not values.
P.S. I know of array_column(), but that's an extra step that I have to make every time, not to mention it doesn't work on methods that entities have.
P.P.S. This is not using Symfony.
It does not appear this is a feature implemented in the QueryBuilder, however fetchAllKeyValue was added in DBAL 2.11 to the Connection object.
Commit, usage
I'm using a personal request in symfony witch is:
public function findByReferenceUser($Reference, $User)
{
$qb = $this->createQueryBuilder('a')
->select('a')
->join('a.Reference', 'r')
->where('r.id = :refId')
->setParameter("refId", $Reference->getId())
->join('a.User', 'u')
->andWhere('u.id = :userId')
->setParameter("userId", $User->getId());
return $qb->getQuery()->getOneOrNullResult();
}
But it doesn't work properly.
I'm getting 3 results witch are of type NULL,NULL, Boolean. I'm using this to check it:
$list_article = $RArticle->findByReferenceUser($reference, $panier->getUser());
foreach ($list_article as $key => $article)
echo gettype($article);
My database works, and have the right informations.
Finnaly, this works:
$list_article = $RArticle->findAll();
foreach ($list_article as $key => $article)
echo gettype($article);
And print object, object.
So there is my questions: Why do I get NULL, NULL, Boolean in the first case and how do I fixe it?
Thank you for your help! :)
When using getOneOrNullResult, Doctrine will Retrieve a single object. If no object is found null will be returned. here.
If you want several object, you should use getResult
findAll() returns array of objects, such as array('key' => 'object'), that's why you are getting correct records, getOneOrNullResult() returns single object (not array, foreach won't work), if you want to retrieve multiple records you need to use getResult()
I have a controller where I want to combine data from multiple tables with parallel structures. What I want to end up with in the end is one object I can return from the controller so I can parse it in Backbone.
I want to do something like this:
public function index()
{
$mc = MainContact::where('verified', '=', '1')->get();
$sm = SendMessage::where('verified', '=', '1')->get();
$obj = (object) array_merge((array) $mc, (array) $sm);
return $obj;
}
I'm told by another post on StackOverflow that this works in PHP 5.3+. However, this returns the following error in Laravel:
UnexpectedValueException: The Response content must be a string or object implementing
__toString(), "object" given.
How do I implement this method in Laravel? Both $mc and sm return valid objects in Laravel.
Nowadays you can use
$new_collection = $collection->merge($other_collection).
This works in Laravel 4 and seems to handle both arrays and collections.
What you can do here is merge the arrays of the two query result and then use the Response with json output like shown below.
$array = array_merge($mc->toArray(), $sm->toArray());
return Response::json($array);
We can use collection as below
$admins = User::where('type', '=', 'admin')->get();
$authors = User::where('type', '=', 'author')->get();
$admin_author_collection = $admins->merge($authors);
Also, Please refer the various collection methods to below link
http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html
Route::get('test', function(){
$rank = Rank::get();
$policy = Policy::get();
$obj = (object)array_merge_recursive((array)$rank , (array)$policy);
var_dump($obj);
});
This is working for me. Instead of array_merge use array_merge_recursive().
You could simply use array_merge(firstObject,secondObject) function.
$obj = array_merge($mc, $sm);
return $obj;
I want to get an array of values from the id column of the Auction table.
If this was a raw SQL I would write:
SELECT id FROM auction
But when I do this in Doctrine and execute:
$em->createQuery("SELECT a.id FROM Auction a")->getScalarResult();
I get an array like this:
array(
array('id' => 1),
array('id' => 2),
)
Instead, i'd like to get an array like this:
array(
1,
2
)
How can I do that using Doctrine?
PHP < 5.5
You can use array_map, and since you only have on item per array, you can elegantly use
'current' as callback, instead of writing a closure.
$result = $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult();
$ids = array_map('current', $result);
See Petr Sobotka's answer below for additional info regarding memory usage.
PHP >= 5.5
As jcbwlkr's answered below, the recommended way it to use array_column.
As of PHP 5.5 you can use array_column to solve this
$result = $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult();
$ids = array_column($result, "id");
A better solution is to use PDO:FETCH_COLUMN . To do so you need a custom hydrator:
//MyProject/Hydrators/ColumnHydrator.php
namespace DoctrineExtensions\Hydrators\Mysql;
use Doctrine\ORM\Internal\Hydration\AbstractHydrator, PDO;
class ColumnHydrator extends AbstractHydrator
{
protected function hydrateAllData()
{
return $this->_stmt->fetchAll(PDO::FETCH_COLUMN);
}
}
Add it to Doctrine:
$em->getConfiguration()->addCustomHydrationMode('COLUMN_HYDRATOR', 'MyProject\Hydrators\ColumnHydrator');
And you can use it like this:
$em->createQuery("SELECT a.id FROM Auction a")->getResult("COLUMN_HYDRATOR");
More info:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#custom-hydration-modes
Ascarius' answer is elegant, but beware of memory usage! array_map() creates a copy of passed array and effectively doubles memory usage. If you work with hundreds of thousands of array items this can become an issue. Since PHP 5.4 call-time pass by reference has been removed so you cannot do
// note the ampersand
$ids = array_map('current', &$result);
In that case you can go with obvious
$ids = array();
foreach($result as $item) {
$ids[] = $item['id'];
}
Since doctrine/orm 2.10.0 there is a built-in solution for this:
use Doctrine\ORM\AbstractQuery;
$query = $em->createQuery("SELECT a.id FROM Auction a");
return $query->getSingleColumnResult();
// Same as:
return $query->getResult(AbstractQuery::HYDRATE_SCALAR_COLUMN);
Docs: https://www.doctrine-project.org/projects/doctrine-orm/en/2.10/reference/dql-doctrine-query-language.html#scalar-column-hydration
I think it's impossible in Doctrine.
Just transform result array into the data structure you want using PHP:
$transform = function($item) {
return $item['id'];
};
$result = array_map($transform, $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult());
I am able to fetch my data from database by using this structure:
$user = $this->getDoctrine()
->getRepository('AcmeDemoBundle:Emails')
->find(8081);
When I do that, I am able to get my data like this:
$user->getColumnNameHere();
Basically I am able to use Entity Class.
But if I want to use QueryBuilder instead of find I am only getting associative arrays.
$product->createQueryBuilder('p')
->setMaxResults(1)
->where('p.idx = :idx')
->select('p.columnNameHere')
->setParameter('idx', 8081)
->orderBy('p.idx', 'DESC')
->getQuery();
$product = $query->getResult();
$product returnds as array. Is it possible to fetch it withj Entity Managaer Class? If yes, how?
I digg the documentation but it seems not possible or not exist in the doc or I'm just blind :)
Yes you can, usually using:
$repository
->createQueryBuilder('p')
->getQuery()
->execute()
;
This should return you an array of entities.
If you want to get a single entity result, use either getSingleResult or getOneOrNullResult:
$repository
->createQueryBuilder('p')
->getQuery()
->getOneOrNullResult()
;
Warning: These method can potentially throw NonUniqueResultException.
Edit: Ok, so the question was about partial objects: http://docs.doctrine-project.org/en/latest/reference/partial-objects.html
you can get an object instead of array by using "Partial Objects".
here is a tested example with DoctrineORM 2.2.2:
// create query builder
// $em is the EntityManager
$qb = $em->createQueryBuilder();
// specify the fields to fetch (unselected fields will have a null value)
$qb->select ('partial p.{id,pubDate,title,summary}')
->from ('Project\Entity\Post', 'p')
->where ('p.isActive = 1')
->orderBy ('p.pubDate', 'desc');
$q = $qb->getQuery();
$result = $q->getResult();
var_dump($result); // => object
If you wish to return an object from your original query:
$product->createQueryBuilder('p')
->setMaxResults(1)
->where('p.idx = :idx')
->select('p.columnNameHere')
->setParameter('idx', 8081)
->orderBy('p.idx', 'DESC')
->getQuery();
$product = $query->getResult();
Remove this line
->select('p.columnNameHere')
As soon as you use select, it will return an array...
getResult() method returns a collection (an array) of entities. Use getSingleResult() if you're going to fetch only one object.
EDIT:
Oh, I just noticed that you want to fetch a single field of a single object. Use getSingleScalarResult() as #Florian suggests.