В этой статье мы разберём функции SMF для создания и изменения таблиц в базе данных.
Если хотите проверить все рассматриваемые функции в деле, потребуется тестовая площадка:
- Установленный форум (чтобы было, на чем тестировать вживую)
- VarDumper for SMF или SMF Tracy Debugger (чтобы была возможность использовать функцию
dump()
)
Все нужные методы для работы с таблицами в базе данных находятся в глобальном ассоциативном массиве $smcFunc
, который устанавливается в корневом index.php
, заполняется в Load.php
и дополняется в файлах DbExtra-mysql.php
, DbExtra-postgresql.php
, DbPackages-mysql.php
, DbPackages-postgresql.php
, DbSearch-mysql.php
, DbSearch-postgresql.php
, Subs-Db-mysql.php
и Subs-Db-postgresql.php
, в зависимости от типа используемой базы данных. А поскольку массив глобальный, не забывайте объявлять global $smcFunc
в своих функциях/методах.
В массиве $smcFunc
хранятся не только функции для работы с базой данных, но также и различные хэлперы, с которыми мы обязательно познакомимся в одном из будущих уроков.
Набор основных функций для работы с запросами находится в Subs-Db-mysql.php
|Subs-Db-postrgesql.php
. Рассмотрим их подробнее.
Универсальная функция для обработки запросов любой сложности. Вторым аргументом можно передать любой запрос. Например, получим все записи из таблицы:
$request = $smcFunc['db_query']('', 'SELECT * FROM {db_prefix}members');
dump($smcFunc['db_fetch_all']($request));
Как и db_query
, экранирует и заключает в кавычки строку, но не выполняет запрос. Пример:
$userQuery = $smcFunc['db_quote'](
'(m.id_member IN ({array_int:matched_members}) OR (m.id_member = {int:id_member_guest} AND ({raw:match_possible_guest_names})))',
array(
'matched_members' => [1,2,3],
'id_member_guest' => 0,
'match_possible_guest_names' => 'm.poster_name LIKE ' . implode(' OR m.poster_name LIKE ', ['Test1', 'Test2', 'Test3']),
)
);
dump($userQuery);
Результат:
'(m.id_member IN (1, 2, 3) OR (m.id_member = 0 AND (m.poster_name LIKE Test1 OR m.poster_name LIKE Test2 OR m.poster_name LIKE Test3)))'
Возвращает следующую строку результата запроса в виде ассоциативного массива. Пример:
$request = $smcFunc['db_query']('', 'SELECT * FROM {db_prefix}members');
while ($row = $smcFunc['db_fetch_assoc']($request))
dump($row);
Возвращает следующую строку результата запроса в виде обычного массива. Пример:
$request = $smcFunc['db_query']('', '
SELECT * FROM {db_prefix}members
WHERE id_member = {int:id}
LIMIT 1',
array(
'id' => 1
)
);
dump($smcFunc['db_fetch_row']($request));
Результат будет выглядеть как-то так:
array(
0 => '1'
1 => 'Test'
2 => '1631176348'
3 => '54'
4 => '1'
5 => 'russian'
6 => '1651629543'
...
)
Возвращает все строки результата запроса в виде ассоциативного массива. См. пример использования `$smcFunc['db_query'].
Освобождает память от результата запроса $request
. Указывайте после каждого использования $smcFunc['db_fetch_assoc'],
$smcFunc['db_fetch_all'] и `$smcFunc['db_free_result']:
$smcFunc['db_free_result']($request);
Добавляет новую запись в указанную таблицу. Пример:
$smcFunc['db_insert']('',
'{db_prefix}messages',
$message_columns,
$message_parameters,
array('id_msg')
);
Чтобы получить идентификатор добавленной записи, можно указать 1
в качестве последнего параметра или использовать `$smcFunc['db_insert_id'] (см. ниже):
$id = $smcFunc['db_insert']('',
'{db_prefix}messages',
$message_columns,
$message_parameters,
array('id_msg'),
1
);
Возвращает идентификатор только что добавленной записи. Пример:
$smcFunc['db_insert']('',
'{db_prefix}messages',
$message_columns,
$message_parameters,
array('id_msg')
);
dump($smcFunc['db_insert_id']);
Возвращает количество строк результата запроса. Пример:
$request = $smcFunc['db_query']('', 'SELECT * FROM {db_prefix}members');
dump($smcFunc['db_num_rows']($request));
Переходит к заданной строке $i
в результирующем наборе $request
. Пример:
$smcFunc['db_data_seek']($request, $i);
Пример использования на практике см. в файле Sources/Memberlist.php
.
Возвращает количество полей результата запроса. Пример:
$request = $smcFunc['db_query']('', 'SELECT * FROM {db_prefix}members');
dump($smcFunc['db_num_fields']($request));
Возвращает строку с экранированными специальными символами, для использования в выражениях SQL. Пример:
$test = "'123'";
dump($smcFunc['db_escape_string']($test));
Результат:
'\'123\''
Удаляет экранирование символов. Синоним для функции stripslashes
. Пример:
$test = "\'123\'";
dump($smcFunc['db_unescape_string']($test));
Результат:
"'123'"
Возвращает версию используемого сервера базы данных. Пример:
dump($smcFunc['db_server_info']());
Результат будет выглядеть как-то так:
'5.5.5-10.6.7-MariaDB'
Возвращает число строк, затронутых последним запросом INSERT, UPDATE, REPLACE или DELETE. Пример:
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}members
WHERE id_member IN ({array_int:ids})',
array(
'ids' => [12, 13, 14]
)
);
dump($smcFunc['db_affected_rows']());
Осуществляет один из этапов транзакции (begin
, commit
, rollback
). Пример:
// Инициализация транзакции
$smcFunc['db_transaction']('begin');
$id = $smcFunc['db_insert']('',
'{db_prefix}messages',
$message_columns,
$message_parameters,
array('id_msg'),
1
);
// далее могут быть другие запросы
if (empty($id)) {
// Откат изменений (все запросы выше откатываются, как будто их и не было)
$smcFunc['db_transaction']('rollback');
return;
}
// Фиксация изменений (все запросы подтверждаются)
$smcFunc['db_transaction']('commit');
Пример использования на практике можно увидеть в исходном коде Light Portal.
Возвращает строку с описанием последней ошибки. Пример:
dump($smcFunc['db_error']($db_connection));
Устанавливает базу данных для выполняемых запросов. Вряд ли пригодится, но вдруг вам захочется подключиться к другой базе данных во время работы с SMF? Пример:
// Выбираем базу данных
$smcFunc['db_select_db']('other_database');
// Осуществляем другие запросы
Возвращает название используемого движка базы данных. Пример:
dump($smcFunc['db_title']());
Экранирует знаки подстановки и возвращает строку с произведёнными заменами. Пример:
$test = '%some_text%';
dump($smcFunc['db_escape_wildcard_string']($test));
Результат:
'\%some\_text\%'
Конструирует оптимизированную строку пользовательского заказа как улучшенная альтернатива find_in_set()
. Пример:
dump($this->smcFunc['db_custom_order']('status', [1, 0]));
Результат:
'CASE status WHEN 1 THEN 0 WHEN 0 THEN 1 END'
Возвращает true
, если база данных поддерживает Common Table Expression (Общие Табличные Выражения). Пример подобного выражения:
SELECT * FROM smf_members;
WITH cte_members AS (
SELECT COUNT(*) as total
FROM smf_members
WHERE is_activated = "1" GROUP BY is_activated
)
SELECT total as `Всего активных пользователей`
FROM cte_members;
Пример использования на практике рекурсивных CTE можно посмотреть в плагине RandomTopics для модификации Light Portal. Примеры других CTE-запросов доступны здесь.
Перед использованием этой группы функций нужно подготовить массив $smcFunc
с помощью вызова db_extend('packages');
.
Добавляет столбец в указанную таблицу. Пример:
$smcFunc['db_add_column'](
'{db_prefix}my_table',
array(
'name' => 'content',
'type' => 'text',
'null' => false,
'not_null' => true
),
array(),
'do_nothing'
);
Добавляет индекс в указанную таблицу. Пример:
$table_name = '{db_prefix}my_table';
$index_info = array(
'name' => 'my_index',
'type' => 'index', // 'index', 'unique', 'primary'
'columns' => array(
'column1', 'column2'
)
);
$smcFunc['db_add_index']($table_name, $index_info);
К сожалению, не все типы индексов можно добавить таким образом. Некоторые (например, FULLTEXT
) добавляются лишь «по старинке», с помощью обычного SQL:
$smcFunc['db_query']('', '
ALTER TABLE {db_prefix}table_name
ADD FULLTEXT index_name (column_name)',
array()
);
Возвращает массив с указанными именем и типом столбца. Пример:
dump($smcFunc['db_calculate_type']('varchar', 255));
Результат:
array(
0 => 'varchar'
1 => 255
)
Изменяет столбец в указанной таблице. Пример:
$column_info = array(
'name' => 'new_name',
'type' => 'new_type',
... // и т. д.
);
$smcFunc['db_change_column']('{db_prefix}my_table', 'column_name', $column_info);
Создаёт таблицу с заданными столбцами, каждый из которых представляет собой массив. Пример:
$tables[] = array(
'name' => 'my_table',
'columns' => array(
array(
'name' => 'id',
'type' => 'int',
'size' => 10,
'unsigned' => true,
'auto' => true
),
array(
'name' => 'title',
'type' => 'varchar',
'size' => 255,
'null' => false,
'not_null' => true
),
array(
'name' => 'created_at',
'type' => 'int',
'size' => 10,
'unsigned' => true
)
),
'indexes' => array(
array(
'type' => 'primary',
'columns' => array('id')
),
)
);
db_extend('packages');
foreach ($tables as $table) {
$smcFunc['db_create_table']('{db_prefix}' . $table['name'], $table['columns'], $table['indexes']);
}
Удаляет указанную таблицу. Пример:
$smcFunc['db_drop_table']('{db_prefix}my_table');
Возвращает структуру таблицы. Пример:
dump($smcFunc['db_table_structure']('{db_prefix}messages'));
Результат:
array(4)
'name' => 'smf_messages'
'columns' => array(18)
'indexes' => array(11)
'engine' => 'InnoDB'
Возвращает информацию о столбцах указанной таблицы. Второй параметр отвечает за отображение подробных сведений о столбцах. Пример:
dump($smcFunc['db_list_columns']('{db_prefix}messages', true));
Возвращает информацию об индексах указанной таблицы. Второй параметр отвечает за отображение подробных сведений о столбцах. Пример:
dump($smcFunc['db_list_indexes']('{db_prefix}messages', true));
Удаляет заданный столбец из указанной таблицы. Пример:
$smcFunc['db_remove_column']('{db_prefix}my_table', 'column_name');
Удаляет заданный индекс из указанной таблицы. Пример:
$smcFunc['db_remove_index']('{db_prefix}my_table', 'index_name');
Перед использованием этой группы функций нужно подготовить массив $smcFunc
с помощью вызова db_extend('search');
.
Синоним `$smcFunc['db_query'].
Возвращает true
, если базой данных поддерживается указанный тип поиска. Пример:
dump($smcFunc['db_search_support']('fulltext'));
Используется для создания пользовательской таблицы с индексами слов (см. Поисковое индексирование в настройках поиска).
Возвращает язык для индекса текстового поиска. Пример:
dump($smcFunc['db_search_language']())
Пример использования на практике можно увидеть в исходном коде Similar Topics.
Перед использованием этой группы функций нужно подготовить массив $smcFunc
с помощью вызова db_extend('extra');
или просто db_extend()
(extra
является значением по умолчанию).
Создает резервную копию указанной таблицы. Пример:
$smcFunc['db_backup_table']('{db_prefix}members', 'backup_members');
Оптимизирует указанную таблицу. Пример:
$smcFunc['db_optimize_table']('{db_prefix}members');
Выводит в виде дампа SQL-схему CREATE для указанной таблицы. Пример:
dump($smcFunc['db_table_sql']('{db_prefix}user_likes'));
Результат будет выглядеть как-то так:
DROP TABLE IF EXISTS `smf_user_likes`;
CREATE TABLE `smf_user_likes` (
`id_member` mediumint(8) unsigned NOT NULL default 0,
`content_type` char(6) NOT NULL default '',
`content_id` int(10) unsigned NOT NULL default 0,
`like_time` int(10) unsigned NOT NULL default 0,
PRIMARY KEY (`content_id`, `content_type`, `id_member`),
KEY `content` (`content_id`, `content_type`),
KEY `liker` (`id_member`)
) ENGINE=InnoDB'
Выводит список всех таблиц в базе данных. Вторым параметром можно указать фильтр (имя проверяемой таблицы или маску поиска).
Пример 1 — получаем массив с именами всех таблиц в текущей базе данных:
dump($smcFunc['db_list_tables']());
Пример 2 — получаем пустой массив, если таблицы my_table
в базе данных my_database
нет:
dump($smcFunc['db_list_tables']('my_database', '{db_prefix}my_table'));
Выводит версию используемого движка базы данных. Пример:
dump($smcFunc['db_get_version']());
Результат будет выглядеть как-то так:
'10.6.7-MariaDB'
Возвращает название используемого движка базы данных. Пример:
dump($smcFunc['db_get_vendor']());
Результат будет выглядеть как-то так:
'MariaDB'
Возвращает true
, если разрешено постоянное соединение с базой данных.