Раздела e на php

Различие между абсолютными и относительными путями. В файловой системе и на сайте.

твой сайт существует в как бы в двух измерениях.
Реальном и виртуальном.

Для всех посетителей — это виртуальный веб-сервер. Который отличается, в числе прочего, тем, что на нем НЕ СУЩЕСТВУЕТ ФАЙЛОВ. если ты пишешь http://site.ru/file.html — это не файл. Это URI, виртуальный адрес. Никакого файла с именем file.html на сервере может вообще не быть. Это все виртуальные адреса, а не файлы.
И браузер работает именно с адресами.

Для разработчика же сайт — это программа, выполняющаяся на совершенно конкретном реальном компьютере. С совершенно конкретным жестким диском, каталогами и файлами. И скрипт, работая со своими данными, подгружая другие скрипты, работает именно с реальными ФАЙЛАМИ, на физическом ДИСКЕ.

Вот в этом различии и кроются трудности, с которыми часто сталкиваются новички.
Теряют файлы, путают ссылки с файлами, обращаются к локальным файлам по протоколу HTTP, или инклюдят файлы от корня веб-сервера.

А всего-то надо четко понимать две вещи:
1. Различать корень веб-сервера, как его видит браузер, и корень файловой системы на диске.
2. Отличие относительных путей от абсолютных.

Начнем со второго.
Это очень просто. Если путь указывается от корня системы, то это путь абсолютный. Это как почтовый адрес в реальной жизни — откуда бы ты не шел, но по точному адресу ты всегда точно найдешь нужное место.
примеры абсолютных путей:
/var/www/site/forum/index.php
/img/frame.gif
с:\windows\command.com
В юникс-системах и на веб сайтах корень обозначается косой чертой — «/».
Это важно. Это не просто палочка, а самостоятельный АДРЕС, путь.
В адресе http://www.site.ru/ последняя косая черта — не для красоты! Она обозначает вполне конкретный адрес — начало сайта.
На диске в юникс системах так же можно набрать «cd /» и ты попадешь в корневой каталог.
В виндоус системах файловая система разбивается по дискам, поэтому, в абсолютном адресе надо указывать имя диска. Абсолютного корня всей файловой системы в виндоус нет, у каждого диска — свой. Например, C:\ E:\
поэтому, даже если путь в виндоус начинается с косой черты, то это не абсолютный путь, а относительный. Относительно текущего диска. А абсолютный начинается с буквы.

Читайте также:  Php get data class

Если в начале пути корень не указать, то этот путь будет относительным, и он достаивается от текущего положения. В реальной жизни это напоминает дорогу к винному магазину — «два квартала налево и там все время прямо». Дойти по такому пути можно только из конкретной точки. Из другой ты попадешь уже в совсем другое место.
Самый простой пример относительного пути — это просто имя файла.
Если файл находится в том же каталоге, с которым работает программа — она его найдет, добавив текущий путь к имени файла.
примеры относительных путей:
file.php (фал лежит в той же папке)
./file.php (фал лежит в той же папке. такая запись иногда требуется в некоторых юникс системах)
images/picture.jpg (файл лежит в капке images, которая находится в текущей)
../file.php (файл лежит в папке, которая расположена на один уровень выше от текущей)
../../file.php (файл лежит в папке, которая расположена на два уровня выше от текущей)

И операционная система, и браузер, встретив относительный путь, достраивают его до абсолютного. но каждый — по-своему.

Теперь перейдём к первому пункту.
Различие корня веб-сервера, как его видит браузер, и корень файловой системы на диске.
В общем-то, из предыдущих объяснений уже все должно быть понятно.
На диске путь к файлу скрипта может быть таким:
/var/www/site/forum/index.php
В то же время, виртуальный адрес этого скрипта при просмотре через браузер, будет:
http://www.site.ru/forum/index.php
На этом примере легко увидеть, где пересекаются два измерения: у этих двух адресов есть общая часть — /forum/index.php — и она-то и служит причиной путаницы.
Для браузера это самый полный путь, который только может быть. Он начинается от корня сайта.
Для скрипта же, исполняющегося на сервере — это всего лишь ЧАСТЬ пути.
для скрипта путь /forum/index.php окажется несуществующим — в корне диска нет каталога forum!
чтобы получить полный путь для того, что на сайте выглядит, как /forum/index.php , надо приставить слева к нему путь к папке, которая считается корневаой для всего веб сервера.
в нашем примере — это
/var/www/site
Этот путь задается в кофигурации веб-сервера и именно он содержится в системной переменной PHP $_SERVER[‘DOCUMENT_ROOT’]

В виртуальном же сервере — том, который видит пользователь — наоборот, нет никакого диска. Есть корень сайта. То есть, для того, чтобы любая ссылка гарантированно работала, независимо от того, из какого места сайта она вызывается, она должна быть абсолютной.
Если у вас на сайте есть, допустим, два раздела:
http://www.site.ru/about/info.php
и
http://www.site.ru/job/vacancy.php
то, если в файле info.php сделать ссылку просто на vacancy.php , то браузер ее не найдет — он будет искать адрес http://www.site.ru/about/vacancy.php , достраивая путь от текущего каталога.
Поэтому надо писать полный путь от корня сайта — /job/vacancy.php
Всё это касается, естественно, не только тегов но и и любых других, где используются ссылки на другие файлы.

Ссылки на локальные адреса следует писать без указания протокола и домена — только путь от корня сайта — /job/vacancy.php . Ссылки же на другие сайты следует писать полностью — http://www.site1.ru/job/vacancy.php .

PHP предоставляет множество средств для работы с файлами, каталогами и URL-ами.

Во-первых, это многочисленные предопределённые переменные, которые описаны в документации и значения которых в своём скрипте можно посмотреть с помощью команды phpinfo() :

Константа __FILE__ содержит имя текущего исполняемого файла.
В отличие от PHP_SELF она содержит имя файла, исполяющегося в данный момент.
очень полезной представляется конструкция dirname(__FILE__) , на которую желательно заменить все вызовы файлов, лежащих в том же каталоге, что и вызывающий скрипт. Например:
require dirname(__FILE__).»/init.php»
функция dirname() , наряду с basename() является одними из наиболее употребительных для работы с файлами и каталогами.

Примечание:
При проблемах с путями при переносе скриптов с виндоус на юникс систему, в первую очередь обращайте внимание на регистр букв. На юникс-серверах регистр букв в имени файла имеет значение, File.txt и file.txt — это два разных файла, а под виндоус — один и тот же. Лучше всего писать имя файла всегда точно, соблюдая регистр.

Источник

Построение дерева категорий на PHP. Рекурсия

Построение дерева категорий на PHP. Рекурсия

Сегодня я расскажу, как на PHP и MySQL создавать иерархическое дерево.

Такие деревья используются при построении категорий динамического сайта, например в интернет-магазине или при выводе комментариев к посту.

Вообще они строятся где только возможно. Главное правильно его построить и применить.

Самое главное, когда строишь иерархическое дерево — это правильная структура базы данных! Для примера рассмотрим структуру базы данных, где хранятся категории сайта. Для простого примера, таблица будет иметь 3 поля:

  1. id — ключ категории
  2. parent_id — id родительской категории
  3. name – название раздела

Создадим таблицу, выполнив SQL-запрос в PHPMyAdmin:

CREATE TABLE `categories` ( `id` INT NOT NULL AUTO_INCREMENT , `parent_id` INT NOT NULL , `name` VARCHAR( 50 ) NOT NULL , PRIMARY KEY ( `id` ) );

Теперь нужно заполнить нашу таблицу записями. В результате, должна получится примерно такая таблица:

Построение дерева категорий на PHP. Рекурсия

Можно заполнить тестовую таблицу запросом:

INSERT INTO `categories` (`id`, `parent_id`, `name`) VALUES (1, 0, 'Раздел 1'), (2, 0, 'Раздел 2'), (3, 0, 'Раздел 3'), (4, 1, 'Раздел 1.1'), (5, 1, 'Раздел 1.2'), (6, 4, 'Раздел 1.1.1'), (7, 2, 'Раздел 2.1'), (8, 2, 'Раздел 2.2'), (9, 3, 'Раздел 3.1');

С базой данных всё! Дальше идем к формированию самого дерева разделов.

И сейчас внимание! Дальше по логике нужно делать выборки из БД в цикле для выбора каждой категории и её подкатегории. НО! Ладно, если в БД несколько категорий, что тоже в принципе не правильно. А если сайт — интернет-магазин и у него сотня категорий и столько же подкатегорий? Тогда беда! Неведомое количество запросов к базе данных приведет к замедлению работы сайта или же к полному краху mysql-сервера.

Можно используя только один запрос к БД выбрать все категории и ихние подкатегории.

Сделаем запрос и сформируем удобный массив для дальнейшей работы.

//Выбираем данные из БД $result=mysql_query("SELECT * FROM categories"); //Если в базе данных есть записи, формируем массив if (mysql_num_rows($result) > 0) < $cats = array(); //В цикле формируем массив разделов, ключом будет id родительской категории, а также массив разделов, ключом будет id категории while($cat = mysql_fetch_assoc($result))< $cats_ID[$cat['id']][] = $cat; $cats[$cat['parent_id']][$cat['id']] = $cat; >>

Выбираем все данные из таблицы categories и формируем ассоциативный массив $cats, ключем будет id родительской категорий.

Сейчас будем строить дерево. Для построения будем использовать рекурсивную функцию.

Иерархическое дерево будет иметь такую структуру:

  • Раздел 1
    • Раздел 1.1
      • Раздел 1.1.1
      • Раздел 1.1
      • Раздел 1.2
      • Раздел 3.1

      Создадим рекурсивную функцию build_tree(). Она будет строить наше иерархическое дерево абсолютно любой вложенности.

      Функция принимает массив разделов и id раздела. В цикле перебираем подкатегории и если в них есть еще разделы, тогда функция запускается еще раз с новыми параметрами (новый массив разделов и id раздела, который нужно построить). Так формируется дерево любой вложенности!

      Для построения дерева, в коде прописываем:

      Так вот в два шага мы создали иерархическое дерево разделов сайта и не важно сколько там разделов!

      UPD Если нужно дерево категорий в обратном порядке зная id категории, тогда нужно воспользоваться функцией:

      function find_parent ($tmp, $cur_id) < if($tmp[$cur_id][0]['parent_id']!=0)< return find_parent($tmp,$tmp[$cur_id][0]['parent_id']); >return (int)$tmp[$cur_id][0]['id']; >

      Данная функция принимает массив категорий, ключом которой есть id рубрики, и id категории от которой нужно идти вверх.

      Для построения такого дерева запускаем функцию build_tree c такими параметрами:

      echo build_tree($cats,0,find_parent($cats_ID,ВАШ_ID_КАТЕГОРИИ));

      Есть вопросы? Задавайте в комментариях

      А как в данном случае будет выглядеть код для select? Чтобы все загружалось в Select, и желательно чтобы были optgroup ответить

      А как добавить сортировку? К примеру, есть еще одно поле в табл. ‘position’. Сейчас, как я понимаю, сортировка идет по id, т.е. в порядке добавления строк. ответить

      $result=mysql_query("SELECT * FROM categories ORDER BY position");

      Большое спасибо за ответ.
      Если можно, еще один вопрос. А как в таком случае создавать линки на каталоги? В БД вносить полные пути, например запись для Раздела 1.1.1
      «Раздел_1/Подраздел_1.1/Подраздел_1.1.1/»
      или лучше вносить запись только для данного подраздела, т.е. «Подраздел_1.1.1». Если второе, то как их потом объединить? ответить

      Максим Никифо$LastName = htmlspecialchars($_POST[‘LastName’]);
      $name = htmlspecialchars($_POST[‘name’]);
      $floor = $_POST[‘floor’];
      $email = mysql_real_escape_string($_POST[’email’]);
      $password = md5 ($_POST[‘password’]);
      $phone = $_POST[‘phone’];
      $data = $_POST[‘data’];
      $country = $_POST[‘country’];
      $region = $_POST[‘region’];
      $city = $_POST[‘city’];
      $rdate = date («Y-m-d H:i:s»); $regex=»/^[\w\.\-]+@[a-zA-Z0-9]+\.[a-zA-Z]$/»; if (preg_match($regex, $email))
      $password=md5($password);
      $activation=md5($email.time());
      $count=mysqli_query($link, «SELECT id FROM user WHERE email=’$email’»);
      if (mysqli_num_rows($count) <1)
      mysqli_query($link, «INSERT INTO user (LastName, name, floor, email, password, phone, data, country, region, city, rdate, activation) VALUES(‘$LastName’, ‘$name’, ‘$floor’, ‘$email’, ‘$password’, ‘$phone’, ‘$data’, ‘$country’, ‘$region’, ‘$city’, ‘$rdate’, ‘$activation’)»);
      include «send_mail.php»;
      $to=$email;
      $subject=»Проверка E-mail-а»;
      $body=»Здравствуйте! Активация! Пожалуйста перейдите по ссылке для активанции вашего аккаунта. «.$base_url.»activation/».$activation.»«;
      send_mail($to, $subject, $body);
      $msg=»Регистрация прошла успешно! Пройдите активацию через email.»;
      >
      else
      $msg=»Данный email уже занят.»;
      >
      >
      elseров, ответить

      это все круто конечно. Но работает только если у вас каталогов не больше 100 У меня в базе 40 тысяч записей. Такой метод не актуальный, ибо расчет происходит почти 10 минут. Ни один человек не будет ждать при переходе по страницам когда случится «чудо» и сервер просчитает ЭТО. Спросите, почему так много? Мне нужно построить дерево регионов — городов. по схеме МИР — СТРАНА — ОБЛАСТЬ(штат/округ) — населенный пункт. Что бы не занимало много место, потомки прячутся во вложенный список родителей, и отображаются только по клику на родителя (список раскрывается). Как решить эту задачу, еще не придумал, есть идеи? ответить

      Ну под «глобальные задачи», нужны и «глобальные сервера».
      А вообще, вам здесь рекурсия не нужна. У вас известна глубина вложенности — три (мир, страна, область). Вот и делайте исходя из вложенности. ответить

      Нужно всегда делать выборку именно той инфы, которая нужна пользователю. Технология ajax Вам в помощь.
      Можно выборку разделить на этапы используя ajax. Выбираете сначала континент(по выбору идет ajax-запрос с id континента и возвращается список стран, его вставляете в следуйщий selest), при выборе страны подгружаете уже регионы и т.д. Так будут запросы намного меньше, и не будет выборок не нужной пользователю информации. ответить

      Источник

Оцените статью