Как следовать родительско-дочерним отношениям в многомерном массиве? - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть классическая таблица базы данных для многоуровневых категорий, подобных этой (0 означает корень):

ID - Name - Father
1    News      0
2    Articles  0
3    Politics  1
4    Politics  2
5    World     3
6    World     4

У меня есть такой путь: /News/Articles/Politics, и у меня есть данные таблицы вышев массиве.

Я начинаю с вызова explode() с / на пути, и я попробовал несколько методов, но во всех случаях нет ничего хорошего.

Здесьэто то, что я пробовал:

$cat_path_ary = explode($cfg['categories_separator'], $cat_path);
if (count($cat_path_ary) > 1) {
    $catname = array_pop($cat_path_ary);
    $catparent = array_pop($cat_path_ary);
    $cat_id = $this->getCatIDbyName($plugin, $catname, $catparent);
} else {
   $catname = $cat_path_ary[0];
   foreach($this->root_cats($plugin) as $categories) {
      if($categories['name'] == $catname ) {
       return $categories['cid'];
      }
   }
}

Каков наилучший способ пересмотреть значения пути и определить окончательное значение ID?

С /News/Articles/Politics Я ожидаю возврата 5. * * 1020

1 Ответ

0 голосов
/ 22 сентября 2018

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

Выполните итерации записей в вашем пути и выполните повторную проверку для подходящих строк (сопоставление Name и сопоставление Father).

Поскольку в каждом внутреннем цикле может быть только одна подходящая строка, break, как только она будет найдена для достижения максимальной эффективности.... просто убедитесь, что обновили переменные $id и $parent перед тем, как это сделать.

Была реализована проверка на отсутствие "подходящих строк", но она может иметь или не иметь отношение к вашему проекту.,Вы можете решить, хотите ли вы эту страховочную сетку.

Код: ( Демо )

$resultset = [                                                     // query just once, collect the full tree
    ["ID" => 1, "Name" => "News", "Father" => 0],
    ["ID" => 2, "Name" => "Articles", "Father" => 0],
    ["ID" => 3, "Name" => "Politics", "Father" => 1],
    ["ID" => 4, "Name" => "Politics", "Father" => 2],
    ["ID" => 5, "Name" => "World", "Father" => 3],
    ["ID" => 6, "Name" => "World", "Father" => 4]
];

$path = "/News/Politics/World";
// $path = "/Articles/The Funnies/Garfield";                        // a test case that fails
// News: parent = 0, id = 1                                         // \
// Politics: parent = 1, id = 3                                     //  > the intended logic
// World: parent = 3, id = 5                                        // /

$cfg['categories_separator'] = "/";
$breadcrumbs = explode($cfg['categories_separator'], trim($path, "/"));
// var_export($breadcrumbs);                                        // see what is generated

$parent = 0;                                                        // default value
foreach ($breadcrumbs as $crumb) {
    $id = false;                                                    // set invalid value for success check
    foreach ($resultset as $row) {
        if ($row["Name"] == $crumb && $parent == $row["Father"]) {  // qualifying match
            $id = $parent = $row["ID"];                             // dual declaration
            break;                                                  // break inner loop, progress to next $crumb        
        }
    }
    if (!$id) {                                                     // inner loop failed to find qualifying match
        echo "Uh-oh, Broken Breadcrumb Path -- $crumb not found in $path\n";
        break;                                                      // break outer loop, path is invalid
    }
    // echo "ID = $id for $crumb\n";                                // uncomment to see progress
}
echo "ID = $id for $crumb\n";                                       // echo the result

Выход:

ID = 5 for World
...