我有一些相关实体,为了方便起见
Product
和Category
。它们是相关的 OneToMany 和 ManyToOne。 (每个产品一类,一类多产品)
我的目标是在模板中显示所有类别及其所有产品,但按字母顺序排列。例如这样:
家具
膳食
办公室
我希望对类别和产品进行排序。
所以:
方法1
使用原则编写查询以获取按名称 ASC 订购的所有类别,并获取按名称 ASC 订购的所有产品,然后在模板中:
{% for c in all_categories %}
{{ c.name }}
{% for p in all_products %}
{% if p.category == c %}
{{ p.name }}
{% endif %}
{% endfor %}
{% endfor %}
方法2
仅获取类别,无论它们如何排序。将 fetch 更改为 eager。然后编写一个排序过滤器作为 Twig Extension,如下所示:
public function sortByName($a, $b)
{
if($a->getName() === $b->getName()) {
return 0;
}
if($a->getName() < $b->getName()) {
return -1;
}
return 1;
}
并使用迭代器和
uasort()
与此函数,然后在模板中:
{% for c in all_categories|sortbyname %}
{{ c.name }}
{% for p in c.products|sortbyname %}
{{ p.name }}
{% endfor %}
{% endfor %}
我可以看到,在1中,if 检查很糟糕,因为许多检查都是多余的。当我已经拥有所有类别时获取所有产品也是多余的。但我认为用 Doctrine 排序应该比用 twig 扩展排序更快。所以我不知道该使用哪一个。如果重要的话,就我而言,我有 3 个实体,如下所示:每个商店都有类别,每个类别都有产品。
你能帮我吗?预先非常感谢! :)
这更多的是一个算法选择,而不是一个 symfony/学说问题。
我的方法是让所有产品按(类别名称,产品名称)排序,然后循环它们以将它们存储在按类别索引的数组中。如果您有许多产品,并且有足够的内存来一次加载所有对象,则可以使用它,但速度会更快(#nbproducts,而不是#nbproducts*#nbcategories),并且仅使用一个 ORM 请求,该请求将使用索引来对数据进行排序。
Php 代码如下所示:
$sorted_products = array();
foreach ($products as $product) {
$category = $product->getCategory();
if (!array_key_exists($category->getId(), $sorted_products)) {
$sorted_products[$category->getId()] = array('category' => $category, 'products' => array());
}
$sorted_products['products'][] = $product;
}
然后你只需要在你的树枝上做 2 次 foreach :
{% for category_infos in sorted_products %}
{{ category_infos.category.name }}
{% for product in category_infos.products %}
{{ product.name }}
{% endfor %}
{% endfor %}