В стандартном функционале WordPress мы часто используем встроенные таблицы базы данных для хранения постов, пользователей, метаданных и прочей информации. Но иногда возникает необходимость хранить специфичные данные, которые не подходят под стандартные типы записей или метаданные. В таких случаях оптимальным решением будет создание собственной таблицы в базе данных WordPress. В этой статье подробно рассмотрим, как создать и правильно использовать собственную таблицу, обеспечив при этом безопасность и производительность.
Зачем создавать собственную таблицу в базе данных WordPress?
WordPress предлагает множество способов расширения данных — кастомные типы записей, таксономии, метаполя. Однако, если вам нужно хранить сложные структуры данных или выполнять сложные запросы, использование собственной таблицы может оказаться более эффективным и удобным.
Например, если вы создаёте плагин для управления бронированиями, заказами или аналитикой, где каждая запись имеет множество параметров и связей, собственная таблица позволит:
- Оптимизировать структуру данных под конкретные задачи.
- Сократить нагрузку на стандартные таблицы WordPress.
- Упростить и ускорить выполнение сложных SQL-запросов.
Создание таблицы: используем dbDelta и wpdb
Для создания таблицы мы будем использовать функцию dbDelta — она позволяет безопасно создавать и обновлять таблицы по SQL-запросу. Для начала подключим глобальный объект $wpdb, который отвечает за работу с базой данных.
Пример создания таблицы для хранения заказов (orders) с полями id, user_id, product_id, quantity и order_date:
function wponline_create_orders_table() {
global $wpdb;
$table_name = $wpdb->prefix . 'wponline_orders';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
user_id bigint(20) NOT NULL,
product_id bigint(20) NOT NULL,
quantity int NOT NULL,
order_date datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (id),
KEY user_id (user_id),
KEY product_id (product_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
register_activation_hook(__FILE__, 'wponline_create_orders_table');Обратите внимание, что имя таблицы формируется с префиксом $wpdb->prefix, что обеспечивает уникальность и согласованность с настройками WordPress.
Почему dbDelta и как он работает
Функция dbDelta анализирует текущую структуру таблицы и SQL-запрос, создавая таблицу или обновляя её структуру без потери данных. Это очень удобно при обновлениях плагина.
Важно: SQL-запрос должен строго соответствовать формату, поддерживаемому dbDelta, включая правильные пробелы, ключевые слова и типы данных.
Добавление, обновление и получение данных из собственной таблицы
Для работы с таблицей используем объект $wpdb и его методы insert, update, get_results и другие.
Добавление записи
function wponline_insert_order($user_id, $product_id, $quantity) {
global $wpdb;
$table_name = $wpdb->prefix . 'wponline_orders';
$result = $wpdb->insert(
$table_name,
[
'user_id' => $user_id,
'product_id' => $product_id,
'quantity' => $quantity,
'order_date' => current_time('mysql')
],
['%d', '%d', '%d', '%s']
);
return $result !== false;
}Здесь важно указывать формат данных для предотвращения SQL-инъекций и корректного форматирования запроса.
Обновление записи
function wponline_update_order_quantity($order_id, $quantity) {
global $wpdb;
$table_name = $wpdb->prefix . 'wponline_orders';
return $wpdb->update(
$table_name,
['quantity' => $quantity],
['id' => $order_id],
['%d'],
['%d']
);
}Получение записей
function wponline_get_orders_by_user($user_id) {
global $wpdb;
$table_name = $wpdb->prefix . 'wponline_orders';
$query = $wpdb->prepare("SELECT * FROM $table_name WHERE user_id = %d ORDER BY order_date DESC", $user_id);
return $wpdb->get_results($query);
}Запросы через $wpdb->prepare обеспечивают безопасность, экранируя параметры.
Безопасность и оптимизация собственной таблицы
Создавая собственную таблицу, важно соблюдать правила безопасности:
- Используйте
$wpdb->prepareдля всех входящих данных. - Не выполняйте динамические SQL-запросы без экранирования.
- Добавляйте индексы на часто используемые поля для ускорения запросов.
- Регулярно проверяйте и оптимизируйте таблицу с помощью SQL-команд
OPTIMIZE TABLE.
Для оптимизации запросов продумывайте структуру таблицы, избегайте избыточных данных и используйте типы данных по назначению.
Пример интеграции собственной таблицы с интерфейсом WordPress
Для удобства работы с данными создадим административную страницу, где можно будет просматривать заказы.
function wponline_register_admin_menu() {
add_menu_page(
'Заказы WPOnline',
'Заказы',
'manage_options',
'wponline_orders',
'wponline_render_orders_page'
);
}
add_action('admin_menu', 'wponline_register_admin_menu');
function wponline_render_orders_page() {
if (!current_user_can('manage_options')) {
wp_die('Доступ запрещён');
}
$orders = wponline_get_orders_by_user(get_current_user_id());
echo '<h1>Мои заказы</h1>';
if (empty($orders)) {
echo '<p>Заказы отсутствуют.</p>';
return;
}
echo '<table class="wp-list-table widefat fixed">';
echo '<thead><tr><th>ID</th><th>Продукт</th><th>Количество</th><th>Дата заказа</th></tr></thead>';
echo '<tbody>';
foreach ($orders as $order) {
echo '<tr>';
echo '<td>' . esc_html($order->id) . '</td>';
echo '<td>' . esc_html($order->product_id) . '</td>';
echo '<td>' . esc_html($order->quantity) . '</td>';
echo '<td>' . esc_html($order->order_date) . '</td>';
echo '</tr>';
}
echo '</tbody></table>';
}Таким образом, администратор или пользователь сможет видеть свои данные в привычном интерфейсе WordPress.