Партнерка на США и Канаду по недвижимости, выплаты в крипто

  • 30% recurring commission
  • Выплаты в USDT
  • Вывод каждую неделю
  • Комиссия до 5 лет за каждого referral

Как видите, мы используем функции замены части строки с помощью регулярных выражений. Обратите внимание на шаблон функции preg_replace: в качестве разделителя здесь выступают слеши, причем после закрывающего разделителя следует модификатор i, указывающий, что шаблон является нечувствительным к регистру. Тот же эффект достигается при использовании POSIX функции с суффиксом i (eregi_replace).

Результат выполнения этих функций одинаков:

[вырезано]
[вырезано]

Функция preg_replace в нашем примере проявила так называемую "жадность", и охватила всю строку, которая начинается с буквы "р" и заканчивается "е". Заставить функцию не "жадничать" помогает модификатор U. В этом случае результат ее выполнения будет:

[вырезано] вы[вырезано]ние

Функция нашла минимальное расстояние между буквами "р" и "е" и заменило его указанной строкой.

Функция eregi_replace также проявила "жадность", но изменить этот порядок уже нельзя, так как в POSIX-функциях не предусмотрено использование модификаторов.

Бегло рассмотрим и другие функции работы с регулярными выражениями.

Функции

Синтаксис

Описание

ereg, eregi, preg_match

функция(pattern, string, [regs])

Ищет в строке string соответствия с регулярным выражением pattern, и сохраняет их в массиве regs (если указано).

preg_match_all

preg_match_all(pattern, subject, matches, [order])

Осуществляет глобальное сопоставление с шаблоном, результаты заносит в matches.

split, spliti, preg_split

функция(pattern, string, [limit])

Разбивает строку в массив посредством регулярного выражения.

preg_grep

preg_grep(pattern, input)

Возвращает массив из элементов массива input, соответствующих шаблону pattern.

Примеры на регулярные выражения.

Перевод времени в стандартное время Unix.

Предположим, у нас в базе данных или в другом источнике хранится дата в следующем формате:
часы:минуты:секунды - день. месяц. год
Но по некоторым причинам (например, произведен редизайн сайта) нам понадобилось отображать дату в следующем виде:
день. месяц. год часы:минуты

НЕ нашли? Не то? Что вы ищете?

Как вы понимаете, вручную заниматься этим - сумасшествие, так что напишем сценарий, который будет на первом этапе приводить дату к виду часы:минуты:секунды месяц/день/год, а затем с помощью функции strtotime() переведить эту запись в стандартное время UNIX, которое мы сможем отображать, как захочется.

Самое интересное - первый этап. Он-то нас и интересует в плане использования регулярных выражений.

$str = "12:57:4"; // $str содержит некоторую дату
$str = preg_replace("!(\d{2})\.(\d{2})\.(\d{2})!", "\\2/\\1/\\3", $str);

С помощью регулярного выражения мы изменяем формат записи дня, месяца и года, причем каждый этот элемент обособляем скобками. Во втором параметре функции мы ссылаемся на найденные соответствия в скобках. Вот как это происходит:

    \\0 - содержит строку, соответствующую всему шаблону (в нашем примере "10.03.02"). \\1 - содержит символы, соответствующие только первому элементу, заключенному в скобки (то есть "10"). \\2 - содержит символы, соответствующие только второму элементу, заключенному в скобки (то есть "03"). и так далее.

На этом этапе мы получем дату "12:57:43 - 03/10/02". Теперь доводим это до конца.

$str = str_replace("-", "", $str); // вырезаем знак "-"
$time = strtotime($str);

Теперь можно использовать переменную $time, как заблагорассудится.

На этом и закончим наш урок. Встретимся на следующем!

Урок 15. Основы MySQL.

Человек - единственное животное на свете,
способное смеяться и рыдать, ибо из всех живых
существ только человеку дано видеть разницу
между тем, что есть, и тем, что могло бы быть.
Уильям Хэзлитт

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

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

Установка MySQL.

Прежде, чем мы начнем знакомство с MySQL, вам необходимо установить эту базу данных на своей машине. Скачать дистрибьютив можно с этой страницы. Рекомендуется выбирать те версии, напротив которых написано "stable release". В помощь прочтите главу из официальной документации "MySQL Installation".

Итак, надеясь, что инсталляция MySQL прошла успешно, продолжаем наш урок и сейчас научимся без посредников в лице PHP, через консоль взаимодействовать с этой базой данных. Для этого зайдите в директорию, в которую вы установили MySQL, найдите там папку bin и откройте в ней файл mysql. exe.

В этом окне мы и будем обучаться MySQL.

Краткий справочник по командам MySQL.

Прежде всего настоятельно рекомендуется прочитать главу из документации "Tutorial Introduction",где изложены основы взаимодействия с MySQL, и статью "Реализация языка SQL в СУБД MySQL". Мы же рассмотрим лишь небольшую часть команд MySQL.

Сначала давайте рассмотрим структуру баз данных. Схематично она выглядит следующим образом:

база данных 1

таблица 1.1

таблица 1.2

таблица 1.n

база данных 2

таблица 2.1

...

база данных n

таблица n.1

Таким образом, данные по сути содержатся в таблицах, которые в свою очередь объединены в группу базы данных. Тем самым, чтобы начать работу с MySQL нам требуется прежде всего создать базу данных, с которой мы будем взаимодействовать.

CREATE.

Итак, в консоли пишем запрос:

CREATE database myphp;

Мы говорим MySQL создать базу данных с именем "myphp", причем регистр ключевых слов несущественен, но порядок слов в запросе не может быть изменен.

Теперь выберем только что созданную базу для работы с ней:

USE myphp;

И, как вы наверное уже догадались, нам необходимо создать таблицу, с которой мы будем работать. Пусть это будет таблица "lessons".

CREATE table lessons (
id int auto_increment primary key,
title varchar(250),
body mediumtext,
pub_date datetime default now(),
enable enum('0', '1') default '1'
);

Заметьте: то, сколько строк занимает запрос, несущественно: концом запроса является лишь символ ";".

Итак, мы создали таблицу lessons с 5 полями: id урока, представяющий собой уникальное число большее нуля, которое будет генерироваться автоматически при добавлении новой записи в таблицу путем увеличения максимального id на единицу (auto_increment); title - название урока длиной до 250 символов; body - собственно, сам урок, представляющий собой текст; pub_date - дата и время публикации урока; enable - флаг, который указывает, доступен ли урок посетителям, поле может иметь только два значения: '0' и '1', причем по умолчанию установлено '1'.

INSERT.

Теперь все готово, и мы можем приступить непосредственно к работе с данными. Сначала добавим в таблицу новую запись:

INSERT INTO lessons VALUES (
"",
"Начала",
"Прежде всего нужно сказать: PHP-скрипт для его выполнения должен быть заключен в следующие последовательности символов...",
'now()',
"1"
);

Итак, в таблице lessons у нас появилась новая запись, значения которой для каждого поля указываются в скобках после слова values (...). Причем заметьте, что мы пропустили ("") поле, которое заполняется автоматически - это поле id. Обратите внимание, на MySQL-функцию now(), которая возвращает текущее значение времени.

Но чтобы не писать пустых строк, также можно указать MySQL, в какие именно поля таблицы мы хотим сохранить данные. Например, введем таким образом данные урока 2:

INSERT into lessons (title, body) values (
"Формы всего сущего",
"На прошлом уроке мы научились передавать данные в php скрипт..."
);

Все остальные поля, не указанные нами, будут заполнены автоматически, причем для полей pub_date и enable применятся значения по умолчанию.

SELECT.

Теперь давайте посмотрим, что у нас оказалось в базе данных. Для этого применем команду SELECT, которая выводит указанные данные на экран.

SELECT * from lessons;

Значок "*" указывает, что мы хотим увидеть все поля таблицы lessons. Но также можно производить и выборочный вывод:

SELECT title, pub_date from lessons;

Также возможно выбирать не все записи в таблице, а удовлетворяющие определенным условиям:

SELECT title FROM lessons WHERE id = '1';

Тем самым мы выберем название только первого урока.

Также мы можем отсортировать данные перед выводом, используя команду ORDER.

SELECT id, title FROM lessons ORDER BY title;

Сортировка в обратном порядке производиться путем указания директивы DESC.

MySQL позволяет ограничить количество записей для вывода. Для примера выведем id и название последнего добавленного урока, подразумевая, что мы не знаем, какой id он имеет:

SELECT id, title FROM lessons ORDER BY id DESC LIMIT 1;

Сначала мы отсортировали все записи по id в обратном порядке, так что запись с максимальным id оказалась первой, и вывели только одну эту запись. Должна возвратиться таблица с id, равным 2, и title "Формы всего сущего".

MySQL также предоставляет функции COUNT(поле) для подсчета элементов, занесенных в указанное поле, MAX(поле) и MIN(поле) для определения максимального и минимального элемента соответственно, а также SUM(поле) для подсчета суммы элементов поля. К примеру:

SELECT COUNT(*), MAX(pub_date), SUM(id) FROM lessons;

UPDATE.

Предположим, что по какой-либо причине мы хотим на время скрыть урок 2 от посетителей. Для этого изменим поле enable, установив его равным нулю.

UPDATE lessons SET enable = '0' WHERE id = 2;

Таким образом можно изменить любое поле таблицы.

ALTER.

Команда ALTER TABLE позволяет изменить уже созданную таблицу. Например, в нашей таблице lessons после поля body вставим поле author.

ALTER TABLE lessons ADD author VARCHAR(200) DEFAULT 'Артем Акатов' AFTER body;

А теперь удалим эту колонку:

ALTER TABLE lessons DROP author;

Тем самым мы свободно можем манипулировать как создаваемыми объектами, так и уже давно созданными.

Как видите, синтаксис MySQL не отличается сложностью. Если вы более или менее владеете английским языком, вы без проблем освоите команды MySQL, к тому же они вполне интуитивно понятны. Мы разобрали лишь часть из них, для получения полной информации прочтите соответствующую официальную документацию.

А на следующем уроке мы займемся уже работой с MySQL посредством PHP. До встречи!

Урок 16. MySQL и PHP.

Человек живет только для того, чтобы учиться...
Карлос Кастанеда. Учение Дона Хуана.

Итак, на прошлом уроке мы познакомились с базой данных MySQL и рассмотрели использование некоторых ее операторов. Теперь же настало время применить полученные знания в программировании на PHP, и на сегодняшнем уроке мы рассмотрим взаимодействие MySQL с этим языком вебпрограммирования.

Соединение с MySQL.

Прежде, чем начать работу с базой данных, необходимо создать соединение с сервером MySQL. Этим и занимается функция mysql_connect(). Она должна быть вызвана до каких-либо других функций работы с MySQL, в противном случае они возвратят ошибки.

Аналогом функции mysql_connect является функция mysql_pconnect. Их отличие состоит в том, что последняя открывает постоянное соединение с MySQL, благодаря чему снижаются расходы времени и ресурсов на создание новых соединений. Это постоянное соединение не уничтожается ни функцией закрытия соединения, ни каким-либо другим образом. Использование этой функции требуется в случае, если вашему веб-приложению приходится часто обращаться к MySQL. Но учтите, что mysql_pconnect работает только на сервере, где PHP установлен как модуль.

Выбор или создание базы данных.

Вторым шагом при работе с MySQL чаще всего становится выбор базы данных для дальнейшей работы, либо создание новой базы данных.

Создание базы данных осуществляет функция mysql_create_db().

mysql_create_db(имя базы данных, [идентификатор соединения]);

Имя базы данных может состоять из любых символов, используемых для задания имени директорий на сервере, исключая символы '/', '\', '.'.

Идентификатор соединения есть результат выполнения функции mysql_connect или mysql_pconnect.

Для дальшейшей работы с базой данных вы должны ее выбрать. Выбор базы данных осуществляется функцией mysql_select_db(). Ее синтаксис выглядит следующим образом:

mysql_select_db(имя базы данных, [идентификатор соединения]);

Запросы в MySQL.

Пожалуй, самая универсальная функция для работы с MySQL - mysql_query(). Она может заменить практически любую функцию работы с базами данных MySQL, исключая mysql_connect() и mysql_close().

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

Например, с помощью нее мы можем создать базу данных, не используя вышерассмотренную функцию mysql_create_db().

$link = mysql_connect('*****', 'artem', '123456') or die("Не могу соединиться");
mysql_query("CREATE database my_db", $link) or die("Ошибка запроса");

Предположим, мы хотим ввести данные в базу данных, созданную на прошлом уроке.

$link = mysql_connect('*****', 'artem', '123456') or die("Не могу соединиться");
mysql_select_db('myphp', $link);
$query = "INSERT INTO lessons (title, body) VALUES (
'Выражаемся по-ПиЭйчПовски',
'Итак, на прошлом уроке я обещал начать урок 3 с изучения следующего, четвертого типа данных...'
)";
mysql_query($query, $link);

А теперь давайте выберем данные, которые ввели на этом и прошлом уроке. Это делается следующим образом:

// предположим, что уже соединились с MySQL
// и выбрали базу данных 'myphp'
$query = "SELECT title, body FROM lessons";
$result = mysql_query($query, $link);
while ($row = mysql_fetch_array($result)) {
 echo "<h1>".$row['title']."</h1><p>";
 echo $row['body']."</p>";
}

Заметьте, что mysql_query возвращает не сам результат, а идентификатор результата, который может быть использован другими функциями. Таким образом, $result в примере выше не содержим необходимую нам информацию в явном виде, его значение - лишь ссылка на нее.

Извлечение информации.

Чтобы извлечь информацию в понятную нам форму, необходимо воспользоваться функциями mysql_fetch_array(), mysql_fetch_row() или другими более специфическими функциями.

Функция mysql_fetch_array(), использованная в примере выше, осуществляет выборку записи в виде ассоциативного массива. Заметьте, эта функция, как и другие функции извлечения информации, не работает непосредственно с MySQL, а лишь обрабатывает полученный результат, поэтому ссылка на идентификатор соединения для работы этой функцией не требуется. Ее обязательный аргумент - лишь идентификатор результата, полученный функцией mysql_query().

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

$result = mysql_query("SELECT id, title FROM lessons", $link);
$first_row = mysql_fetch_array($result);
echo "Первая запись:<br>".$first_row['id']." - ".$first_row['title']."<br>";
echo "Остальные записи:<br>";
while ($row = mysql_fetch_array($result)) {
 echo $row['id']." - ".$row['title'].'<br>';
}

Данный пример может вывести у вас непонятные символы - текст в неизвестной кодировке. Это связано с тем, что MySQL использует по умолчанию кодировку latin, тогда как отображение данных происходит на веб-странице с кодировкой, скорее всего, windows-1251. Тем самым, данные введенные посредством одной кодировки и показанные - другой, превращаются в абракадабру. Но если вы будете вводить данные через веб-интерфейс и выводить через него же, то "смешения" кодировок не произойдет, и текст будет выводиться в нормальном виде.

Функция mysql_fetch_row() аналогична вышерассмотренной функции, за исключением того, что она возвращает пронумерованный массив, а не ассоциативный.

В случае, когда идентификатор результата содержит значения небольшого количества полей, или, что еще лучше, одного, то тогда становится удобным размещать данные не в массиве, а в отдельных переменных. Этим и занимается функция mysql_result(). Она имеет несколько более сложный синтаксис, чем mysql_fetch_array, поэтому рассмотрим его подробнее:

mysql_result(идентификатор результата, номер записи, [поле]);

Номер записи - это номер строки, из которой требуется получить данные. Поле - это название или номер поля указанной записи, из которой необходимо получить данные.

$result = mysql_query("SELECT title FROM lessons", $link);
$title1 = mysql_result($result, 0);
$title2 = mysql_result($result, 1);

Так как мы сделали выборку только по одному полю, то третий аргумент функции mysql_result() необязателен.

Закрытие соединения с MySQL.

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

Закрытие соединения осуществляется с помощью функции mysql_close().

В заключение.

Конечно, все функции PHP для работы с данными MySQL невозможно охватить в пределах одного урока. Мы разобрали самые важные и наиболее используемые из них. Настоятельно рекомендую ознакомиться с другими в документации PHP.

На этом и закончим наш урок. До встречи.

Урок 17. Шаблоны.

Разделение оформления и содержания - извечная проблема веб-разработчика. Для держателя небольшого сайта в несколько страниц такой проблемы не возникает. Изменение дизайна, либо другая правка внешнего вида страниц для него не представляет трудностей. Однако для крупных веб-ресурсов, порталов смешение этих двух важнейших компонентов сайта: оформления и содержания - просто недопустимо. Иначе сайт становится настолько неповоротлив, что владелец ресурса теряет над ним управление.

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

Что есть шаблон?

Понятие "шаблон" довольно обширное. Но чаще всего под шаблоном понимается некий документ (обычно в формате HTML), содержащий в себе все оформление ресурса, либо только его части, а также специальные метки, которые в процессе генерации страницы заменяются на информационные данные.

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

Наверное, во всех языках вебпрограммирования есть подобные инструменты для работы с шаблонами: в Perl это FastTemplate (который, кстати, существует и для PHP, но его использование не рекомендуется, так как приемлемые для работы версии относятся еще к третьей версии PHP), в отношении PHP - это крупный и многофункциональный Smarty, а также ряд других более мелких "шаблонизаторов".

Smarty.

Smarty - одна из самых крупных разработок подобного рода. Реализован он, как и практически все приложения подобного типа, в виде класса.

Этот "шаблонизатор" имеет огромное количество возможностей: он не только осуществляет замену выделенных участков шаблона указанными данными, но и предоставляет использование внутри шаблона исполняемых участков, функций, конфигурационных файлов и прочее.

Описывать все его возможности и правила использвования не имеет смысла, так как на это потребуется не один и не два урока, к тому же к нему написана довольно хорошая документация, а примеры использования прилагаются к самому Smarty.

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

Другие инструменты для работы с шаблонами.

Здесь я хочу обратить ваше внимание на "шаблонизаторы" на основе функции eval(). Эта функция расценивает код, заданный в ее аргументе, как код PHP и, соответственно, исполняет его. Например:

$text = 'Здравствуйте, $name $fam!';
$name = "Артем";
$fam = "Акатов";
eval('echo "' . $text. '";');

Этот примитивный пример работы с мини-шаблоном выведет "Здравствуйте, Артем Акатов!".

Преимущество данного типа инструментов работы с шаблонами связано с тем, что от разработчика заранее не требуется определять текст или другую информацию для меток в шаблоне (в нашем примере таковыми метками служат слова $name и $fam). Также такие "шаблонизаторы" значительно выигрывают по скорости.

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

function getTemplate($template, $ext = "htm") {
 $templatefolder = "templates"; // папка для хранения шаблонов
 return str_replace("\"","\\\"", implode("", file($templatefolder."/".$template.".".$ext)));
}
$name = "Артем";
$fam = "Акатов";
eval('echo "'.getTemplate('test').'";');

Если в файл test. htm мы поместим текст из переменной $text из примера выше, то результат выполения данного примера будет аналогичен предыдущему.

Для удобства работы с данным типом шаблонов пишутся классы. Одним из самых удачных классов такого рода является класс Евгения Кучерова.

Попробуем с его помощью создать один из вариантов примитивного "движка" для данного раздела "Уроки". При этом будем использовать записи MySQL, которые мы внесли на прошлых уроках.

Прежде всего заготовим шаблон. Для этого откроем окно с HTML-кодом данной страницы и заменим номер урока на переменную $row[id], вместо названия "Шаблоны" вставим $row[title], весь текст от первого слова "Разделение" до последнего "встречи!" заменим на $row[body]. Вместо элементов навигации "Назад, на урок 16" и в месте, где должно было бы располагаться "Дальше, на урок 18", соответственно ставим $prev и $next. Сохраним его как page. tpl. Готовый шаблон можно скачать здесь.

Теперь работаем с PHP. Пишем:

require "class. Template. php";  // относительный путь до класса
$tpl = new Template;
$id = (int)getenv("QUERY_STRING");  // извлекаем номер урока из строки запроса

mysql_connect("host", "artem", "12345");
mysql_select_db("myphp");
$query = "SELECT * FROM lessons WHERE id = '$id'";
$result = mysql_query($query);
$row = mysql_fetch_array($result);

if ($id > 1) $prev = "<a href='?".($id - 1)."'>Назад, на урок ".($id - 1)."</a>";

$query = "SELECT COUNT(*) FROM lessons";
$result = mysql_query($query);
$max = mysql_result($result, 0);

if ($id < $max) $next = "<a href='?".($id + 1)."'>Дальше, на урок ".($id + 1)."</a>";
eval('echo "'.$tpl->get("page").'";');

Это простой пример страницы, имеющей несложную структуру. Но даже на таком примере видно, как шаблоны упрощают создание веб-приложений.

В заключение.

Конечно, здесь мы разобрали лишь крохотную часть этой обширной темы работы с шаблонами и рассмотрели лишь малую долю инструментов работы с шаблонами. Но хотелось бы сказать, что не так уж важно, каким образом вы работаете с шаблонами и какие средства вы используете, намного важнее то, как вы с ними работаете. Научиться грамотной работе с шаблонами не так-то просто, понимание этого приходит только с практикой, и тут я не могу дать определенных советов.

На этом все. До следующей встречи!

Урок 18. Деревья.

С человеком происходит то же, что и с деревом.
Чем больше стремится он вверх, к свету, тем глубже
уходят корни его в землю, вниз, в мрак и глубину - ко злу.
Фридрих Ницше

Сегодняшний урок будет посвящен построению так называемых деревьев данных. Этот элемент часто используется в вебпрограммировании и просто необходим для таких приложений, как каталоги сайтов, многоуровневых форумов и других скриптов, в которых данные хранятся таким образом, что каждый элемент вложен в другой.

Все, кто имел дело с компьютером, имеют представление о деревьях. Например, это файловая система операционной системы.

Графически дерево можно представить следующим образом:

элемент 1

|

+ - элемент 2

| |

| + - элемент 3

| + - элемент 4

|

+ - элемент 5

Уровень вложенности и длина дерева не ограничены.

Создание деревьев.

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

Метод заключается в том, что в каждом дочернем элементе сохраняются данные о его непосредственном родителе, то есть, рассматривая схему выше, элементы 2 и 5 содержат ссылку на элемент 1, а 3 и 4 - на элемент 2.

Запрос на создание таблицы, в которой будут храниться данные по вышеуказанному алгоритму, может выглядеть следующим образом:

CREATE TABLE catalogs (

cat_id int(11) NOT NULL auto_increment,

parent_id int(11) NOT NULL default '0',

cat_name varchar(200) NOT NULL default '',

PRIMARY KEY (cat_id)

)

Вставим в полученную таблицу несколько записей:

// функция для вставки записей в MySQL
function sql_insert($parent_id, $cat_name) {
 $query = "INSERT INTO catalogs(parent_id, cat_name) VALUES('".(int)$parent_id."', '$cat_name')";
 mysql_query($query) or die(mysql_error());
 return mysql_insert_id(); // возвращаем id внесенной записи
}
// соединение и выбор базы данных рассматривать не будем
$level[1][0] = sql_insert("0", "Программирование");
$level[2][0] = sql_insert($level[1][0], "Веб программирование");
$level[2][1] = sql_insert($level[1][0], "Системное программирование");
$level[3][0] = sql_insert($level[2][0], "PHP");
$level[3][1] = sql_insert($level[2][0], "Perl");
$level[3][2] = sql_insert($level[2][1], "C++");
$level[4][0] = sql_insert($level[3][2], "Visual C++");
$level[3][3] = sql_insert($level[2][1], "Delphi");

// Вторая ветвь
$level[1][1] = sql_insert("0", "Базы данных");
$level[2][2] = sql_insert($level[1][1], "MySQL");
$level[2][3] = sql_insert($level[1][1], "Oracle");
$level[2][4] = sql_insert($level[1][1], "MS Access");

Теперь выведем полученное дерево:

function get_tree($parent_id = 0, $prefix = "") {
global $out;
$query = "SELECT * FROM catalogs WHERE parent_id = '$parent_id'";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
$out.= $prefix.$row['cat_name']."<br>";
get_tree($row['cat_id'], $prefix."&nbsp;&nbsp;");
}
return $out;
}
echo get_tree();

Так как мы имеем многоуровневое дерево, функцию get_tree() нам приходся вызывать рекурсивно, для одноуровневых деревьев (не больше одного уровня вложенности) этого не требуется.

Как видите, алгоритм построения такого рода деревьев очень прост.

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

Алгоритм Nested Sets.

Алгоритм Nested Sets - более мощный инструмент работы с деревьями. Класс для работы с ним вы можете скачать здесь. Архив состоит из двух файлов: dbtree. php - собственно, класс для работы с деревьями, и database. php - класс для работы с базой данных. Во второй файл вы можете добавить свои функции работы с MySQL и всячески подстраивать для себя, только не изменяйте функции, используемые классом в файле dbtree. php.

Алгоритм Nested Sets с первого взгляда может показаться сложным, но на самом деле он предельно прост. Суть его заключается в том, что он не сохраняет id родительского элемента, а использует три дополнительных поля: cat_left, cat_right и cat_level (имена полей вы можете изменить). Использует он их следующим образом.

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

Посмотрим, как поставит флажки наш человечек в схеме дерева из начала урока (синим отмечены флажки, поставленные при первом проходе элемента, зеленым - при возвращении из ветки).

элемент 1 [1] [10]

|

+ - элемент 2 [2] [7]

| |

| + - элемент 3 [3] [4]

| + - элемент 4 [5] [6]

|

+ - элемент 5 [8] [9]

Значения синих флажков в таблице MySQL запоминаются в поле cat_left, а зеленых - в поле cat_right, уровень вложенности - в поле cat_level.

Создадим таблицу с деревом, подобному указанному выше.

include("dbtree. php");

include("database. php");

$db = new CDatabase("your_database_name", "localhost", "root", "12345");

$tree = new CDBTree ($db, "catalogs2", "cat_id");

// создаем таблицу

$query="CREATE TABLE catalogs2(

cat_id int not null auto_increment primary key,

cat_left int not null,

cat_right int not null,

cat_level int not null,

cat_name varchar(200) not null)";

$db->query($query);

// заполняем таблицу

// создаем корневой элемент

$level[0][0]=$tree->clear();

// записываем основную часть дерева

$level[1][0] = $tree->insert($level[0][0], array("cat_name"=>"Программирование"));

$level[1][1] = $tree->insert($level[0][0], array("cat_name"=>"Базы данных"));

$level[2][0] = $tree->insert($level[1][0],

array("cat_name"=>"Веб программирование"));

$level[2][1] = $tree->insert($level[1][0],

array("cat_name"=>"Системное программирование"));
$level[2][2] = $tree->insert($level[1][1], array("cat_name"=>"MySQL"));

$level[2][3] = $tree->insert($level[1][1], array("cat_name"=>"Oracle"));

$level[2][4] = $tree->insert($level[1][1], array("cat_name"=>"MS Access"));

$level[3][0] = $tree->insert($level[2][0], array("cat_name"=>"PHP"));

$level[3][1] = $tree->insert($level[2][0], array("cat_name"=>"Perl"));

$level[3][2] = $tree->insert($level[2][1], array("cat_name"=>"C++"));

$level[3][3] = $tree->insert($level[2][1], array("cat_name"=>"Delphi"));

$level[4][0] = $tree->insert($level[3][2], array("cat_name"=>"Visual C++"));

// Выводим дерево

$query = "SELECT * FROM catalogs2 ORDER BY cat_left";

$result = $db->query($query);

while ($row = $db->fetch_array($result)){

echo str_repeat("&nbsp;&nbsp;&nbsp;", $row['cat_level']).$row['cat_name'].
" <font color='#0033FF'>[".$row['cat_left']."]</font>".

" <font color='#009900'>[".$row['cat_right']."]</font><br>";

}

Использование полей cat_left и cat_right позволяет манипулировать деревом практически во всех направлениях. Например, заметьте, что у элементов, не имеющих потомков, значения этих полей отличаются на единицу. А у потомков какого-либо данного элемента значения cat_left больше значения у выбранного родителя, а cat_right - меньше, причем, чем больше ветвь потомков, тем больше разность между значениями cat_right и cat_left у данного родителя (сравните "Веб программирование" и "Базы данных"). Основываясь на этих данных, сделаем выборку всех элементов, не имеющих родителей, а также всех потомков элемента "Системное программирование":

$query = "SELECT cat_left, cat_right FROM catalogs2 ".

"WHERE cat_name = 'Системное программирование'";
$result = $db->query($query);
$val = $db->fetch_array($result);
$query = "SELECT * FROM catalogs2 WHERE cat_left > '".$val['cat_left'].

"' AND cat_right < '".$val['cat_right']."' ORDER BY cat_left";
$result = $db->query($query);
echo "<b>Ветка 'Системное программирование'</b><br>";
while ($row = $db->fetch_array($result)) {
echo str_repeat("&nbsp;&nbsp;&nbsp;", $row['cat_level']).

$row['cat_name']."<br>";
}


echo "<b>Все элементы, не имеющие потомков</b><br>";
$query = "SELECT * FROM catalogs2 WHERE cat_right - cat_left = 1";
$result = $db->query($query);
while ($row = $db->fetch_array($result)) {
echo $row['cat_name']." ( ".$row['cat_id']." )<br>";
}

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

На этом и заканчиваем наш урок. До встречи на следующем!

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4