2010-01-26 4 views
0

Целью этого кода является получение всех брендов для всех магазинов в один массив и вывод его на экран. Если бренд существует в нескольких магазинах, он будет добавлен только один раз.Можно ли упростить этот PHP-код для повышения производительности?

Но я чувствую, что у меня слишком много для циклов, и это может затормозить процессор при интенсивном движении. Есть ли лучшее решение?

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; 
    } 
+0

Не могли бы вы рассказать нам больше о ваших таблицах базы данных и запросах, которые вы используете? Есть хороший шанс, что вы можете сократить его до одного запроса к базе данных и одного цикла, используя соответствующее соединение. –

ответ

1

Как проектируются ваши столы? Если бы у вас была таблица магазинов, таблица брендов и таблица ссылок, в которой были отношения между магазинами и брендами, вы могли бы просто втянуть список брендов из таблицы брендов в один запрос и не выполнять какую-либо другую логику.

Создайте свои таблицы, чтобы они легко отвечали на вопросы, которые вам нужно задать.

+0

БД спроектирована правильно. Это будет сложный запрос, потому что мне нужно также включить таблицу руководства по шопингу. В таблице руководства есть x магазинов, и в каждом магазине есть y брендов. – Steven

1

Если вам нужно получить все бренды для определенного набора магазинов, вам следует подумать о том, чтобы использовать запрос, созданный для этого, вместо того, чтобы проходить через все магазины и получать отдельные фрагменты информации.

2

Не нужно проходить через два набора массивов (один для создания массива брендов, а затем один для создания HTML). Тем более, что ваша вспомогательная функция выполняет цикл - используйте функцию array_key_exists и используйте идентификатор в качестве ключа. Кроме того, вы можете использовать функцию implode, чтобы присоединиться к ссылкам с помощью «,», поэтому вам не нужно делать это вручную (в вашем существующем коде у вас будет запятая в конце, которую вам нужно будет обрезать). Вы можете сделать это без двух наборов для петель:

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.

+0

go хэш карты! вы на самом деле не объясняете ему ** почему ** это быстрее, хотя ... –

+0

Добавлено лучшее уточнение, спасибо. – Parrots

4

В своем комментарии вы упомянули, что «Таблица руководства содержит магазины X и каждый магазин имеет марки Y». Предположительно, есть таблица «магазины», таблица «бренды» и таблица «привязки», которая сопоставляет store_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 статья будет показывать только каждый бренд один раз. Если вы удалите его, вы можете добавить идентификатор магазина и вывести полный список ассоциаций магазинов-брендов.

+0

Я не уверен, что SQL полностью корректен, но это лучшее решение для перемещения логики в SQL-запрос. Это самое быстрое решение! – powtac

Смежные вопросы