可以简化此PHP代码以提高性能吗?

时间:2010-01-26 03:01:58

标签: php sql

此代码的目标是将所有商店的所有品牌合并为一个数组,并将其输出到屏幕。如果一个品牌存在于多个商店中,则只会添加一次。

但我觉得我有太多的循环,并且它可能会在繁忙的流量上阻塞CPU。 有更好的解决方案吗?

  function getBrands($stores, $bl)
  {
    $html = "";

    //Loop through all the stores and get the brands
    foreach ($stores as $store)
    {
      //Get all associated brands for store
      $result = $bl->getBrandsByStore($store['id']);

      //Add all brands to array $brands[]
      while ($row = mysql_fetch_array($result))
      {
        //If this is the first run, we do not need to check if it already exists in array
        if(sizeof($brands) == 0)
        {
          $brands[] = array("id" => $row['id'], "name" => $row['name']);
        }
        else
        {
          // Check tosee if brand has already been added.
          if(!isValueInArray($brands, $row['id']))
            $brands[] = array("id" => $row['id'], "name" => $row['name']);
        }
      }
    }

    //Create the HTML output
    foreach($brands as $brand)
    {
      $url = get_bloginfo('url').'/search?brandID='.$brand['id'].'&brand='.urlSanitize($brand['name']);
      $html.= '<a href="'.$url.'" id="'.$brand['id'].'" target="_self">'.$brand['name'].'</a>, ';
    }

    return $html;
  }

  //Check to see if an ID already exists in the array
  function isValueInArray($values, $val2)
  {
    foreach($values as $val1)
    {
      if($val1['id'] == $val2)
        return true;
    }
    return false;
  }

4 个答案:

答案 0 :(得分:4)

从您的评论中,您提到“指南表有X个商店,每个商店都有Y个品牌”。据推测,有一个“商店”表,一个“品牌”表和一个“联动”表,它将store_id与brand_id配对,以一个商店与多个品牌的关系,对吗?

如果是这样,单个SQL查询可以完成您的任务:

SELECT b.`id`, b.`name`
FROM `stores` s
LEFT JOIN `linkage` l
  ON l.`store`=s.`id`
LEFT JOIN `brands` b 
  ON b.`id`=l.`brand`
GROUP BY b.`id`;

最终的GROUP BY条款只会显示每个品牌一次。如果删除它,您可以添加商店ID并输出商店到品牌关联的完整列表。

答案 1 :(得分:2)

无需遍历两组数组(一组用于构建品牌数组,另一组用于制作HTML)。特别是因为你的辅助函数循环执行 - 使用array_key_exists函数并使用ID作为键。另外,您可以使用implode功能将链接加入',',这样您就不必手动执行(在现有代码中,您必须使用逗号,最后必须删除)。您可以在没有两组for循环的情况下执行此操作:

function getBrands($stores, $bl) 
{
    $brands = array();

    //Loop through all the stores and get the brands
    foreach ($stores as $store)
    {
        //Get all associated brands for store
        $result = $bl->getBrandsByStore($store['id']);

        //Add all brands to array $brands[]
        while ($row = mysql_fetch_array($result))
        {
            if (!array_key_exists($row['id'])
            {

                $url = get_bloginfo('url') . '/searchbrandID=' . 
                       $brand['id'] . '&brand=' . urlSanitize($brand['name']);
                $brands[$row['id']] .= '<a href="' . $url . '" id="' . 
                                       $brand['id'] . '" target="_self">' . 
                                       $brand['name'] . '</a>';
            }
        }
    }

    return implode(', ', $html);
}

这样可以更快地获得同样的效果。它会更快,因为你曾经循环获取品牌,然后循环并构建HTML。不需要将它作为两个独立的循环,所以它一下子就可以存储HTML。此外,由于它已切换为使用array_key_exists,而不是您编写的帮助程序,通过再次循环查看是否有品牌在那里,您将看到更多的速度改进。 Hashmaps很漂亮,因为hashmap中的每个元素都有一个键,并且有一些本机函数可以查看是否存在一个键。

你可以通过编写一个带有不同过滤器的更好的SQL语句来进一步优化事物,以便你不需要在foreach中做一段时间。

答案 2 :(得分:1)

你的桌子是如何设计的?如果您有商店餐桌,品牌表和具有商店和品牌之间关系的链接表,您可以在一个查询中从品牌表中提取品牌列表,而不必执行任何其他逻辑。 / p>

设计表格,以便他们轻松回答您需要提出的问题。

答案 3 :(得分:1)

如果您需要获得某些商店的所有品牌,那么您应该考虑使用精心设计的查询,而不是遍历所有商店并获取单独的信息。