Основы WordPress: взаимодействие с базой данных (часть 1)
В WordPress существует огромное количество различных функций, предназначенных для взаимодействия с базой данных. Несмотря на их удобство, они не являются единственно возможным решением. В данной статье мы рассмотрим простой и безопасный способ взаимодействия с базой данных, который основан на использовании класса $wpdb. Класс $wpdb, базирующийся на великолепном классе ezsql, автором которого является Джастин Винсент, позволяет выполнить запрос к любой таблице базы данных, а также помогает произвести обработку возвращенных данных. Поскольку класс является частью базовой функциональности WordPress, пользователям не нужно открывать отдельное соединение с базой данных (в данном случае вам понадобилось бы копировать фрагмент кода), и отпадает потребность в создании хаков, таких как изменение итогового набора после выполнения запроса.
В данной статье я покажу вам, как начать работу с классом $wpdb, как получить данные из БД WordPress и как выполнить более сложные запросы, которые позволяют обновить или удалить что-либо в базе данных. Методы, рассмотренные далее, позволяют обойти некоторые ограничения, выставляемые различными функциями, такими как get_posts() и wp_list_categories(). Вы сможете адаптировать запросы под свои собственные потребности, поднять производительность своего сайта, получая только те данные, которые действительно необходимы.
Если вы знаете, как функционирует MySQL или другие похожие языки, то никаких проблем при работе с классом $wpdb у вас не возникнет; вам понадобится лишь запомнить небольшое количество функций. Основное использование класса становится понятным на примере. Давайте создадим запрос к базе данных, позволяющий получить идентификаторы и заголовки четырех последних записей в порядке убывания числа комментариев.
<?php $posts = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_status = 'publish' AND post_type='post' ORDER BY comment_count DESC LIMIT 0,4") ?>
Как вы успели заметить, здесь приведен SQL-запрос, обернутый в PHP-код. Класс $wpdb содержит метод (методы – это специальное название для функций, являющихся внутренними для классов) под названием get_results(), который не только отправляет результаты работы, но и помещает их в удобный объект. Вы, возможно, заметили, что вместо wp_posts я использовал $wpdb->posts для получения доступа к базовым таблицам WordPress. Я еще вернусь к этому в дальнейшем.
Объект $results содержит полученные данные в следующем формате:
Array ( [0] => stdClass Object ( [ID] => 6 [post_title] => The Male Angler Fish Gets Completely Screwed ) [1] => stdClass Object ( [ID] => 25 [post_title] => 10 Truly Amazing Icon Sets From Germany ) [2] => stdClass Object ( [ID] => 37 [post_title] => Elderberry Is Awesome ) [3] => stdClass Object ( [ID] => 60 [post_title] => Gathering Resources and Inspiration With Evernote ) )
Получение результатов из базы данных
Если вы хотите получить некоторую информацию из базы данных, вы можете использовать одну из четырех функций, предназначенных для структурирования данных.
get_results()
Функция, с которой мы уже успели столкнуться ранее. Позволяет преобразовать данные в массив, который содержит отдельные объекты в каждой строке:
<?php $posts = $wpdb->get_results("SELECT ID, post_title FROM wp_posts WHERE post_status = 'future' AND post_type='post' ORDER BY post_date ASC LIMIT 0,4") // Echo the title of the first scheduled post echo $posts[0]->post_title; ?>
get_row
Когда вам требуется найти одну определенную строку в базе данных (к примеру, запись с наибольшим числом комментариев), вы можете использовать функцию get_row(). Она представляет искомые данные в виде одномерного объекта.
<?php $posts = $wpdb->get_row("SELECT ID, post_title FROM wp_posts WHERE post_status = 'publish' AND post_type='post' ORDER BY comment_count DESC LIMIT 0,1") // Echo the title of the most commented post echo $posts->post_title; ?>
get_col
Метод очень похож на get_row, за единственным исключением: он получает отдельный столбец. Это действие полезно в том случае, если вы нуждаетесь в идентификаторах для 10 самых комментируемых записей. Как и get_row, функция get_col хранит результаты в одномерном объекте.
<?php $posts = $wpdb->get_col("SELECT ID FROM wp_posts WHERE post_status = 'publish' AND post_type='post' ORDER BY comment_count DESC LIMIT 0,10") // Echo the ID of the 4th most commented post echo $posts[3]->ID; ?>
get_var
В большинстве случаев вы будете нуждаться только в одном значении из базы данных; к примеру, вам может понадобиться электронная почта одного из пользователей. В этой ситуации вы можете использовать функцию get_var, позволяющую получить единственное значение. Тип данных для полученного значения не будет отличаться от типа данных этого же значения, хранящегося в БД (целые числа останутся целыми числами, строки останутся строками).
<?php $email = $wpdb->get_var("SELECT user_email FROM wp_users WHERE user_login = 'danielpataki' ") // Echo the user's email address echo $email; ?>
Вставка в базу данных
Чтобы произвести вставку, мы можем воспользоваться соответствующим методом, именуемым методом вставки:
$wpdb->insert( $table, $data, $format);
Этот метод получает три аргумента. Первый аргумент определяет название таблицы, в которую вы вставляете данные. Второй аргумент – массив, который содержит столбцы и соответствующие им значения, хранящиеся в виде пар “key-value” (“ключ-значение”). Третий аргумент определяет тип данных для ваших значений в том порядке, в котором вы задали их. Пример:
<?php $wpdb->insert($wpdb->usermeta, array("user_id" => 1, "meta_key" => "awesome_factor", "meta_value" => 10), array("%d", "%s", "%d")); // Equivalent to: // INSERT INTO wp_usermeta (user_id, meta_key, meta_value) VALUES (1, "awesome_factor", 10); ?>
На первый взгляд этот метод может показаться вам слишком громоздким, особенно если вы привыкли вручную записывать свои вставки, однако на самом деле он предлагает большую гибкость, поскольку в качестве ввода в нем используются массивы.
Определение формата является дополнительным аргументом; по умолчанию все значения обрабатываются как строки. Несмотря на это хорошим тоном считается явное указание формата. Вы можете использовать три значения: %s для строк, %d для десятичных чисел и %f для чисел с плавающей запятой.
Обновление данных
Для обновления данных используется метод под названием update(). Он аналогичен методу, рассмотренному выше, за тем лишь исключением, что нам понадобится обработать логическую цепь нашего обновления, которая задана в переменной where; для этой цели мы воспользуемся двумя дополнительными параметрами.
Переменные $table, $data и $format остались прежними. В переменной $where содержатся условия обновления, которые представляют собой массив, заданный в форме column-value (столбец-значение). Если вы определили несколько параметров, все они должны быть связаны друг с другом с помощью логического AND. Переменная $where_format во многом подобна $format: она определяет формат значений, хранящихся в переменной $where.
$wpdb->update( $wpdb->posts, array("post_title" => "Modified Post Title"), array("ID" => 5), array("%s"), array("%d") );
Другие запросы
Хелперы, приведенные выше, позволяют справиться лишь с простыми задачами. Как быть с более сложными запросами? Если вам необходимо выполнить обновление с комплексным условием where, содержащим многократную логику AND/OR, вы не сможете использовать метод update(). Если вы хотите сделать что-либо наподобие удаления строки или задания набора символов, вам понадобится прибегнуть к помощи “общего” метода query(), который позволяет выполнить любой тип запросов.
$wpdb->query("DELETE FROM wp_usermeta WHERE meta_key = 'first_login' OR meta_key = 'security_key' ");
Защита и валидация данных
Я надеюсь, вам не надо рассказывать о том, как важно, чтобы данные, находящиеся в БД, хранились в безопасности и не допускали стороннего вмешательства. Валидация данных выходит за рамки этой статьи, поэтому я не буду ее касаться.
Чтобы избежать SQL-инъекций, необходимо провести экранирование спецсимволов. В том случае, если вы используете хелперы, вам не понадобится ничего делать – все уже будет сделано за вас. Однако в случае с методом query() вам понадобится ставить защиту вручную с помощью метода prepare():
$sql = $wpdb->prepare( 'query' [, value_parameter, value_parameter ... ] );
Чтобы сделать код более удобоваримым, давайте немного изменим основной формат:
$sql = $wpdb->prepare( "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value ) VALUES ( %d, %s, %d )", 3342, 'post_views', 2290 ) $wpdb->query($sql);
Вместо добавления значений, как это было ранее, вы сначала вводите тип данных, а затем добавляете фактические данные в качестве последующих параметров.
http://wp.smashingmagazine.com/2011/09/21/interacting-with-the-wordpress-database/