Другим сценарием является то, что вы нанесли нулевой объект в тип значения . Например, код ниже:
object o = null;
DateTime d = (DateTime)o;
Он выкинет NullReferenceException
в роли. В приведенном выше примере это кажется совершенно очевидным, но это может произойти в более «поздних связующих» сложных сценариях, где нулевой объект был возвращен из некоторого кода, которого вы не являетесь, и приведение, например, генерируется некоторой автоматической системой.
Одним из примеров этого является этот простой фрагмент привязки ASP.NET с элементом управления календарем:
" />
Здесь SelectedDate
на самом деле является свойством - типа DateTime
- типа Calendar
Web Control, и привязка может отлично вернуть что-то null. Неявный генератор ASP.NET создаст кусок кода, который будет эквивалентен приведенному выше методу. И это поднимет NullReferenceException
, что довольно сложно определить, потому что он лежит в сгенерированном ASP.NET коде, который компилирует отлично ...
Некоторое очень простое, общее построение дерева:
function buildTree(array $elements, $parentId = 0) {
$branch = array();
foreach ($elements as $element) {
if ($element['parent_id'] == $parentId) {
$children = buildTree($elements, $element['id']);
if ($children) {
$element['children'] = $children;
}
$branch[] = $element;
}
}
return $branch;
}
$tree = buildTree($rows);
Алгоритм довольно прост:
0
/ nothing / null
/ whatever). parent_id
элемента совпадает с текущим родительским идентификатором, который вы получили 1., элемент является дочерним элементом родителя. Поместите его в список текущих детей (здесь: $branch
). children
. Другими словами, одно выполнение этой функции возвращает список элементов, которые являются дочерними данного родительского идентификатора. Вызовите его с помощью buildTree($myArray, 1)
, он вернет список элементов, у которых есть родительский идентификатор 1. Первоначально эта функция вызывается с родительским идентификатором, равным 0, поэтому возвращаются элементы без родительского идентификатора, которые являются корневыми узлами. Функция вызывает себя рекурсивно, чтобы найти детей детей.
Я знаю, что этот вопрос старый, но у меня возникла очень похожая проблема - за исключением очень большого количества данных. После некоторой борьбы мне удалось построить дерево за один проход из набора результатов - используя ссылки. Этот код не очень хорош, но он работает, и он работает довольно быстро. Он нерекурсивный - то есть есть только один проход по набору результатов, а затем один array_filter
в конце:
$dbh = new PDO(CONNECT_STRING, USERNAME, PASSWORD);
$dbs = $dbh->query("SELECT n_id, n_parent_id from test_table order by n_parent_id, n_id");
$elems = array();
while(($row = $dbs->fetch(PDO::FETCH_ASSOC)) !== FALSE) {
$row['children'] = array();
$vn = "row" . $row['n_id'];
${$vn} = $row;
if(!is_null($row['n_parent_id'])) {
$vp = "parent" . $row['n_parent_id'];
if(isset($data[$row['n_parent_id']])) {
${$vp} = $data[$row['n_parent_id']];
}
else {
${$vp} = array('n_id' => $row['n_parent_id'], 'n_parent_id' => null, 'children' => array());
$data[$row['n_parent_id']] = &${$vp};
}
${$vp}['children'][] = &${$vn};
$data[$row['n_parent_id']] = ${$vp};
}
$data[$row['n_id']] = &${$vn};
}
$dbs->closeCursor();
$result = array_filter($data, function($elem) { return is_null($elem['n_parent_id']); });
print_r($result);
Когда выполняется по этим данным:
mysql> select * from test_table;
+------+-------------+
| n_id | n_parent_id |
+------+-------------+
| 1 | NULL |
| 2 | NULL |
| 3 | 1 |
| 4 | 1 |
| 5 | 2 |
| 6 | 2 |
| 7 | 5 |
| 8 | 5 |
+------+-------------+
Последний print_r
производит этот вывод:
Array
(
[1] => Array
(
[n_id] => 1
[n_parent_id] =>
[children] => Array
(
[3] => Array
(
[n_id] => 3
[n_parent_id] => 1
[children] => Array
(
)
)
[4] => Array
(
[n_id] => 4
[n_parent_id] => 1
[children] => Array
(
)
)
)
)
[2] => Array
(
[n_id] => 2
[n_parent_id] =>
[children] => Array
(
[5] => Array
(
[n_id] => 5
[n_parent_id] => 2
[children] => Array
(
[7] => Array
(
[n_id] => 7
[n_parent_id] => 5
[children] => Array
(
)
)
[8] => Array
(
[n_id] => 8
[n_parent_id] => 5
[children] => Array
(
)
)
)
)
[6] => Array
(
[n_id] => 6
[n_parent_id] => 2
[children] => Array
(
)
)
)
)
)
Это именно то, что я искал.
Можно использовать php, чтобы получить результат mysql в массив, а затем использовать его.
$categoryArr = Array();
while($categoryRow = mysql_fetch_array($category_query_result)){
$categoryArr[] = array('parentid'=>$categoryRow['parent_id'],
'id'=>$categoryRow['id']);
}