【问题标题】:Foreach in a while loop在while循环中进行foreach
【发布时间】: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 列不满足第一范式。

标签: mysql arrays foreach while-loop smarty


【解决方案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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-19
        • 2013-10-01
        • 2012-09-05
        • 1970-01-01
        • 2023-04-09
        • 2015-07-03
        • 2015-09-23
        相关资源
        最近更新 更多