Как создать таблицу в базе данных для плагина WordPress?

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

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

Далее будет рассмотрено, как “научить” плагин автоматически создавать таблицу при активации. Для этого нужно выполнить три шага:

  • написать php-функцию, которая будет создавать таблицу;
  • убедиться, что WordPress вызывает эту функцию при активации плагина;
  • написать функцию обновления, на тот случай, если у обновлённого плагина будет иная структура таблицы.

Создание таблицы базы данных

Рассмотрим первый шаг: написание функции вашего плагина, создающей таблицу БД при активации плагина. Предположим, что вы захотите назвать эту функцию “jal_install”.

Префикс таблицы базы данных

В файле wp-config.php владелец сайта на WordPress может задать префикс таблиц. По умолчанию это “wp_”, но необходимо проверить текущий префикс и в дальнейшем использовать его для определения имени таблицы. Узнать префикс можно командой $wpdb->prefix (в версиях WordPress старше 2.0 нужно использовать глоальную переменную $table_prefix, которая не рекомендуется в версиях WordPress, начиная с 2.1).
Итак, если вы хотите создать таблицу с именем (prefix)liveshoutbox, то первые строки функции, создающей таблицу, будут выглядеть так:

function jal_install () {
   global $wpdb;
   $table_name = $wpdb->prefix . "liveshoutbox";

Таблица уже создана?

Следующим шагов в создании таблицы будет проверка, создана ли уже такая таблица. Для этого нужно выполнить запрос SHOW TABLES SQL, что бы попытаться найти таблицу и сравнить результат с именем нашей таблицы.

if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {

Создание или обновление таблицы

Следующий шаг состоит в том, чтобы действительно создать таблицу базы данных. Вместо того, что бы выполнять SQL запросы напрямую, мы будем использовать функцию dbDelta из wp-admin/upgrade-functions.php (следует загрузить этот файл, поскольку он не загружен по умолчанию). Функция dbDelta анализирует нынешнюю структуру таблицы, сравнивает ее с желаемой структуры таблицы, и либо добавляет или изменяет таблицу по мере необходимости, что может быть очень удобно для обновления (см. wp-admin/upgrade-schema.php для примера использования dbDelta). Однако, стоит заметить, что dbDelta довольно требовательна. Например:

  • Вы должны разместить каждое поле на отдельной строке в Вашем SQL запросе;
  • Между словами “PRIMARY KEY” и определение основного ключа должно быть два пробела;
  • Вы должны использовать ключевые слова KEY, а не его синоним INDEX.

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

$sql = "CREATE TABLE " . $table_name . " (
	  id mediumint(9) NOT NULL AUTO_INCREMENT,
	  time bigint(11) DEFAULT '0' NOT NULL,
	  name tinytext NOT NULL,
	  text text NOT NULL,
	  url VARCHAR(55) NOT NULL,
	  UNIQUE KEY id (id)
	);";

require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);

Добавление исходных данных

Наконец, вы можете добавить некоторые данные в таблицу, которую только что создали (как я понимаю, именно таким способом добавляется первый пост и комментарий при установке WP; на мой взгляд, в плагине это лишнее. – прим. Dandr). Вот пример того, как это сделать:

  $welcome_name = "Mr. WordPress";
  $welcome_text = "Congratulations, you just completed the installation!";

  $insert = "INSERT INTO " . $table_name .
            " (time, name, text) " .
            "VALUES ('" . time() . "','" . $wpdb->escape($welcome_name) . "','" . $wpdb->escape($welcome_text) . "')";

  $results = $wpdb->query( $insert );

ПРИМЕЧАНИЕ: Даже если мы определили $welcome_name и $welcome_text в этой функции, и знаем, что в них нет SQL специальных символов, не помешает всегда запускать $ wpdb-> escape(function) перед передачей ее в базу данных для предотвращения проблем в области безопасности и случайных ошибок.

Опция версии

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

add_option("jal_db_version", "1.0");

Функция целиком

Итак, функция написана. Давайте посмотрим весь код полностью. Имейте в виду, что номер версии в настоящее время хранится в глобальной переменной.

$jal_db_version = "1.0";

function jal_install () {
   global $wpdb;
   global $jal_db_version;

   $table_name = $wpdb->prefix . "liveshoutbox";
   if($wpdb->get_var("show tables like '$table_name'") != $table_name) {
      
      $sql = "CREATE TABLE " . $table_name . " (
	  id mediumint(9) NOT NULL AUTO_INCREMENT,
	  time bigint(11) DEFAULT '0' NOT NULL,
	  name tinytext NOT NULL,
	  text text NOT NULL,
	  url VARCHAR(55) NOT NULL,
	  UNIQUE KEY id (id)
	);";

      require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
      dbDelta($sql);

      $welcome_name = "Mr. WordPress";
      $welcome_text = "Congratulations, you just completed the installation!";

      $insert = "INSERT INTO " . $table_name .
            " (time, name, text) " .
            "VALUES ('" . time() . "','" . $wpdb->escape($welcome_name) . "','" . $wpdb->escape($welcome_text) . "')";

      $results = $wpdb->query( $insert );
 
      add_option("jal_db_version", $jal_db_version);

   }
}

Вызов функции

Теперь следует убедиться в том, что WordPress вызывает эту функцию при активации плагина. Для этого мы воспользуемся “activate_ action hook” (активационным крючком??? – Dandr). Если файл вашего плагина wp-content/plugins/plugindir/pluginfile.php, то вам следует добавить следующие строки в текст вашего плагина:

register_activation_hook(__FILE__,'jal_install');

См. Function_Reference/register_activation_hook для получения более подробной информации.

Функция добавления и обновления

Со временем, вы можете обнаружить, что вам нужно изменить плагин и изменить структуру базы данных в обновленной версии.. Для этого вам нужно будет обновить код вашего плагина, который будет обнаруживать, обновления плагина, а также обновлять структуру базы данных. Проще всего это сделать, добавив код к функции jal_install, которую мы только что создали.
Имейте в виду, вам нужно убедиться, что функция вызывается. Т.е., пользователи вашего плагина, должны при обновлении они отключить плагин, скопировать новый файл плагина на сервер, а затем включить плагин снова.
Итак, давайте предположим, что функция была использована для создания базы данных версии 1.0, а вы сейчас обновляете до версии 1.1, в которой поле URL может быть шире (100 символов вместо 55). Вам нужно добавить следующие строки в конец вашей функции jal_install, для проверки версии и обновления в случае необходимости:

   $installed_ver = get_option( "jal_db_version" );

   if( $installed_ver != $jal_db_version ) {

      $sql = "CREATE TABLE " . $table_name . " (
	  id mediumint(9) NOT NULL AUTO_INCREMENT,
	  time bigint(11) DEFAULT '0' NOT NULL,
	  name tinytext NOT NULL,
	  text text NOT NULL,
	  url VARCHAR(100) NOT NULL,
	  UNIQUE KEY id (id)
	);";

      require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
      dbDelta($sql);

      update_option( "jal_db_version", $jal_db_version );
  }

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


Данная статья является вольным, но достаточно близким переводом Creating Tables with Plugins.

Запись опубликована в рубрике HOWTO с метками , , , . Добавьте в закладки постоянную ссылку.

9 комментариев на «Как создать таблицу в базе данных для плагина WordPress?»

  1. А чтоб, русского перевода еще нигде не было??
    А так, правда полезно.

  2. Christian Archer говорит:

    Хороший тон еще удалять таблицу после деактивации плагина.

  3. Dandr говорит:

    Christian Archer, согласен. До этого я ещё не дошёл)))

  4. lilumi говорит:

    вот и ученик превзошел учителя — для меня это темный лес, так как еще ни разу не писал собственного плагина с нуля

  5. Dandr говорит:

    Миш, мне, конечно, лестно читать такие слова, но мы с тобой оба прекрасно понимаем, что у нас слишком разный уровень.
    ЗЫ “не писал” и “не могу написать” – несколько разные вещи. У тебя просто не было необходимости в этом)))

  6. lilumi говорит:

    да нет же — я отстойный программер

  7. Dandr говорит:

    lilumi, странно, и чего это я тебе не верю? 🙂

  8. Narehh говорит:

    Я сделала все как написано, но в ДБ не добавляется таблица.

Добавить комментарий для Christian ArcherОтменить ответ