Skip to content

Latest commit

 

History

History
95 lines (70 loc) · 10.9 KB

SchemaManagement.md

File metadata and controls

95 lines (70 loc) · 10.9 KB

Управление схемой

Мы рассмотрели некоторые новые подходы, доступные для взаимодействия с данными. Конечно, существуют конкретные обстоятельства, при которых взаимодействие с базой данных может быть непосредственно необходимым.

Адаптер базы данных

Адаптер базы данных по умолчанию в XF2 основан на расширении MySQL и PHP mysqli. Конфигурируемый адаптер базы данных доступен в любом классе XF, используя следующее:

$db = \XF::db();

Адаптер имеет несколько доступных методов, которые будут выполнять SQL-запрос, а затем форматировать результаты в массив. Например, для доступа к одной записи пользователя:

$db = \XF::db();
$user = $db->fetchRow('SELECT * FROM xf_user WHERE user_id = ?', 1);

Теперь переменная $ user будет содержать массив всех значений из первой строки, найденной в результате запроса. Чтобы получить одно значение из этого запроса, например, имя пользователя, вы можете сделать следующее:

$username = $user['username'];

Предупреждение Запросы базы данных, написанные напрямую и переданные в адаптер базы данных, не являются автоматически «безопасными». Таким образом увеличивается риск подвергнутся SQL-инъекции, если пользовательский ввод будет передан без предварительной проверки. Способ сделать это правильно - это использовать подготовленные операторы, как в приведенном выше примере. Параметры представлены в самом запросе с использованием ? заполнителя. Затем эти заполнители заменяются значениями в следующем аргументе после того, как они были соответствующим образом экранированы. Если вам нужно использовать более одного параметра, это должно быть передано в метод в виде массива. Если возникнет такая необходимость, вы можете избежать значений котировки напрямую, используя $db->quote($value).

Вы можете найти дополнительную информацию о подготовленных запросах тут.

Также можно запросить одно значение из записи. Например:

$db = \XF::db();
$username = $db->fetchOne('SELECT username FROM xf_user WHERE user_id = ?', 1);

Если у вас есть запрос, который должен возвращать несколько строк, вы можете использовать либо fetchAll:

$db = \XF::db();
$users = $db->fetchAll('SELECT * FROM xf_user LIMIT 10');

либо fetchAllKeyed:

$db = \XF::db();
$users = $db->fetchAllKeyed('SELECT * FROM xf_user LIMIT 10', 'user_id');

Оба этих метода возвращают многомерный массив, который представляет каждую пользовательскую запись. Разница между методами fetchAll и fetchAllKeyed заключается в том, что возвращаемый массив будет вводиться по-разному. С помощью fetchAll массив будет вводиться с числовыми последовательными целыми числами. С помощью fetchAllKeyed массив будет зависеть от имени поля, указанного во втором аргументе.

Примечание Если вы используете fetchAllKeyed обратите внимание, что вторым аргументом является поле для ввода массива, но ** третий ** аргумент - это то, где вы передаете значения параметра, соответствующие совпадениям ?.

Существуют и другие методы типа выборки, включая fetchAllColumn для захвата массива значений определенного столбца из всех возвращенных строк:

$db = \XF::db();
$usernames = $db->fetchAllColumn('SELECT username FROM xf_user LIMIT 10');

В приведенном выше примере будет возвращен массив из 10 имен пользователей, найденных из полученного запроса.

Наконец, вам более не нужные какие-либо данные. В этом случае вы можете просто выполнить простой запрос:

$db = \XF::db();
$db->query('DELETE FROM xf_user WHERE user_id = ?', 1);

Управление схемой

XF2 включает в себя все новые способы управления схемой базы данных, которая использует объектно-ориентированный подход для выполнения определенных операций с таблицами. Давайте сначала рассмотрим традиционный Alter, используя адаптер базы данных, как мы уже говорили выше:

$db = \XF::db();
$db->query("
    ALTER TABLE xf_some_existing_table
    ADD COLUMN new_column INT(10) UNSIGNED NOT NULL DEFAULT 0,
    MODIFY COLUMN some_existing_column varchar(250) NOT NULL DEFAULT ''

"); А также рассмотрим типичный запрос создания таблицы:

$db = \XF::db();
$sm = $db->getSchemaManager();

$defaultTableConfig = $sm->getTableConfigSql();

$db->query("
    CREATE TABLE xf_some_table (
        some_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
        some_name VARCHAR(50) NOT NULL,
        PRIMARY KEY (user_id)
    ) {$defaultTableConfig}
");

Альтернативный и предпочтительный подход в XF2 использует новый объект SchemaManager. Давайте посмотрим на оба этих запроса, как это делает диспетчер схем, начиная с Alter:

$sm = \XF::db()->getSchemaManager();
$sm->alterTable('xf_some_existing_table',     function(\XF\Db\Schema\Alter $table)
{
    $table->addColumn('new_column', 'int')->setDefault(0);
    $table->changeColumn('some_existing_column')->length(250);
});

И создание таблицы:

$sm = \XF::db()->getSchemaManager();
$sm->createTable('xf_some_table', function(\XF\Db\Schema\Create $table)
{
    $table->addColumn('some_id', 'int')->autoIncrement();
    $table->addColumn('some_name', 'varchar', 50);
});

Оба этих примера дают тот же самый результаты, что и их более прямые аналоги. Хотя вы можете заметить, что некоторые вещи (намеренно) отсутствуют. Например, ни один из примеров не указывает длину для полей int. Это просто потому, что, опуская это, MySQL предоставит ему значение по умолчанию, которое равно 10 для целых чисел без знака. Говоря об этом, мы также не указываем, что столбец some_id не имеет знака. Использование целых чисел без знака в XF является наиболее распространенным вариантом , поэтому он автоматически добавляется. Если вам действительно нужна поддержка отрицательных целых чисел, вы можете отменить это с помощью метода ->unsigned(false). Другое упущение - отсутствие определения «NOT NULL для всего». Опять же, это применяется автоматически, но вы можете отменить это с помощью ->nullable (true).

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

Существует и другой автоматический вывод, который происходит в отношении первичных ключей. Вы можете явно определить первичный ключ (или любой другой тип ключа), если хотите, но часто автоматически увеличиваются поля, которые обычно являются вашим основным ключом для таблицы. Поэтому в примере создания таблицы поле «some_id» автоматически назначается в качестве первичного ключа для этой таблицы.

Наконец, для подхода create table мы можем автоматически добавить правильную конфигурацию таблицы для указанного механизма хранения (который по умолчанию относится к InnoDB, но может быть легко изменен для других типов двигателей).