symfony2 - PHP - неопределенный индекс - Объединение таблиц

Я новичок в Symfony2 и разрабатываю свой первый проект, в котором я

  • 1 юридическое лицо "ejuridique", у которого есть 1 одноточечное отношение с
  • 1 объект "проект", у которого есть 1 одноточечное отношение с
  • 1 сущность "фото".

Я хотел бы иметь 1 таблицу, показывающую для каждого "ejuridique" имя ejuridique и его первую фотографию его первого проекта.

Но на данный момент я получаю сообщение об ошибке «неопределенный индекс: chl\websitesBundle\photo», когда я вызываю из контроллера свою собственную функцию с двумя каскадными левыми соединениями.

ветка "liste.html.twig"

{% for ejuridique in ejuridiques %}

            <div>
                  <div>{{ejuridique.nom}} </div>
                  <div>
                        {% for projet in ejuridique.projets %}
                             {% for photo in projet.photos %}
                                 {{photo.name}}
                             {%endfor%}
                        {%endfor%}
                  </div>
              <div>

{%endfor%}

контроллер

class websitesController extends Controller
{
    public function listeAction($page)
    {

        $em = $this                   ->getDoctrine()
                                      ->getManager();

        $ejuridiques = $em            ->getRepository('chlwebsitesBundle:Ejuridique')
                                      ->findAll();

        $projets = $em                ->getRepository('chlwebsitesBundle:Ejuridique')
                                      ->myFindAll();

        return $this->render('chlwebsitesBundle:websites:liste.html.twig', array(
        'ejuridiques'=>$ejuridiques,'projets'=>$projets));

Репозиторий ejuridique

class ejuridiqueRepository extends EntityRepository
{
    public function myFindAll()
        {
            $qb = $this->createQueryBuilder('a')
                ->leftjoin('a.projets', 'pr' )
                ->leftjoin('pr.photos', 'ph' )
                ->where('pr.projetPosition = :position_pr')
                ->ANDwhere('ph.position = :position_ph')
                ->setParameters(array('position_pr'=> "1",'position_ph'=> "1"))
                ->addSelect('pr')
                ->addSelect('ph');

            return $qb->getQuery()
                  ->getResult();
        }
}

Мои 3 объекта

юридический

class ejuridique
{

  /**
   * @ORM\OneToMany(targetEntity="chl\websitesBundle\Entity\Projet", mappedBy="ejuridique")
   * @ORM\JoinColumn(nullable=false)
   */
  private $projets;

проект

class projet
{

  /**
   * @ORM\ManyToOne(targetEntity="chl\websitesBundle\Entity\ejuridique", inversedBy="projets")
   */
  private $ejuridique;

   /**
    * @var integer
    *
    * @ORM\Column(name="projet_position", type="integer")
    */
   private $projetPosition;

  /**
   * @ORM\OneToMany(targetEntity="chl\websitesBundle\Entity\Photo", mappedBy="projet")
   * @ORM\JoinColumn(nullable=false)
   */
  private $photos;

Фото

class photo
{

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

  /**
   * @ORM\ManyToOne(targetEntity="chl\websitesBundle\Entity\projet", inversedBy="photos")
   */
  private $projet;

    /**
     * @var integer
     *
     * @ORM\Column(name="position", type="integer")
     */
    private $position;

}

Итак, со всеми этими файлами я получаю на данный момент ошибку «ContectErrorException: Note: Undefined index: chl\websitesBundle\Entity\Photo», но

  • Когда я просто вызываю из контроллера простую команду «findall()» в моем репозитории ejuridique, я получаю все ejuridique со всеми их проектами и всеми изображениями. Следовательно, я думаю, что с моими сущностями и моей БД все в порядке.

  • То же самое, когда я вызываю свою функцию «myFindAll» только с одним левым соединением между «ejuridique» и «projet» с параметрами. Все работает правильно.

  • Только когда у меня есть 2 каскадных левых соединения в моей собственной функции "myFindAll", я получаю эту ошибку

Я надеюсь, что мой вопрос ясен и что я дал всю необходимую информацию.

Спасибо заранее за вашу помощь.


person Christian Lemaire    schedule 22.05.2014    source источник


Ответы (3)


Я думаю, вы кое-что путаете (или я не совсем понял, что вы пытаетесь сделать :-D).

------ 1 ---------

Когда вы делаете это:

$projets = $em->getRepository('chlwebsitesBundle:Ejuridique')
              ->myFindAll();

вы не получаете Projet объектов, но получаете Ejuridique объектов. Функция ->leftjoin() позволяет вам выбирать (или «фильтровать») только некоторые определенные ejuridique и функцию ->addSelect() для предварительной загрузки объединенных объектов.

------ 2 ------

Когда вы делаете это:

{% for projet in ejuridique.projets %}

после этого:

return $this->render('chlwebsitesBundle:websites:liste.html.twig', array(
    'ejuridiques'=>$ejuridiques,'projets'=>$projets));

вы не получаете доступ к своей переменной $projets, вы просто получаете все Project, которые связаны с текущим ejuridique. Если вы хотите прочитать содержимое $projets, вам нужно сделать следующее:

{% for projet in projets %}

(Но обратите внимание, что это не решение в вашем случае.

Учитывая эти ошибки, я настоятельно рекомендую вам потратить некоторое время на чтение учебника. Поскольку вы говорите по-французски, я предлагаю следующее: Openclassrooms (ex-Site du Zéro) особенно этой главы.

person Blacksad    schedule 22.05.2014
comment
Сообщаю вам, что я смог написать все эти файлы после третьего дня использования symfony2, особенно благодаря уроку openclasrooms, которому я следовал. Но я понимаю ваше замечание. Я более или менее понял, что мне не нужно было писать -- array('projets'=>$projets) -- но я сделал это, потому что моя функция myFindAll показала мне ошибку индекса. - person Christian Lemaire; 24.05.2014
comment
Поэтому я хотел попробовать другое. Я понимаю, что это сбивало с толку. И я подтверждаю, что у меня есть эта ошибка индекса с моей функцией 'myFindAll', когда я использую только -- array('ejuridiques'=›$ejuridiques'). И я проверил свою БД. Все индексы кажутся хорошими. - person Christian Lemaire; 24.05.2014
comment
Прошу не видеть оскорблений в моем ответе. Я понимаю, что вы новичок (как и я не так давно), но, на мой взгляд, вам следует уделять больше времени изучению основ (например, имя класса PHP всегда начинается с заглавной буквы). Болезненное, но полезное вложение, в долгосрочной перспективе оно, вероятно, сэкономит ваше время и усилия. Особенно, если это профессиональный проект. Как вы видели, учебник Openclassroom действительно хорош, в нем действительно есть все, что вам нужно (а если нет, вы сможете найти и понять другие уроки, когда поймете, что есть в Openclassroom). Удачи и приятного времяпровождения! - person Blacksad; 26.05.2014
comment
В своем руководстве я видел, что имя класса PHP должно начинаться с заглавной буквы, но я еще не полностью интегрировался. Благодаря вам он теперь полностью интегрирован. Я думаю, что у каждого есть свой способ двигаться вперед с мотивацией. И, как вы говорите, нам весело, и я надеюсь, что вы снова поможете мне в будущем :-) - person Christian Lemaire; 26.05.2014

Просто измените это на свой контроллер:

public function listeAction($page)
{

    $em = $this->getDoctrine()->getManager();

    $ejuridiques = $em->getRepository('chlwebsitesBundle:Ejuridique')
                       ->myFindAll();     

    return $this->render('chlwebsitesBundle:websites:liste.html.twig', array(
    'ejuridiques' => $ejuridiques));
}

Вам нужен только один запрос, чтобы получить всю эту информацию :) Но то, что вы сделали, должно работать, даже если вы делаете лишние бесполезные вещи...

Я не знаю, изменит ли это что-нибудь, но обычно, когда я составляю запрос, я делаю это так:

 $qb = $this->createQueryBuilder('a')
            ->leftjoin('a.projets', 'pr' )
            ->addSelect('pr')
            ->leftjoin('pr.photos', 'ph' )
            ->addSelect('ph');
            // ...
person Rybus    schedule 22.05.2014
comment
ты прав. Это были бесполезные вещи. Но, к сожалению, его удаление не меняет мою ошибку индекса, как вы предполагали. Даже если мой индекс кажется хорошим в моей БД, я думаю, что я должен проверить таким образом. - person Christian Lemaire; 24.05.2014

Это была небольшая важная вещь в моих сущностях, например, подчеркнутая блэксадом...

Имя класса PHP должно было начинаться с заглавной буквы. Так что это может совпадать с

targetEntity="chl\websitesBundle\Entity**P**rojet

targetEntity="chl\websitesBundle\Entity**P**hoto

Я попытался поместить пластыри в свой контроллер, добавив еще одну функцию и массив непосредственно в «проект», но это лишь частично решило мою первоначальную ошибку. Контроллер, предложенный "kanalkyte", хорош.

Спасибо.

person Christian Lemaire    schedule 24.05.2014