Основы WordPress: взаимодействие с базой данных (часть 2)

Дата публикации:Сентябрь 29, 2011

Помимо рассмотренных в прошлой статье прекрасных методов существует множество других переменных и функций, упрощающих жизнь любому веб-разработчику. Я остановлюсь лишь на некоторых из них, наиболее распространенных и востребованных; в случае острой необходимости остальные функции можно будет получить из Codex’а.

insert_id()

Всякий раз, когда вы вставляете что-либо в таблицу, у вас происходит (не всегда, но очень часто) автоинкрементная индексация по ID. Чтобы найти значение последней вставки, выполненной вашим скриптом, вы можете использовать $wpdb->insert_id:

$sql = $wpdb->prepare( "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value ) VALUES ( %d, %s, %d )", 3342, 'post_views', 2290 )
   $wpdb->query($sql);

   $meta_id = $wpdb->insert_id;

num_rows()

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

Имена таблиц

Все базовые имена таблиц хранятся в переменных, которые названы точно так же, как и их табличные эквиваленты. Имя вашей таблицы с записями (обычно wp_posts) было бы сохранено в переменной $posts; вы можете легко его вывести с помощью $wpdb->posts.

Такая конструкция используется в результате того, что пользователь может самостоятельно определять префикс для таблиц. Несмотря на то что большинство людей остаются верными стандартному префиксу wp, остаются и те, кто меняет его в угоду большей гибкости. Таким образом, если вы разработали свой плагин и используете в его коде wp_postmeta вместо $wpdb->postmeta для запросов, этот плагин не будет работать на некоторых веб-сайтах.

Если вы хотите получить данные из таблиц WordPress, не входящих в ядро, вам понадобится писать их название вручную, поскольку для них не предусмотрено никаких специальных переменных.

Обработка ошибок

Методы show_errors() и hide_errors() позволяют включить/выключить сообщения об ошибках (по умолчанию выключены). Также вы можете использовать метод print_error(), чтобы вывести на экран ошибки для последнего запроса.

$wpdb->show_errors();
   $wpdb->query("DELETE FROM wp_posts WHERE post_id = 554 ");

   // When run, because show_errors() is set, the error message will tell you that the "post_id" field is an unknown
   // field in this table (since the correct field is ID)    

Создание простого отслеживания с помощью $wpdb

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

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

Структура таблиц

Чтобы отследить все щелчки по рекламным объявлениям, а также их просмотры, я создал таблицу; давайте назовем ее «tracking». В эту таблицу в режиме реального времени будут заноситься действия пользователя. Каждый рекламный переход записывается в собственной строке и структурируется следующим образом:

  • ID. Автоинкрементная индексация по ID.
  • time. Время и дата, когда было совершено действие.
  • deal_id. ID соглашения, которое соединяется с действием (т.е. рекламное объявление, по которому был совершен щелчок или которое было просмотрено)
  • action. Тип действия (щелчок или просмотр)
  • action_url. Страница, с которой было инициировано действие.
  • user_id. Если пользовать зарегистрирован, то его ID.
  • user_ip. IP адрес пользователя

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

Вставка данных в таблицу

Щелчок пользователя по объявлению автоматически детектируется, и информация, в которой мы нуждаемся, передается нашему скрипту в форме массива $_POST со следующими данными:

Array
(
   [deal_id] => 643
   [action] => click
   [action_url] => http://thisiswhereitwasclicked.com/about/
   [user_id] => 223
   [user_ip] = 123.234.223.12
)

Мы можем вставить эти данные в БД с помощью хелпера:

$wpdb->insert('tracking', array("deal_id" => 643, "action" => "click", "action_url" => "http://thisiswhereitwasclicked.com/about/",
"user_id" => 223, "user_ip" => "123.234.223.12"), array("%d", %s", "%s", "%d", "%s"));

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

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

Удаление сразу всех кликов, совершенных администраторами, выполняется гораздо проще, чем проверка на их появление в каждой вставке. Такая проверка заметно нагружает сервер.

Удаление действий от пользователей, IP-которых находится в черном списке

Если мы считаем, что IP-адрес (к примеру, 168.211.23.43), слишком нам надоедает, мы можем поместить его в черный список. В таком случае, если бы мы собирали ежедневные данные, нам понадобилось бы удалить все заметки, выполненные с этого IP:

$sql = $wpdb->prepare("DELETE FROM tracking WHERE user_ip = %s ", '168.211.23.43');
   $wpdb->query($sql);

Вы, наверно, заметили, что я все еще экранирую данные, даже учитывая то, что IP был получен от безопасного источника. Я предлагаю экранировать ваши данные вне зависимости от обстоятельств. Хакеры — превосходные программисты. Они могут перехитрить вас такими способами, о которых вы не подозреваете. К тому же, я и сам могу повредить свои же сайты сильнее, чем любой хакер, поэтому меры предосторожности я произвожу и для себя.

Обновление результатов

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

$total = $wpdb->get_var(«SELECT COUNT(ID) WHERE deal_id = 125 «);

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

$wpdb->update( $wpdb->postmeta, array("meta_value" => $total), array("ID" => 125), array("%d"), array("%d") );

   // примечание: далее должен следовать update_post_meta(), но я его упущу, чтобы не усложнять пример     

Заключительные мысли и советы

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

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

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

SELECT title, ID FROM wp_posts ORDER BY post_date DESC LIMIT 0,5.

Несмотря на то что вы всегда можете прибегнуть к помощи метода query(), рекомендуется по возможности останавливать свой выбор на хелперах (insert, update, get_row, etc.). Они являются примитивными кирпичиками, позволяющими создавать простые запросы. К тому же хелперы автоматически экранируют данные, что делает их использование безопасным.

Внимательно подходите к удалению записей из базы данных WordPress. Когда в WordPress удаляется любой комментарий, происходит огромное количество действий: число комментариев в таблице wp_posts уменьшается на единицу, удаляются все данные в таблице comment_meta и т.д. При удалении убедитесь в том, что вы очистили все лишнее.

Чтобы использовать богатый потенциал класса, изучайте официальную документацию. Я также рекомендую обратить свое внимание на класс ezSQL, котрый можно использовать в своих проектах, не связанных с WordPress; я применяю его практически во всех своих разработках.

http://wp.smashingmagazine.com/2011/09/21/interacting-with-the-wordpress-database/

Поделиться

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

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