简体   繁体   English

如何迭代Symfony 3原则findby()结果集

[英]how to iterate over symfony 3 doctrine findby() result set

I am new to symfony/doctrine and when setting up my first table and query I am struggling with the best way to output results in Twig. 我是symfony / doctrine的新手,在设置我的第一个表和查询时,我正在努力在Twig中输出结果的最佳方法。

So, I have this method on \\AppBundle\\Controller\\BrandsController 所以,我在\\ AppBundle \\ Controller \\ BrandsController上有此方法

    public function showAction($brand)
{

   $product = $this->getDoctrine()
       ->getRepository('AppBundle:Brands')
       ->findOneByBrand($brand);

   if (!$product) {
       throw $this->createNotFoundException(
           'No product found for id '.$brand
       );
   }
    return $this->render('brands/brands.html.twig', [
        'product' => $product
    ]);
}

This produces an object like below, which I cannot iterate over. 这将产生一个如下所示的对象,我无法对其进行迭代。

Brands {#459 ▼
-brand_id: 24
-brand: "Ford"
-active: "Y"
-img_logo: "/img/brand/ford.png"
-img_logo_small: "/img/brand/ford_20.png"
-img_logo_big: "/img/brand/ford-big.png"
}

Of course I can create a query like below, but that negates the benefit of the findBy() method: 当然,我可以创建如下所示的查询,但这否定了findBy()方法的优点:

$repository = $this->getDoctrine()
->getRepository('AppBundle:Brands');
$query = $repository->createQueryBuilder('p')
    ->where('p.brand = :brand')
    ->setParameter('brand', $brand)
    ->getQuery();
    $product = $query->getSingleResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);

I found similar questions, like this one , but they mess up with the array keys by giving a array that looks like: 我发现了类似的问题, 像这样 ,但是他们通过给出一个看起来像这样的数组来弄乱数组的键:

array:6 [▼
"\x00AppBundle\Entity\Brands\x00brand_id" => 24
"\x00AppBundle\Entity\Brands\x00brand" => "Ford"
"\x00AppBundle\Entity\Brands\x00active" => "Y"
"\x00AppBundle\Entity\Brands\x00img_logo" => "/img/brand/ford.png"
"\x00AppBundle\Entity\Brands\x00img_logo_small" => "/img/brand/ford_20.png"
"\x00AppBundle\Entity\Brands\x00img_logo_big" => "/img/brand/ford-big.png"
]

By the way, that's the simple version of the code on brands/brands.html.twig: 顺便说一下,这是brands / brands.html.twig上代码的简单版本:

 {% for item in product %}
      <p> This is my   {{ item }}</p>
 {% endfor %}

Is there a clean way to do it? 有没有一种干净的方法?

Thanks 谢谢

General... It's kinda bad idea to iterate through your product in twig like an array. 一般...在数组中像树枝一样遍历您的product有点不好。 Just because it's matter of time till you'll need more controll like show/do this if product is active or not... and so on. 只是因为这是时间问题,直到您需要更多的控件,例如显示/执行此操作(无论产品是否处于活动状态)等等。 So pretty soon you'll have to do somthing like this (just an wild example of possible usecase...) 很快,您将不得不做这样的事情(只是一个可能的用例的疯狂例子……)

{% if product|default %}

  {# if logo isn't there or empty or similar use path to no-logo.png as fallback  #}
  {% set _product_logo_path = product.img_logo|default('/assets/images/no-logo.png') %}

  {{ product.brand }} <img src="{{- _product_logo_path  -}}" title="blah blah" />

  {% if not product.isActive|default %}
   <span>currently unavailable</span>
  {% endif %}
{% endfi %}

Architectual... Architectual ...

You can use your repository for that kind of "manipulation" 您可以将您的存储库用于这种“操作”

something like : 就像是 :

in your controller: 在您的控制器中:

$product = $this->getDoctrine()
       ->getRepository('AppBundle:Brands')
       ->findOneForViewByBrand($brand);


// concider to use instanceof since you expecting Brands object
// if not stay with !$product
if( false === $product instanceof Brands )
{
   // not found exception..
}

in your Repo-Class 在您的Repo-Class中

public function findOneForViewByBrand( $brand )
{

  // you ca make use of PARTIAL SELECTS
  // NOTE: if you use PARTIAL selects you have to select at least id, like PARTIAL p.{brand_id}

  $query = $this->createQueryBuilder('p')
    ->select('PARTIAL p.{brand_id, brand, active, img_logo, img_logo_small, img_logo_big}')
    ->where('p.brand = :brand')
    ->setParameter('brand', $brand)
    ->getQuery();


  // If found you'll get a Brand BUT ONLY field in curly brackets will be populated with data, others will be just NULL
  return $query->getOneOrNullResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY); 


}

and then in your twig 然后在你的树枝上

{% for fieldName, fieldValue in product %}
      {# should skip null values #}
      {% if fieldValue is defined and fieldValue is not empty % }
      <p> This is my   {{ fieldValue }}</p>
     {% endif %}
 {% endfor %}

About Partial Selects 关于部分选择

PS code is untested and it's here so you can get an idea ;) I don't know what version of symfony you use and what version of doctrine is installed, so if one of mentioned methods doesn't exists - please don't be angry :) PS 代码未经测试 ,就在这里,您可以有所了解;)我不知道您使用的是哪个symfony版本以及安装了哪个版本的doctrine,因此,如果上述方法之一不存在-请不要生气:)

The idea is to use Entity Serializer Doctrine Script , look to the link below : https://github.com/borisguery/bgylibrary/blob/master/library/Bgy/Doctrine/EntitySerializer.php 这个想法是使用Entity Serializer Doctrine Script ,请看下面的链接: https : //github.com/borisguery/bgylibrary/blob/master/library/Bgy/Doctrine/EntitySerializer.php
Just copy the script into a new class : EntitySerializer.php , under AppBundle\\Controller , then in your BrandsController class: 只需将脚本复制到新类: EntitySerializer.php ,位于AppBundle\\Controller ,然后在AppBundle\\Controller类中:

$em = $this->getDoctrine()->getManager(); 
$product = $em->getRepository('AppBundle:Brands') ->findOneByBrand($brand); 
$serializer = new EntitySerializer($em);
$product = $serializer->toArray($product);

and finnally you can easily iterate the array : 最后,您可以轻松地迭代数组:

foreach ($array as $key => $value) {
    echo 'the key is '.$key.'<br>';
    echo 'the value is '.$value;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM