Pomm Bundle такой же spl_object_hash, но объект другой
Я использую Pomm bundle для моего проекта Symfony, и у меня возникла проблема: я создал сложный запрос и мой экземпляр результата стал одним и тем же объектом с разными атрибутами. Это только для примера, но этот запрос имеет отношение один -> многие
Я знаю, что этот запрос (1 -> много) не корректен с точки зрения отношений, однако я хотел бы понять, как pomm bundle me генерирует дважды одну и ту же ссылку на объект
public function getSousFamilleParametreListing(Where $condition = null,$locale='fr')
{
$sql ="
select
{projection}
from
{sousfamilleparametre} sfp
inner join {parametre} par ON sfp.\"Parametre\" = par.\"ID\"
inner join {parametre_valeur} pav ON pav.\"Parametre\" = sfp.\"Parametre\"
inner join {valeur} val ON pav.\"Valeur\" = val.\"ID\"
where {condition}
order by sfp.\"Niveau\", sfp.\"Pos\", pav.\"Pos\""
;
$projection = $this->createProjection()
->setField('nom_param','par."Nom"','text')
->setField('type_param','par."Type"','text')
->setField('pos_valeur', 'pav."Pos"','text')
->setField('Valeur', 'val."ID"','text')
->setField('nom_valeur','val."Nom"','text')
->setField('couleur_valeur','val."ValCouleur"','text')
->setField('sur_mesure','val."SurMesure"','boolean');
$parametre = $this->getSession()
->getModel(ParametreModel::class);
$valeur = $this->getSession()
->getModel(ValeurModel::class);
$parametre_valeur = $this->getSession()
->getModel(ParametrevaleurModel::class);
$condition = (new Where)->andWhere($condition);
$sql = strtr(
$sql,
[
'{projection}' => $projection->formatFieldsWithFieldAlias('sfp'),
'{sousfamilleparametre}'=> $this->structure->getRelation(),
'{parametre}' => $parametre->getStructure()->getRelation(),
'{valeur}' => $valeur->getStructure()->getRelation(),
'{parametre_valeur}' => $parametre_valeur->getStructure()->getRelation(),
'{locale}' => $locale,
'{condition}' => $condition,
]
);
return $this->query($sql,$condition->getValues(),$projection);
}
И результат var_dump:
object(AppBundle\Entity\Model\MyDb1\PublicSchema\Sousfamilleparametre)#574 (2) {
["container":protected]=>
array(11) {
["SousFamille"]=>
int(8)
["Parametre"]=>
int(375)
["Pos"]=>
int(0)
["Niveau"]=>
int(1)
["nom_param"]=>
string(6) "TAILLE"
["type_param"]=>
string(1) "6"
["pos_valeur"]=>
string(1) "0"
["Valeur"]=>
string(1) "7"
["nom_valeur"]=>
string(2) "T1"
["couleur_valeur"]=>
string(7) "#4F4FFF"
["sur_mesure"]=>
bool(false)
}
["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
int(1)
}
string(32) "0000000067acae310000000004f8d20f"
object(AppBundle\Entity\Model\MyDb1\PublicSchema\Sousfamilleparametre)#574 (2) {
["container":protected]=>
array(11) {
["SousFamille"]=>
int(8)
["Parametre"]=>
int(375)
["Pos"]=>
int(0)
["Niveau"]=>
int(1)
["nom_param"]=>
string(6) "TAILLE"
["type_param"]=>
string(1) "6"
["pos_valeur"]=>
string(1) "1"
["Valeur"]=>
string(1) "8"
["nom_valeur"]=>
string(2) "T2"
["couleur_valeur"]=>
string(7) "#2424FF"
["sur_mesure"]=>
bool(false)
}
["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
int(1)
}
string(32) "0000000067acae310000000004f8d20f"
3 ответа
ОК, спасибо за ваш ответ.
В моем проекте SF я должен работать с существующей базой данных postgresql (иначе я буду использовать Doctrine для управления моей базой данных)
База - это не "объект" и не "сеть", я иногда вынужден делать запросы, заставляющие меня беспокоиться о столкновении объектов.
Однако я нашел хитрость, создав "представления", которые возвращают в точности те же строки, что и моя сопоставленная сущность, но с новым автоматическим приращением "ID" на основе моего представления.
Это не самый чистый метод, но в моем случае он работает отлично.
Как только промежуточное ПО предоставляет объектно-ориентированное представление строк базы данных, оно должно столкнуться с проблемой: что делать, если строка выбирается дважды даже из двух разных запросов? Pomm использует средство идентификации для отслеживания выбранных объектов.
Устройство отображения идентификаторов использует первичный ключ объекта для распознавания строки. Каждый раз, когда строка выбирается из итератора, если она уже присутствует в преобразователе объектов, объект обогащается новыми значениями и возвращается. Это означает, что извлеченные строки хранятся в памяти, что может быть проблемой, если много записей прочитано.
Давайте рассмотрим пример столкновения:
Столкновение происходит только тогда, когда я объединяю два массива объектов в один массив. Независимость от $ перечисления_value и $ перечисления_value2, даже если у него одинаковые объекты, это не создает столкновения.
Проверьте пример:
$listing_valeur = $this->get('pomm')
->getDefaultSession()
->getModel(ParametrevaleurModel::class)
->getParametreValeur(new Where("pav.\"Parametre\" in ($custom)",$tab_id),
"position(pav.\"Parametre\"::text in '".join(',',$tab_id)."')",
$request->getLocale());
$listing_valeur2 = $this->get('pomm')
->getDefaultSession()
->getModel(ParametrevaleurModel::class)
->getParametreValeur(new Where("pav.\"Parametre\" in ($custom)",$tab_id),
"position(pav.\"Parametre\"::text in '".join(',',$tab_id)."')",
$request->getLocale());
$tab=array();
foreach ($listing_valeur as $key => $value) {
//DUMP1
echo "<pre>";
var_dump($value);
echo "</pre>";
$tab[] = $value;
}
foreach ($listing_valeur2 as $key1 => $value1) {
$value1->set('Pos',10);
//DUMP2
echo "<pre>";
var_dump($value1);
echo "</pre>";
//$value & $value1 same spl_object_hash bug value different on POS
$tab[] = $value1;
}
echo "<hr>";
foreach ($tab as $key => $value) {
//WHEN ITERATE TAB COLLISION OBJET POS = 10 on VALUE & VALUE1
echo "<pre>";
var_dump($value);
echo "</pre>";
}
echo "dump1A<br/>";
foreach ($listing_valeur as $key => $value) {
//DUMP1A
echo "<pre>";
var_dump($value);
echo "</pre>";
$tab[] = $value;
}
Dump1:
object(AppBundle\Entity\Model\MyDb1\PublicSchema\Parametrevaleur)#591 (2) {
["container":protected]=>
array(6) {
["Parametre"]=>
int(375)
["Valeur"]=>
int(7)
["Pos"]=>
int(0)
["nom_valeur"]=>
string(2) "T1"
["couleur_valeur"]=>
string(7) "#4F4FFF"
["sur_mesure"]=>
bool(false)
}
["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
int(1)
}
Dump2:
object(AppBundle\Entity\Model\MyDb1\PublicSchema\Parametrevaleur)#591 (2) {
["container":protected]=>
array(6) {
["Parametre"]=>
int(375)
["Valeur"]=>
int(7)
["Pos"]=>
int(10)
["nom_valeur"]=>
string(2) "T1"
["couleur_valeur"]=>
string(7) "#4F4FFF"
["sur_mesure"]=>
bool(false)
}
["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
int(3)
}
dump3 (итерация по вкладке)
object(AppBundle\Entity\Model\MyDb1\PublicSchema\Parametrevaleur)#591 (2) {
["container":protected]=>
array(6) {
["Parametre"]=>
int(375)
["Valeur"]=>
int(7)
["Pos"]=>
int(10)
["nom_valeur"]=>
string(2) "T1"
["couleur_valeur"]=>
string(7) "#4F4FFF"
["sur_mesure"]=>
bool(false)
}
["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
int(3)
}
object(AppBundle\Entity\Model\MyDb1\PublicSchema\Parametrevaleur)#591 (2) {
["container":protected]=>
array(6) {
["Parametre"]=>
int(375)
["Valeur"]=>
int(7)
["Pos"]=>
int(10)
["nom_valeur"]=>
string(2) "T1"
["couleur_valeur"]=>
string(7) "#4F4FFF"
["sur_mesure"]=>
bool(false)
}
["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
int(3)
}
Dump1A:
object(AppBundle\Entity\Model\MyDb1\PublicSchema\Parametrevaleur)#591 (2) {
["container":protected]=>
array(6) {
["Parametre"]=>
int(375)
["Valeur"]=>
int(7)
["Pos"]=>
int(0)
["nom_valeur"]=>
string(2) "T1"
["couleur_valeur"]=>
string(7) "#4F4FFF"
["sur_mesure"]=>
bool(false)
}
["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
int(3)
}