Описание: php Работа с многомерными массивами |
Поиск в теме | Версия для печати |
Furax |
Отправлено: 22 Ноября, 2008 - 01:07:51
|
Бледнотик
Покинул форум
Сообщений всего: 1472
Дата рег-ции: Март 2007
Откуда: Иркутск, Сибирь, СССР
Карма 32
|
victor
Это не есть объявления массивов. Возможно, результат сериализации. А вообще можно сделать так:CODE:$source = array
(
array('adm', 'css'),
array('adm', 'flash'),
array('adm', 'java', 'ajax', 'lib')
);
$t = array();
foreach ($source as $element)
$t[] = implode('/', $element); |
|
|
victor |
Отправлено: 23 Ноября, 2008 - 23:44:12
|
Full Member
Покинул форум
Сообщений всего: 177
Дата рег-ции: Февр. 2005
Карма 0
|
Furax ты прав это полученные массивы.
Я тебе не совсем то написал что хочу получить, просто к утру видимо голова совсем не варила.
Для удобства их нужно объеденить между собой. Таким образом я получу групповое объединение. Потомучто я эту цепочку забираю из БД. Чтоб потом с ней работать.
БД хранит два поля put (путь к файлу или директории) и type(что это файл или директория?)
Объясню задачу из выше показанного примера видно что это файловая система.
Файловую систему я получаю за счет рекурсивного дерева. И записываю ее в таблицу БД.
Получаю такую строчку в поле put БД.
Если данная строка описывает путь к директории то я помечаю в таблице БД что это директория.
Теперь на основе таких строк хочу сделать чтото на подобе "проводника" или "far"
Смысл следующий, я выбираю из БД каталоги, после чего их надо сгрупировать между собой по принадлежности друк к другу, так как создавать данную таблицу я хочу один раз а в будущем просто дополнять ее, если появляется новый файл или каталог. Это озночает что цепочки для одного каталога будут идти не подряд
После того как будет созданна группа каталогов, к ним я применю JavaScript и на их основании сделаю запрос к БД для получения файлов которые хранятся внутри каждого каталога, что позволит мне просматривать файловую систему в интернете и использовать в своих целях.
Т.е. приведу пример в БД получились такие строчки
adm
dmo
adm/css
dmo/css
adm/css/help
adm/help
dmo/temp
В итоге я должен сделать запрос к БД
adm
adm/css
adm/css/help
dmo
dmo/css
dmo/temp
Тоесть необходимо сделать фильтрацию полученных каталогов, послечего сделать рекурсивный запрос к БД.
Просто несоображу, как лучше сделать, может лучше както по другому файловую систему хранить в БД?(Отредактировано автором: 23 Ноября, 2008 - 23:45:04) |
|
|
Furax |
Отправлено: 24 Ноября, 2008 - 02:40:22
|
Бледнотик
Покинул форум
Сообщений всего: 1472
Дата рег-ции: Март 2007
Откуда: Иркутск, Сибирь, СССР
Карма 32
|
Хм... Я бы сделал так:
id | Имя файла/каталога | Тип | id родительского элемента
При этом, соотвтетственно, один из элементов является корневым, каталоги первого уровня имеют его в качестве родительского, каталоги второго уровня - каталоги первого уровня, и так далее. И обращаться к базе тоже по id - это, во-первых, скорость (intовые операции намного быстрее строковых), а во-вторых - меньше возможностей сделать SQL-инъект.
А вообще, если я правильно понял теперь, что надо сделать, то это можно сделать так:CODE:$source = array
(
array('adm', 'css'),
array('adm', 'flash'),
array('adm', 'java', 'ajax', 'lib')
);
$dirs = array();
foreach ($source as $path)
{
$current = $dirs;
foreach ($path as $dir)
{
if (!isSet($current[$dir]))
$current[$dir] = array();
$current = $current[$dir];
}
}
print_r($dirs); |
|
|
victor |
Отправлено: 24 Ноября, 2008 - 08:28:44
|
Full Member
Покинул форум
Сообщений всего: 177
Дата рег-ции: Февр. 2005
Карма 0
|
Furax по поводу id родительского элемента Я о нем думал когда делал рекурсивное дерево, но при реализации понял, что тогда прежде чем писать полученные данные в БД мне необходимо разбить полученную строчку на составляющие, а потом делать запрос к БД чтобы узнать id родительского элемента и только после этого выполнить записи новой строки.
Я решил не утруждать php такими трюками. Тем более что в некоторых папках есть одноименные названия папок.
И еще посидев подумав я решил (из сложившейся ситуации) что можно сделать следующее:
1 Необходимо узнать длину дерева в глубь, это делается элементарно. Делаем запрос к БД с типом dir после чего выбираем самую длинную строку, таким образом я буду знать максимальное количество запросов к БД.
И второе чтобы не маятся с массивами делать запросы к БД использую REGEXP
Что позволит мне сделать функцию которая будет вызывать саму себя при столкновении с параметром dir
Правда используя REGEXP я столкнулся с синтаксической ошибкой, ну дамаю это проше поправить:
CODE:
SELECT *
FROM `fails`
WHERE `put` NOT REGEXP '^.+[//].+'
AND `dir` = 'dir'
LIMIT 0 , 30
данный запрос покажет корневые папки
CODE:
$put='adm';
SELECT *
FROM `fails`
WHERE `put` NOT REGEXP '^$put([//]{1})'
AND `dir` = 'dir'
LIMIT 0 , 30
А вот этот запрос должен идти в глубь, вот тут синтаксическая ошибка. Он мне показывает все пути папок вложенных в adm а должен показать только первый ряд т.е
должен показать
adm/css
а показывает
adm/css/help
и т.д.(Отредактировано автором: 24 Ноября, 2008 - 08:33:19) |
|
|
Furax |
Отправлено: 24 Ноября, 2008 - 08:51:28
|
Бледнотик
Покинул форум
Сообщений всего: 1472
Дата рег-ции: Март 2007
Откуда: Иркутск, Сибирь, СССР
Карма 32
|
Во-первых, не накладно ли хранить поле dir в строковом виде? Лучше в битовом.
Названия папок я бы, кстати, вовсе вынес в отдельную таблицу, сделав дерево рекурсивным. А глубину, кстати, можно добавить в виде отдельного поля - тогда всего-то и понадобится, что сделать SELECT MAX(`depth`).
С регэкспами в SQL я не работал, так что помочь не смогу - может, кто-то другой поможет... |
|
|
victor |
Отправлено: 25 Ноября, 2008 - 00:55:40
|
Full Member
Покинул форум
Сообщений всего: 177
Дата рег-ции: Февр. 2005
Карма 0
|
Furax по поводу битов ты прав, но я пока тестирую, поэтому пока в виде строки использую чтобы уж точно знать с чем работаю.
По поводу отдельной таблицы не согласен, зачем делать несколько таблиц когда можно использовать одну. Хотя если записей много то да лучше разделить, быстрее работать будет.
Для того чтобы получить глубину дерева я делаю следующий запрос.
CODE:
$gl=0;
SELECT * FROM `fails` WHERE `dir`='dir'";
$res=select_table($q2);
$rows=mysql_num_rows($res);
for ($num=0; $num<$rows; $num++){
$put[$num] = mysql_result($res, $num, 'put');
if(substr_count($put,"/") > $gl ) { $gl=substr_count($put,"/"); }
}
Таким образом я получаю максимальное число слешей в директории, а значит глубину.
По поводу запроса я тогда сделал так.
CODE:
$put='adm/java';
SELECT *
FROM `fails`
WHERE `put` REGEXP '^$put/[a-d]'
AND `dir` = 'dir'
Таким образом, если в списке встречается директория то происходит запрос данного вида. Если внутри этой директории встречается директория то сново идет запрос к БД и так до конца списка. В итоге получаем проводник, причем его можно использовать не с корневого пути сайта а с любого места.
Сейчас еще REGEXP для списка придумаю и все. |
|
|
Furax |
Отправлено: 25 Ноября, 2008 - 01:51:30
|
Бледнотик
Покинул форум
Сообщений всего: 1472
Дата рег-ции: Март 2007
Откуда: Иркутск, Сибирь, СССР
Карма 32
|
Как раз разделение данных на разные таблицы и есть основной способ повышения производительности реляционных баз данных.
А что касается такого способа поиска наиболее глубокой директории - любопытно было бы посмотреть, сколько времени такой поиск займёт при количестве файлов хотя бы в 1000 и средней длине имени файла хотя бы в 6 символов, да ещё и на PHP. По-моему, тут без поля глубины не обойтись: добавив по нему индекс, мы сможем очень быстро извлекать максимальную глубину; кроме того, задать его при добавлении файла не составит никакого труда, а дополнительный объём места на диске, затраченный на это поле, исчезающе мал на фоне того, в котором хранятся имена (тем более что одинаковые имена файлов всё же включены в базу данных по нескольку раз). |
|
|
|
Поиск в теме | Версия для печати |
Страниц (1): [1] |
Сейчас эту тему просматривают: 4 (гостей: 4, зарегистрированных: 0, скрытых: 0) |
« PHP/Perl » |
Все гости форума могут просматривать этот раздел. Только администраторы и модераторы могут создавать новые темы в этом разделе. Только администраторы и модераторы могут отвечать на сообщения в этом разделе.
|
|
|