|
|
|
| Привет, может кто знает, как можно сделать следующее:
Имеем следующую структуру в базе данных:
ID | Parent | Name
---------------------------------------------
1 | 0 | Category One
2 | 1 | Subcategory One
3 | 0 | One more category
4 | 2 | Sub-sub category
... и т.д.
Мне нужен PHP класс, который данную таблицу сериализует в следующий
формат:
[
{
"Name" : "Category One",
"ID" : 1,
"Children" : [
{
"Name" : "Subcategory One",
"ID" : 2,
"Children" : ...
}
]
},
{
"Name" : "One more category",
"ID" : 3,
"Children" : [ ]
}
]
т.е. массив объектов, в каждом из которых есть массив дочерних элементов, т.е. рекурсивная модель. | |
|
|
|
|
|
|
|
для: Raffi
(11.07.2008 в 22:27)
| | Что мешает сперва загрузить таблицу в массив, а затем этот массив сериализировать? | |
|
|
|
|
|
|
|
для: Trianon
(11.07.2008 в 22:50)
| | В этом-то и проблема - не могу понять, как мне рекурсивно сделать, чтобы эти данные считались в массив? И можно ли будет потом применить к получившемуся массиву XmlHttpRequest ? | |
|
|
|
|
|
|
|
для: Raffi
(11.07.2008 в 23:42)
| | Вашу проблему с рекурсией sms-send решил.
Думайте теперь, как строки защитить от разрушения. | |
|
|
|
|
|
|
|
для: Trianon
(11.07.2008 в 23:43)
| | от\какого разрушения? | |
|
|
|
|
|
|
|
для: Raffi
(11.07.2008 в 22:27)
| |
<?php
function serialize_table_id($id = 0)
{
$q = mysql_query('SELECT `ID`,`Name` FROM `tbl` WHERE `Parent`='.intval($id));
$str = '[';
for($i = 0; false !== $fetch = mysql_fetch_assoc($q); $i++)
{
if($i != 0)
$str .= ',';
$str .= '{';
$str .= '"Name" : "'.$fetch['Name'].'",';
$str .= '"ID" : '.$fetch['ID'].',';
$str .= '"Children" : '.serialize_table_id($fetch['ID']);
$str .= '}';
}
mysql_free_result($q);
$str .= ']';
return $str;
}
echo serialize_table_id();
?>
|
| |
|
|
|
|
|
|
|
для: sms-send
(11.07.2008 в 23:15)
| | Не устаю поражаться уверенности большинства коллег в том, что стоит цепочку символов окружить кавычками, как она тут же станет строковой лексемой.
Блин. | |
|
|
|
|
|
|
|
для: Trianon
(11.07.2008 в 23:35)
| | Думал об этом, но в условии ничего не сказано о синтаксисе экранирования, может нужно обратный слеш ставить, может кавычку удваивать, я этого не знаю. | |
|
|
|
|
|
|
|
для: sms-send
(11.07.2008 в 23:44)
| | Мне в конечном итоге нужно на странице произвести XmlHttpRequest и запросить данный объект.
и заполнить элемент select с помощью данного массива, вложенность отображая отступами.
Такое возможно сделать?
Я извиняюсь, может задаю глупые вопросы, просто в PHP не так давно начала программировать | |
|
|
|
|
|
|
|
для: Raffi
(11.07.2008 в 23:47)
| | То есть получаемая структура - это хеш на языке JavaScript?
Значит unicode, эскейпинг всех спецсимволов, букв нац.алфавитов... Вот, sms-send, недостающая инфа.
Собственно, отступы ему только для красоты, хотя слегка покумекав, можно сделать и отступы. | |
|
|
|
|
|
|
|
для: Trianon
(11.07.2008 в 23:52)
| | Мне чтобы соединить PHP и Java Script нужно PHP-код встачить в один файл, а Java Script в другой и из JS-файла при помощи XmlHttpRequest считать информацию из PHP-файла, чтобы затем при помощи того же JS-файла вывести её на экран? | |
|
|
|
|
|
|
|
для: Raffi
(12.07.2008 в 00:10)
| | Можно оттолкнуться от решения sms-send . Только я всё равно, написал хотя бы
$str .= '"Name" : "'.mysql_escape_string($fetch['Name']).'",';
|
Постепенно преодолевая сложности.
Можно воспользоваться чем-то готовым. Вроде библиотеки Д.Котерова
http://dklab.ru/lib/JsHttpRequest/ | |
|
|
|
|
|
|
|
для: Raffi
(12.07.2008 в 00:10)
| | В предыдущем примере слишком много запросов (по запросу для каждой записи), переписал так:
<?php
$q = mysql_query('SELECT `ID`,`Parent`,`Name` FROM `tbl`');
$table = array();
while(false !== $fetch = mysql_fetch_assoc($q))
{
$table[$fetch['ID']] = $fetch;
}
mysql_free_result($q);
$q = mysql_query('SELECT `Parent`,GROUP_CONCAT(`ID`) AS `ids` FROM `tbl` GROUP BY `Parent`');
$links = array();
while(false !== $fetch = mysql_fetch_assoc($q))
{
$links[$fetch['Parent']] = explode(',' ,$fetch['ids']);
}
mysql_free_result($q);
function serialize_table_id($id = 0)
{
global $table, $links;
static $level = 0;
$space = str_repeat(' ', 4);
$nl = chr(13).chr(10);
$str = '';
if(array_key_exists($id, $links))
{
if($id != 0)
{
$str .= $nl;
$level++;
}
$str .= str_repeat($space, $level);
}
$str .= '[';
if(array_key_exists($id, $links))
{
$level++;
$str .= $nl;
foreach($links[$id] as $k => $child)
{
if($k != 0)
$str .= ','.$nl;
$str .= str_repeat($space, $level).'{'.$nl;
$level++;
$str .= str_repeat($space, $level).'"Name" : "'.addslashes($table[$child]['Name']).'",'.$nl;
$str .= str_repeat($space, $level).'"ID" : '.$child.','.$nl;
$str .= str_repeat($space, $level).'"Children" : '.serialize_table_id($child);
$level--;
$str .= str_repeat($space, $level).'}';
}
$str .= $nl;
$level--;
$str .= str_repeat($space, $level);
$level--;
}
$str .= ']'.$nl;
return $str;
}
echo serialize_table_id();
?>
|
Намучался с отступами, вроде бы получилось. Насчёт экранирования в JS, я не знаю как и что экранировать в литералах этого языка, поэтому пользуюсь обычным addslashes, если нужно что то ещё учесть - поправте.
[UPD]
Как минимум эта функция (addslashes) не экранирует переводы строк. Поэтому тут правильней написать отдельную функцию, которая учтёт все особенности. | |
|
|
|
|
|
|
|
для: Raffi
(11.07.2008 в 23:47)
| | >и заполнить элемент select с помощью данного массива, вложенность отображая отступами.
Боюсь, что я не о тех отступах подумал :( | |
|
|
|
|
|
|
|
для: sms-send
(11.07.2008 в 23:44)
| | >Думал об этом, но в условии ничего не сказано о синтаксисе экранирования, может нужно обратный слеш ставить, может кавычку удваивать, я этого не знаю.
Согласен. Не сказано. Но тогда нужно поставить хоть что-то. Не устроит - поправят. Хотя бы внимание обратят.
Потому что "'$text'" при неизвестном $text - это заведомый баг. Гарантированный. | |
|
|
|
|
|
|
|
для: Trianon
(12.07.2008 в 00:20)
| | Ок. Исправлюсь :) | |
|
|
|
|
|
|
|
для: sms-send
(12.07.2008 в 01:38)
| | Спасибо большое за код!!! сейчас буду думать, как к нему XmlHttpRequest прикрутить | |
|
|
|