Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Для профи > Как и где лучше хранить структуру сайта?


Автор: AntiLL 9.3.2006, 00:06
Доброго время суток!
В настоящее время поставлена задача создать универсальную CMS. Встал вопрос как лучше организовывать структуру для сайта, а самое главное где лучше ее хранить.
Была идея хранить струтуры сайтов в виде XML, но вроде бы как стало известно, что PHP очень медленно работает с оным. Поэтому не стоит.
Кто нибудь знает эта верная инфа?
Вроде бы структуру сайта можно хранить в виде Б+ дерьев в БД. Якобы все это дело будет быстрее и оптимальнее.
Кто что может посоветовать по этому поводу?

Автор: Serkys 9.3.2006, 00:47
Я продумал структуру с помощью id в БД. Конечно, отследить вручную бывает сложно, но движок всё прекрасно отслеживает. Если надо, распишу подробнее.

Автор: AntiLL 9.3.2006, 12:46
Ну если не сложно, то распиши пожалуйста, буду очень признателен.
Ну а в XML то никто не пробовал хранить структуру?

Автор: IZ@TOP 9.3.2006, 12:56
AntiLL, если у тебя небольшой проект, то можно и в XML. Когда речь заходит о больших объемах данных, естественно лучше использовать базы данных.

Автор: Serkys 9.3.2006, 20:09
AntiLL, в принципе ничего заумно сложного. Структура такая:
В БД выделена таблица, содержащая названия всех разделов, их id и rod_id. При обращении к какому-либо разделу через GET передаётся id этого раздела. По этому id ищутся разделы, у которых этот id записан в поле rod_id. Поле rod_id содержит id раздела, в котором расположен этот раздел. Немного муторно, т.к. напрямую через БД сложно отследить структуру, но толковой инфы на эту тему в нете не нашёл и пришлось самому сочинять.

Автор: AntiLL 9.3.2006, 22:37
Нет, планируется запустить большой проект, поэтому значит XML отпадает.
Поэтому буду реализовывать в таблице БД, по совету Serkys'а. Спасибо! =)

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

Автор: Ciber SLasH 10.3.2006, 05:28
Цитата(AntiLL @ 9.3.2006, 22:37 Найти цитируемый пост)
как получить в пхп полный урл со всеми параметрами открываемой страницы?

Код

echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];

Автор: AntiLL 10.3.2006, 12:45
Все спасибо всем за помощь! Респект сайту и форумчанам! =)

Автор: CyClon 11.3.2006, 20:54
Хм, а чем передача с помощью GET имен модулей не устраивает? К примеру /?go=download - список файлов.

Автор: Serkys 11.3.2006, 21:49
Цитата(CyClon @ 11.3.2006, 20:54 Найти цитируемый пост)
а чем передача с помощью GET имен модулей не устраивает? К примеру /?go=download - список файлов.

Смысл?

Автор: CyClon 12.3.2006, 10:52
Смысл - не нужно замарачиваться со всякими id и БД, XML. А теперь вопрос: Смысл заморачиватсья? Чтобы был id в адресной строке, для красоты? Тогда MOD_REWRITE? Или я чего-то не понял?

Автор: Grasshopper 23.3.2006, 17:52
Цитата(Serkys @ 10.3.2006, 01:09)
По этому id ищутся разделы, у которых этот id записан в поле rod_id.

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

Автор: IvanB 23.3.2006, 18:43
А одним запросом не получится?

Автор: Serkys 26.3.2006, 01:04
Цитата(Grasshopper @ 23.3.2006, 17:52 Найти цитируемый пост)
Проблема в том что если вложение больше одного уровня, то придется делать много запросов к бд, чтобы найти родителя родителя, родителя родителя родителя и т.д.

ИМХО много запросов придётся делать при попытке отследить наследование. Но часто это можно и не делать... smile . Также можно писать в сессии разделы, посещённые до этого (большинство посетителей ведь будут проходить весь путь наследования, а не сразу по ссылке, а при недостаче - уже черпать из БД. Думать всё это надо, как-нибудь придумаю потом (самому эту проблему решать надо будет в ближайшее время). Заморочек конечно на первый взгляд много, но, как мне говорит опыт, почти все исчезнут в процессе обдумывания/написания, а остальные можно малыми потерями обойти.

Цитата(IvanB @ 23.3.2006, 18:43 Найти цитируемый пост)
А одним запросом не получится?

Что-то из околостульной части тела мне подсказывает, что нет smile

Автор: youri 31.3.2006, 03:48
Цитата(CyClon @ 11.3.2006, 20:54 Найти цитируемый пост)
Хм, а чем передача с помощью GET имен модулей не устраивает? К примеру /?go=download - список файлов.

а можно поподробнее: как связать вместе структуру сайта, которая храниться в БД, и передачу имени модуля через GET? где храняться имена модулей? имеется в виду, что есть index.php, который по имени модуля узнает, какому скрипту передать запрос? можно отказаться от хранения структуры сайта в базе?

Автор: AntiLL 3.4.2006, 23:13
Цитата
Хм, а чем передача с помощью GET имен модулей не устраивает? К примеру /?go=download


А как же ты будешь дерево сайта делать? Ну то есть вложенность разделов. Помоему хранить в БД это самый нормальный вариант для создания универсальной CMS. А дальше это уже оптимизировать разве что.

Автор: owlet 21.2.2007, 00:16
Я задавался целью сделать движок, совсем не использующий БД для статичных страниц. Нашел два приемлемых для меня варианта хранить структуру:

1. Если сайт небольшой можно всю структуру хранить в одном файле в виде PHP кода (вложенные массивы). Плюсы - не нужно парсить XML - просто инклюдим и все. Научить CMS генерить такой файл  не сложно совсем. 

2. Если сайт средний, кладем в корень каждой директории стандартный файл - например, menu.dat, содержащий, опять же PHP код такого вида:

Код

$m[] = array('Главная', '');
$m[] = array('Страница', 'page.html');
$m[] = array('Раздел', 'part/');


Парсим URL страницы, находим все директории, в которые вложена страница - например:
http://domain.ru/dir1/dir2/dir3/page.html дает массив:
array('', 'dir1/', 'dir1/dir2/', 'dir1/dir2/dir3/')
Меню строит функция, которая, в данном случае, читает четыре файла menu.dat из каждой директории и выполняет их eval() для получения меню соответствующего уровня.

Структура в этом случае распределена по файловой системе. Но все удобно - под рукой.

Плюсы в том, что статичные страницы сайта будут работать, даже если лежит БД. Удобно редактировать навигацию в разделах. 

Минусы: нужно прочесть некоторое кол-во файлов - от 1 до N; N =  кол-во вложенных уровней + 1.

Второй вариант работает на среднем по объему проекте, мне удобно.

В тех частях сайта, где используются модули, генерирующие контент из БД, навигация по страницам таких модулей возлагается на них же. 

Думаю, второй подход можно использовать с БД. Первичным ключем можно сделать пути (тот же array('', 'dir1/', 'dir1/dir2/', 'dir1/dir2/dir3/')), а всю структуру директории записать как blob прямо в виде PHP кода, опять же, и выполнять eval(). Тогда все данные для создания меню к конкретной странице берутся одним запросом. Полагаю, будет работать быстро. 

Автор: SamDark 21.2.2007, 13:14
Вытащить дерево одним запросом ещё как получится. Особенно быстро, если можно организовать обход в ширину.

Автор: artfabrique 23.2.2007, 15:40
ну короче.
У тебя есть в бд таблица site_tree
в ней поля 
ID(int 11) - ИД данного элемента
PARENT_ID(int 11) - ИД родительского элемента
NAME(VARCHAR 100) - ИМЯ данного элемента
TYPE (VARCHAR 100) - ТИП данного элемента. Например, это может быть "tpl","module","section"
TPL (VARCHAR 255) - Если тип данного шаблона "tpl" то тут можно записать путь к файлу шаблона для данного элемента.
PLACE (VARCHAR 255) -Если тип данного шаблона "tpl" то тут можно записать место,которое заменять что-то вроде {[_place1_]}

далее пишем функцию шаблонизатор, которая собирает рекурсивным методов наше дерево и выдает страницу сайта на экран.
Например как то так:

Код

global $tree_out;
function showSection($sect_name) {
 global $tree_out;
 //получаем по переданному имени ID с которой начать и запускаем рекурсию нашу;
 gatherAll($наш_первый_id);
}

function gatherAll($pid) {
 global $tree_out;
 //Смотрим есть ли у этого элемента дети по бд тоесть есть ли элементы у которых парент_ид равен ид этого эелемента.
 //Запускаем функцию посещения элемента которая собсно будет обрабатывать этот элемент.
 visitElement($current_row); //- $current_row  это ряд уже отфетченный текущего элемента;
 //Если есть то запускаем из этой функции саму себя только уже с ид этого ребенка.
 gatherAll($current_row['id']);
 //Если нет детей то ничего не делаем.
}

function visitElement($row) {
 global $tree_out;
 //Ну а тут все в нашем распоряжении у тя текущая инфа о данном элементе под рукой как хошь так и оперируй с ней.
 //Например если тип данного элемента tpl 
 //заменяем в нашем глобальном выводе с помощью str_replace(); все подстроки которые
 //совпадают с полем PLACE данного элемента на загруженный из файла шаблон путь к которому указан в поле TPL
 //Короче нафонтазировать много можно.
  
}



Автор: eee 18.5.2008, 19:31
самый простой способ без бд - это именно передавать параметры в урл
Код

http://yoursite.com/index.php?go=download

Код

extract($_GET);
// разметка и все другое
include ("dir/".$go.".php"); // dir-каталог где хранятся разделы
// разметка и тра та та

в итоге подгрузится скрипт dir/download.php

Автор: ReactOS 18.5.2008, 19:37
Цитата(eee @  18.5.2008,  19:31 Найти цитируемый пост)
самый простой способ без бд - это именно передавать параметры в урл

но по-моему это отходит от смысла топика smile

человек хочет создавать универсальную CMS, наверное такую же мощную, как Drupal, тут только тонкая работа с бд smile

Автор: Smith 19.5.2008, 07:22
Цитата(IvanB @ 23.3.2006,  18:43)
А одним запросом не получится?

http://phpclub.ru/faq/Tree?v=w5u

Автор: acdcee 27.8.2008, 16:55
Рассмотрите проблему - узнать родителя родителя родителя на примере DOM
Почему бы строку /news/test/test23/test-2/ не разобрать и одной рекурсией вытащить с БД и имена и все параметры не перевести на подобии работы DOM
к примеру news родитель и для test и для test23
причем у news два статуса - файловый или статический (простая html страница с БД)

и тогда структура будет так
#root - корень для news (стартовая страница или страница по умолчанию)
  |- news - наш модуль от кого будем плясать
        | - test - вот и наши разделы
        | - test23 - еще один

и обращатся вот так
$root =& new MOD();
$news =& $root->item(0) || $root->rootModule;
$test = $news->item($news->modCount);

а дальше дело фантазии как это реализовать smile

Добавлено через 4 минуты и 54 секунды
$test = $news->item($news->modCount);

причем эта запись должна показывать корректно последнего из списка потомков раздела news
т.е если после news идет test/test23 - то показать должен и вытащить из массива test23 потому как $news->modCount будет 2 - а как тут быть это уже надо структура класса продумать. Почему если $news->modCount = 2 будет вытащен раздел test23 хотя по идеи он в массиве будет по ключем 1 а не 2
smile

Но ничего сложного нету тут вообще!!!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)