WSDB


WSDB предоставляет статический доступ к основному подключению базы данных CMS.

Поддерживает

  • статический доступ к основному подключению
  • регистрацию дополнительных подключений
  • выборку, добавление, обновление и удаление данных
  • условия, сортировку и ограничение выборки
  • работу с JSON-полями
  • транзакции с автоматическим откатом
  • блокировку параллельного выполнения операций
  • проверку существования таблиц, столбцов и индексов
  • автоматическое использование префикса таблиц

Класс автоматически доступен после запуска CMS. Создавать его экземпляр не нужно.

Быстрый старт

Получение одной строки:

php
$page = WSDB::fetchOne(
    'page',
    ['id' => 15],
    ['id', 'title', 'url']
);

Получение списка:

php
$pages = WSDB::fetchAll(
    table: 'page',
    where: ['status' => 'publish'],
    columns: ['id', 'title', 'url'],
    order: ['id' => 'DESC'],
    limit: 10
);

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

php
$id = WSDB::insert(
    'page',
    [
        'title' => 'Новая страница',
        'status' => 'draft',
    ]
);

Подключения

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

on(string $name = 'default'): Database

Возвращает объект Database для выполнения запросов:

php
$database = WSDB::on();
$page = $database->fetchOne('page', ['id' => 15]);

Для основного подключения методы Database можно вызывать напрямую через WSDB:

php
$page = WSDB::fetchOne('page', ['id' => 15]);

connection(string $name = 'default'): DatabaseConnection

Возвращает параметры зарегистрированного подключения:

php
$connection = WSDB::connection();

$pdo = $connection->pdo();
$prefix = $connection->prefix();

Обычно получать DatabaseConnection вручную не требуется.

isRegistered(string $name = 'default'): bool

Проверяет, зарегистрировано ли подключение с указанным именем:

php
if (WSDB::isRegistered('analytics')) {
    $database = WSDB::on('analytics');
}

register(DatabaseConnection $connection, string $name = 'default'): void

Регистрирует дополнительное подключение:

php
$connection = DatabaseConnection::connect('localhost', 'analytics', 'user', 'password', 'ANALYTICS_');

WSDB::register($connection, 'analytics');

После регистрации запросы выполняются через выбранное подключение:

php
$events = WSDB::on('analytics')->fetchAllFrom('events', ['id', 'name']);

Имя подключения приводится к нижнему регистру. Оно должно начинаться с латинской буквы или цифры и может содержать цифры, _ и -.

Получение данных

Метод Возвращает Описание
fetchOne() array|null Возвращает первую найденную строку.
fetchAll() array Возвращает строки по условиям.
fetchAllFrom() array Возвращает все строки таблицы.
count() int Возвращает количество строк.

fetchOne(string $table, array $where, array $columns = ['*'], ?array $order = null, array $jsonFields = []): ?array

php
$user = WSDB::fetchOne(
    'user',
    ['id' => 7],
    ['id', 'login', 'email']
);

Если строка не найдена, возвращается null.

fetchAll(string $table, array $where, array $columns = ['*'], ?array $order = null, ?int $limit = null, ?int $offset = null, array $jsonFields = []): array

php
$posts = WSDB::fetchAll(
    table: 'post_news',
    where: ['status' => 'publish'],
    columns: ['id', 'title'],
    order: ['publish_date' => 'DESC'],
    limit: 20
);

Условия обязательны. offset можно использовать только вместе с limit.

fetchAllFrom(string $table, array $columns = ['*'], ?array $order = null, array $jsonFields = []): array

Используйте этот метод для выборки без условий:

php
$languages = WSDB::fetchAllFrom(
    'languages',
    ['id', 'code', 'name'],
    ['id' => 'ASC']
);

count(string $table, array $where = []): int

php
$total = WSDB::count(
    'page',
    ['status' => 'publish']
);

Без условий подсчитываются все строки таблицы:

php
$total = WSDB::count('page');

Условия

Простое значение проверяет равенство:

php
$where = ['status' => 'publish'];

Поддерживаемые операторы:

Оператор Описание
in Значение входит в список.
like Сравнение через LIKE.
> Больше.
< Меньше.
>= Больше или равно.
<= Меньше или равно.
!= Не равно.
is-null Значение равно NULL.
is-not-null Значение не равно NULL.
json-search Поиск значения внутри JSON-массива.
php
$pages = WSDB::fetchAll(
    'page',
    [
        'status' => [
            'in' => ['publish', 'draft'],
        ],
    ]
);

Для объединения групп доступны $or и $and:

php
$users = WSDB::fetchAll(
    'user',
    [
        '$or' => [
            ['role' => 'admin'],
            ['role' => 'editor'],
        ],
    ]
);

Сортировка

Сортировка передаётся массивом поле => направление:

php
$order = [
    'publish_date' => 'DESC',
    'id' => 'ASC',
];

Поддерживаются только ASC и DESC.

Выбор столбцов

По умолчанию возвращаются все столбцы. Для ограничения результата передайте список:

php
$page = WSDB::fetchOne(
    'page',
    ['id' => 15],
    ['id', 'title', 'url']
);

Для псевдонима используйте исходное поле => новое имя:

php
$page = WSDB::fetchOne(
    'page',
    ['id' => 15],
    [
        'title' => 'name',
    ]
);

Изменение данных

Метод Возвращает Описание
insert() int Добавляет строку и возвращает её идентификатор.
update() int Обновляет строки и возвращает их количество.
upsert() int Добавляет или обновляет строку.
delete() int Удаляет строки и возвращает их количество.

insert(string $table, array $data): int

php
$id = WSDB::insert(
    'user',
    [
        'login' => 'new-user',
        'email' => 'user@example.com',
        'role' => 'user',
    ]
);

update(string $table, array $data, array $where): int

php
$updated = WSDB::update(
    'page',
    ['status' => 'publish'],
    ['id' => 15]
);

upsert(string $table, array $data, array $update = []): int

php
$id = WSDB::upsert(
    'options',
    [
        'type' => 'global',
        'name' => 'sitename',
        'value' => 'Мой сайт',
    ],
    [
        'value' => 'Мой сайт',
    ]
);

Метод обновляет строку при конфликте уникального ключа.

delete(string $table, array $where): int

php
$deleted = WSDB::delete(
    'page',
    ['id' => 15]
);

Удаление без условий запрещено.

JSON-поля

Для преобразования JSON-полей в массивы передайте их через jsonFields:

php
$page = WSDB::fetchOne(
    table: 'page',
    where: ['id' => 15],
    columns: ['id', 'meta'],
    jsonFields: ['meta']
);

Пустое значение преобразуется в пустой массив.

updateJson(string $table, string $jsonColumn, array $set, array $where): int

Обновляет отдельные значения JSON-поля:

php
$updated = WSDB::updateJson(
    'user',
    'meta',
    [
        'profile.name' => 'Иван',
        'profile.phone' => '+375000000000',
    ],
    ['id' => 7]
);

upsertJson(string $table, array $keyData, string $jsonColumn, array $jsonSet): int

Создаёт строку или обновляет отдельные значения JSON-поля:

php
$id = WSDB::upsertJson(
    'options',
    [
        'type' => 'themes',
        'name' => 'example',
    ],
    'value',
    [
        'color' => '#1251b7',
    ]
);

Массивы, переданные в обычные методы записи, автоматически сохраняются как JSON.

Транзакции

transaction(callable $callback): mixed

Выполняет несколько операций как единое целое:

php
$pageId = WSDB::transaction(function (Database $database) {
    $pageId = $database->insert('page', ['title' => 'Новая страница', 'status' => 'draft']);
    $database->insert('page_meta', ['page_id' => $pageId, 'name' => 'layout', 'value' => 'default']);

    return $pageId;
});

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

Вложенные транзакции не поддерживаются. Изменение структуры таблиц внутри транзакции использовать нельзя.

Блокировка операций

withAdvisoryLock(string $name, int $timeout, callable $callback): mixed

Не позволяет нескольким процессам одновременно выполнять одну операцию:

php
$result = WSDB::withAdvisoryLock('product-import', 10, function (Database $database) {
    return $database->fetchAllFrom('products');
});

$timeout задаёт время ожидания блокировки в секундах. Блокировка освобождается после завершения callback, в том числе при возникновении исключения.

Имя блокировки должно содержать от 1 до 64 латинских букв, цифр или символов _, ., :, -.

Информация о базе данных

Метод Возвращает Описание
getPrefix() string Возвращает префикс таблиц подключения.
getServerVersion() string Возвращает версию сервера базы данных.
listTables() array Возвращает список таблиц.
describeTable(string $table) array Возвращает описание столбцов таблицы.
showIndexes(string $table) array Возвращает индексы таблицы.
tableExists(string $table) bool Проверяет существование таблицы.
columnExists(string $table, string $column) bool Проверяет существование столбца.
indexExists(string $table, string $index) bool Проверяет существование индекса.

Имена таблиц передаются без системного префикса:

php
if (WSDB::tableExists('page')) {
    $columns = WSDB::describeTable('page');
}

Префикс таблиц

Передавайте имя таблицы без системного префикса:

php
$page = WSDB::fetchOne('page', ['id' => 15]);

Префикс текущего подключения добавляется автоматически.

Исключения

Исключение Когда возникает
InvalidArgumentException Передано недопустимое имя, пустые данные или неверный аргумент запроса.
LogicException Подключение отсутствует, уже зарегистрировано или выполняется вложенная транзакция либо блокировка.
RuntimeException Не удалось подключиться, завершить транзакцию или получить блокировку.
BadMethodCallException Через WSDB вызван неизвестный метод Database.
PDOException Сервер базы данных отклонил запрос.
JsonException Переданное значение невозможно преобразовать в JSON.

Важные замечания

  • не создавайте экземпляр WSDB
  • основное подключение регистрируется CMS автоматически
  • статические методы используют основное подключение
  • для дополнительного подключения используйте WSDB::on($name)
  • fetchOne(), fetchAll(), update() и delete() требуют непустые условия
  • для получения всех строк используйте fetchAllFrom()
  • count() без условий подсчитывает все строки таблицы
  • значения запросов передаются через подготовленные выражения
  • имена таблиц и столбцов должны задаваться разработчиком