А это клавиатура, с помощью которой я творю...
http://kurepin.ru/php/back5/
Rambler's Top100
Пишем на PHP: BackOffice (продолжение-5)

——
Файлы этого выпуска: /step/154/
——

Ох, что-то мне стало скучно писать этот курс. Как-то вяло вы принимаете в нем участие. Проект читают около тысячи человек, а явные ошибки и опечатки замечают единицы. Я даже не исправляю их. Зачем?

У меня сложилось такое впечатление, что 99% читателей курса попросту ждут его завершения, чтобы запользовать готовые стрипты для своих задач. А программирование на PHP их интересует просто по ходу дела.

Это так? Если это так, ответьте. Я буду меньше времени уделять болтовне и буду публиковать больше готовых стриптов с минимумом пояснений. Мне ж не жалко. Наоборот, писать скрипты — это для меня намного проще, чем объяснять, как они работают.

Но мне дороже те, кто пришел ко мне за умением, за соревнованием, за сложностями. Вот для таких работать по-настоящему интересно. Именно они — "умники и умницы".

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

Итак. Вполне реальная задача.
Есть у меня робот, занимающийся рассылками всякой всячины: http://www.21.ru/post/.

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

Для этого ведется специальный лог в SQL-таблице — когда в какую рассылку какой текст был отправлен.

И при поиске следующего текста обязательно учитываются данные из этого лога.

Дальше. У MySQL, в отличие от более продвинутых диалектов SQL, нет такого понятия, как select from table where var in select... То есть, не поддерживаются вложенные запросы.

Жаль. Как бы было удобно, запросить следующий текст для рассылки примерно так:

select [данные текста] from [таблица] where [id текста] not in select [id текста] from [таблица логов]

Но я этого сделать не могу.

Конечно, можно вложенный запрос смоделировать каким-то простым способом. Например, запросить все интересующие ID из лога, сложить их в конструкцию (1,2,5,73...) и запросить из таблицы текст, где id текста not in (список). Но боже мой, как это не красиво!

Вот мы и подошли к задаче.

"Как выбрать верный следующий текст из таблицы текстов при помощи одного SQL-запроса?"

Вот такая задачка. Поверьте, она не сложная. Тем более, что я дал только 30% реальной задачи. Но меня интересуют именно эти 30%.

Если вы решите эту задачку — считайте, что диалект MySQL вы знаете на хорошем уровне.

А теперь вернемся к нашему проекту.

Я вижу, что вы мне там уже каких-то текстов в базу насували. Молодцы! Ща будем разбираться в них.

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

Речь идет об удалении рубрик. Как мы можем удалить рубрику, если с ней связан какой-то текст? Никак не можем мы этого допустить. И я очень жалею, что в MySQL объявление внешних ключей сделано только для совместимости с другими диалектами SQL. Очень удобно, когда за целостностью базы следит сама база. Но что поделать, у каждого свои плюсы и минусы. Поехали доделывать in_cat_delete(). Теперь эта функция выглядит вот так:


А в список ошибок добавляем:

$err[29]="Вы не можете удалить рубрику, она связана с текстами";

Что теперь? Есть два пути. Можно довести до ума добавление текстов, их редактирование, или заняться выводом информации.

Мы займемся....ммм-м-м... выводом информации. А то вы мне весь сайт за#рете, прежде чем я его открою. Шутка.

Что нам нужно для вывода?

Я так думаю, что нужно:

— список рубрик;
— список названий текстов в данной рубрике;
— вывод самого текста с названием и датой публикации;

С чего начнем? Давайте по порядку, не так уж много надо написать. За полчаса управимся.

Чуть-чуть правим out_cat_list() (видите, как удобны префиксы в названии функций, совпадающие с названием класса: сразу видно, в каком классе искать функцию): заменяем

$this->out_cat_list.="<a href=/cat/$id>$name</a><br>\n";

на

$this->out_cat_list.="<a href=/cat/?cat=$id>$name</a><br>\n";

И пишем функцию вывода названия текстов по номеру рубрики. Очень просто:


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

И не забудьте в начало файла добавить новые переменные out_cat_id и out_cat_name.

Так-с... вывод рубрик и названия текстов в них у наc теперь есть.

Не хватает вывода текста.

Давайте сделаем.


Это мы сделали не вывод самого текста, а проверку на его существование и получение данных по нему.

Не забудьте добавить в utils новый номер ошибки, а в начало текста новые переменные: out_text_id, out_text_name и out_text_dt.

Ну что, давайте теперь сформируем рабочие файлы и проверим мою писанину на работоспособность?

Итак, список рубрик у нас выводился так же, как и раньше, только немного изменен формат ссылок. Проверяем на /step/154/. Работает.

Раз рубрики ссылаются на /cat/?cat=, значит нам нужно создать поддиректорию /cat/ в директории WWW. И положить туда файл index.php, содержащий вывод всех работ в запрашиваемой рубрике.

Вот так он выглядит:


Как я его сделал? Взял корневой файл index.php и добавил несколько строк. Каких — догадайтесь сами.

Познакомлю вас только с самой первой. По-моему, такой у нас еще не было.

Она гласит: "Если посетитель зашел в директорию /cat/ без указания интересующей его рубрики, он прямиком отправляется на головную страницу".

Все, рубрикатор готов. Можете справа щелкать по рубрикам и видеть их содержимое.

Осталось вывести сам текст.

Это тоже будет просто. Мы скопируем файл index.php из папки cat в папку text и чуть его подправим.

Вот, что у меня получилось.


В центре выводим название, затем сам текст. Внизу справа — дата.

Все прилично, вроде.

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

До завтра!

[шаг назад] [печатать] [в начало сайта]



copyright ©2000-2017 Ruslan Kurepin