Подключение к базе данных
В Slim нет своей работы с базой данных. Самый простой вариант — PDO, встроенное в PHP расширение для запросов SQL. Подключение создают один раз в контейнере, и оно попадает в любой класс, который попросит его в конструкторе.
База и таблица
Создайте базу данных blog:
mysql -u root -p -e "CREATE DATABASE blog CHARACTER SET utf8mb4"Структуру таблиц удобно хранить в проекте. Создайте папку database и файл в ней:
-- database/schema.sql
CREATE TABLE posts (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
body TEXT NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO posts (title, body) VALUES
('Первая статья', 'Текст первой статьи.'),
('Вторая статья', 'Текст второй статьи.');Выполните файл:
mysql -u root -p blog < database/schema.sqlВ базе появится таблица posts с двумя строками.
Параметры подключения
Добавьте в .env три строки:
DB_DSN="mysql:host=localhost;dbname=blog;charset=utf8mb4"
DB_USER=root
DB_PASSWORD=DSN — строка, описывающая, к какой базе подключаться: тип, сервер, имя базы и кодировка. Затем добавьте раздел db в настройки:
// config/settings.php
return [
'debug' => filter_var($_ENV['APP_DEBUG'] ?? false, FILTER_VALIDATE_BOOL),
'site_name' => $_ENV['SITE_NAME'] ?? 'Блог',
'db' => [
'dsn' => $_ENV['DB_DSN'] ?? '',
'user' => $_ENV['DB_USER'] ?? '',
'password' => $_ENV['DB_PASSWORD'] ?? '',
],
];PDO в контейнере
// config/container.php
use Psr\Container\ContainerInterface;
PDO::class => function (ContainerInterface $c) {
$db = $c->get('settings')['db'];
return new PDO($db['dsn'], $db['user'], $db['password'], [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
},Запись добавляется в массив рядом с остальными. Первая настройка заставляет PDO бросать исключение при ошибке в запросе, вторая — возвращать строки таблицы как массивы с именами столбцов. Подключение создаётся при первом обращении к PDO::class; страницы, которым база не нужна, к ней не подключаются.
Проверка
Добавьте временный маршрут. Внутри функции-обработчика контейнер доступен как $this:
// config/routes.php
$app->get('/db-check', function (Request $request, Response $response) {
$count = $this->get(PDO::class)->query('SELECT COUNT(*) FROM posts')->fetchColumn();
$response->getBody()->write("Статей в базе: $count");
return $response;
});Откройте http://localhost:8080/db-check — на странице будет «Статей в базе: 2». После проверки маршрут удалите: запросы к базе будут жить в отдельном классе, о нём следующий урок.
Изменение структуры
Slim не управляет структурой базы. Пока проект небольшой, достаточно файла schema.sql. Когда таблицы начинают часто меняться, подключают инструмент миграций — например, Phinx: каждое изменение структуры описывается отдельным файлом и выполняется одной командой.
Частая ошибка
Пароль и адрес базы, вписанные прямо в config/container.php, попадают в систему контроля версий и оказываются у всех, у кого есть доступ к коду. Параметры подключения держите только в .env, а сам файл .env — вне репозитория.