Whenever I use an ArrayCollection with Doctrine ORM (2.3, PHP > 5.4), and associate the object values with a key in the collection (such as when using the set
method), the values get stored correctly in the database. But when I want to retrieve the collection from the entity, the keys don't get retrieved and instead they use a numeric index.
For instance, if I have the following classes:
/** @Entity */
class MyEntity
{
/** @OneToMany(targetEntity="MyOtherEntity", mappedBy="mainEntity") */
private $myArray;
public function __construct()
{
$this->myArray = new ArrayCollection();
}
public function addOtherEntity($key, $value)
{
$this->myArray->set($key, $value);
}
...
}
/** @Entity */
class MyOtherEntity
{
/** @ManyToOne(targetEntity="MyEntity", inversedBy="myArray") */
private $mainEntity;
...
}
The set
method works properly, but when I retrieve the information the keys in $myArray
are gone.
How do I make the ORM remember properly the keys? Thank you beforehand.
To sort an existing Collection you are looking for the ArrayCollection::getIterator () method which returns an ArrayIterator. example: The easiest way would be letting the query in the repository handle your sorting.
Doctrine criteria does not allow to order by a property on a related object. If you want to do it (like me), you have to use the uasort method of the Iterator like a previous response and if you use PHP 7, you can use the Spaceship operator <=> like this : Show activity on this post.
If you have an ArrayCollection field you could order with annotations. eg: Say an Entity named Society has many Licenses. You could use That will order the ArrayCollection by endDate (datetime field) in desc order.
This is solved in the following way:
/** @Entity */
class MyEntity
{
/** @OneToMany(targetEntity="MyOtherEntity", mappedBy="mainEntity", indexBy="key") */
private $myArray;
public function __construct()
{
$this->myArray = new ArrayCollection();
}
public function addOtherEntity($key, $value)
{
$this->myArray->set($key, $value);
}
...
}
/** @Entity */
class MyOtherEntity
{
/** @ManyToOne(targetEntity="MyEntity", inversedBy="myArray") */
private $mainEntity;
/** @Column(name="MyOtherTable_Key", type="string", unique=true, length=50)
private $key;
...
}
You also need MyOtherTable_Key
in your db schema so it can store the key properly.
Remember to always set the object key into the property. One way to do so is to declare the key in the constructor.
public function __construct($key)
{
$this->key = $key;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With