Symfony2 and Doctrine - returns the database result as an array of arrays in the controller

Doing this in the symfony2 controller leads to an array where each individual result is an object in itself. But I need it to be an array, so I can easily json_encode the entire list

$em->getRepository('MyBundle:Report')->findByEvaluation($evaluation_id, \Doctrine\ORM\Query::HYDRATE_ARRAY) 

So, how do I get an array of arrays, not an array of objects, what do I get with HYDRATE_ARRAY?

+4
source share
2 answers

As a result, I installed the JMSSerializerBundle , which provides the methods I need. Since I had a related object and I do not need a related object, in my entity class I now have

 ... use JMS\SerializerBundle\Annotation\ExclusionPolicy; use JMS\SerializerBundle\Annotation\Exclude; /** * Iddp\RorBundle\Entity\Report * * @ORM\Table() * @ORM\Entity(repositoryClass="Iddp\RorBundle\Entity\ReportRepository") * @ExclusionPolicy("None") */ class Report 

By adding @ExclusionPolicy ("No"), all properties should be serialized, except those marked as exclude. Then in related functions in one class just add exclude annotation

 /** * @ORM\ManyToOne(targetEntity="Client", inversedBy="reports") * @ORM\JoinColumn(name="client_id", referencedColumnName="id") * @Exclude */ protected $client; 

and so in the controller I can now (after adding the use of Symfony \ Component \ HttpFoundation \ Response;)

 $serializer = $this->container->get('serializer'); $reports = $serializer->serialize($reports, 'json'); return new Response($reports); 

What is it. Symfony + Doctrine can make some simple things complicated.

+4
source

It is impossible, outside the box, to tell Doctrine to process the object as an array. However, with a few tweaks and some dubious design decisions, you can achieve this.

The first thing you need to do is create a base class (to extend your classes) that implements the ArrayAccess interface. An article describing this can be found in the Doctrine Cookbook . It will look something like this:

 abstract class DomainObject implements ArrayAccess { public function offsetExists($offset) { return isset($this->$offset); } public function offsetSet($offset, $value) { throw new BadMethodCallException( "Array access of class " . get_class($this) . " is read-only!" ); } public function offsetGet($offset) { return $this->$offset; } public function offsetUnset($offset) { throw new BadMethodCallException( "Array access of class " . get_class($this) . " is read-only!" ); } } 

Then, when you create model classes (or at least the ones you want to treat as arrays), you need to extend this DomainObject class. The last part of the puzzle is to make your class properties public, to give the json_encode function the ability to check your class properties and use them as keys for the json object.

NB : using publicly available properties in classes can lead to a lot of difficulties in tracking errors and is generally considered questionable practice. this is just an example of what i was whipping quickly to illustrate how this can be done. I am sure there is a more elegant way to implement this, which does not require public properties. This solution is intended only to get ball rolling.

An example domain class might look something like this:

 class Tester extends DomainObject { public $foo; public $bar; public function __construct($foo, $bar) { $this->foo = $foo; $this->bar = $bar; } } 

Now you can pass an instance of the Tester class to an array and pass this array to json_encode:

 $test = new Tester('Hello', 'World'); echo json_encode((array)$test); 

Which will produce the following output:

 {"foo":"Hello","bar":"World"} 

EDIT : just return the code snippet to the context. You no longer need to use HYDRATE_ARRAY, it will look like this:

 $results = $em->getRepository('MyBundle:Report')->findByEvaluation($evaluation_id); foreach ($results as $result) { echo json_encode((array)$result); } 

if the Report class extends the DomainObject class defined above.

+2
source

Source: https://habr.com/ru/post/1386040/


All Articles