在while循环中进行foreach
Posted
技术标签:
【中文标题】在while循环中进行foreach【英文标题】:Foreach in a while loop 【发布时间】:2012-01-12 13:09:01 【问题描述】:我有两张表:“汽车”和“经销商”:
汽车表
id_car | name_car | etc.
----------------------------
1 | A3 Sportback | etc.
2 | Ranger | etc.
3 | Transit Van |etc.
4 | Cayman | etc.
etc. | etc. | etc.
经销商表
在 deal_cars 列中,我将对应汽车的 id 作为数组插入。
deal_id | deal_name | deal_cars | etc.
--------------------------------------
1 | Ford | 2,3 | etc.
2 | Audi | 1 | etc.
3 | Porsche | 4 | etc.
etc. | etc. | etc. |
我会得到一个显示以下信息的页面:
经销商名称 - 汽车
福特 – Ranger、Transit Van 奥迪 – A3 Sportback Cayman – 保时捷我可以提取经销商名称,但我不知道如何从 ids 中提取汽车名称。
我试过了:
$dealerships_sql = $data->query("SELECT * FROM dealerships ORDER BY deal_name ASC");
while($dealerships_obj = $data->extract($dealerships_sql))
//Dealerships data
$deal_id[] = $dealerships_obj->deal_id;
$deal_name[] = $dealerships_obj->deal_name;
etc etc
//Try to get cars ids and turn them in cars names.
$deal_cars[] = $dealerships_obj->deal_cars;
$deal_cars[] = explode(',',$deal_cars);
$cars = array();
foreach ($deal_cars AS $deal_car)
$cars_sql = $data->query("SELECT name_car FROM cars WHERE id_car = '$deal_car'");
while($cars_obj = $data->extract($cars_sql))
$cars[] = stripslashes($cars_obj->name_car)." ";
我使用 smarty 作为模板引擎,所以我分配了一些变量:
$smarty->assign ("deal_id", $deal_id);
$smarty->assign ("deal_name", $deal_name);
etc etc.
$smarty->assign ("cars", $cars);
我的模板是:
<table border="1">
<tr>
<td>Dealership</td>
<td>Cars</td>
</tr>
section name="foo" loop=$deal_name
<tr>
<td>$deal_name[foo]</td>
<td>$cars[foo]</td>
</tr>
/section
</table>
但代码返回:
福特 - 游侠 奥迪 – A3 Sportback Cayman – 保时捷它只显示每个经销商的第一辆车(数组中找到的第一个元素)。我该如何解决这个问题?
【问题讨论】:
JOIN
会帮助你。开始here。
你应该阅读规范化。您的deal_cars
列不满足第一范式。
【参考方案1】:
我认为您的数据库设计不适合这里。
汽车表
id_car | name_car | etc.
----------------------------
1 | A3 Sportback | etc.
2 | Ranger | etc.
3 | Transit Van | etc.
4 | Cayman | etc.
etc. | etc. | etc.
经销商表
deal_id | deal_name | etc.
---------------------------
1 | Ford | etc.
2 | Audi | etc.
3 | Porsche | etc.
etc. | etc. |
经销商到汽车表
dealerid | carid
1 | 2
1 | 3
2 | 1
etc. | etc.
如您所见,我为这两个表之间的关系制作了另一个表。
$dealerships_sql = $data->query("SELECT * FROM dealerships ORDER BY deal_name ASC");
$dealers = array();
while($dealerships_obj = $data->extract($dealerships_sql))
//Dealerships data, use object
$dealerid = $dealerships_obj->deal_id;
$dealers[$dealerid]['dealer'] = $dealerships_obj;
// Cars
$cars = array();
$car_sql = $data->query("SELECT name_car FROM cars JOIN dealerToCars ON carid = id_car JOIN dealer ON deal_id = dealerid WHERE deal_id = " . $dealerid);
// now you have all cars from the selected dealer
while ($cars_obj = $data->extract($car_sql))
$cars[] = stripslashes($cars_obj->name_car);
// Assign Cars to dealer
$dealers[$dealerid]['cars'] = $cars;
现在您在 $dealers 中拥有所有经销商及其汽车。
由于您使用 smarty,只需将整个数组传递给 smarty 并让其余部分在其模板中执行 smarty。 Smarty 可以使用数组和对象,所以不需要拆分成多个数组:
$smarty->assign ("dealers", $dealer);
因为我不知道你的类,你可能需要添加一些 getter 或 setter 或者只是将属性公开,以便 smarty 可以访问它们:
<table border="1">
<tr>
<td>Dealership</td>
<td>Cars</td>
</tr>
foreach $dealers as $dealer
<tr>
<td>$dealer['dealer']->deal_name</td>
<td>foreach $dealer['cars'] as $car$car, /foreach</td>
</tr>
/foreach
</table>
也许你需要看看模板中的标识符。
(我为此使用 smarty 3)
【讨论】:
【参考方案2】:我认为您应该为每辆车设置一个经销商行(这将允许您通过 JOIN 获取所有信息并轻松解析所有信息)。
【讨论】:
【参考方案3】:最好的方法是一次得到所有东西,你可以这样做:
select
d.deal_name,
group_concat(c.name_car order by c.name_car separator ', ')
from dealerships d
join cars c on find_in_set(c.id_car, d.deal_cars) > 0
group by d.deal_name;
或(作为分隔的字段):
select d.deal_id, d.deal_name, c.id_car, c.name_car
from dealerships d
join cars c on find_in_set(c.id_car, d.deal_cars) > 0;
【讨论】:
以上是关于在while循环中进行foreach的主要内容,如果未能解决你的问题,请参考以下文章