Файлы конфигурации PHP: от простого к сложному
Основные подходы к хранению конфигурации в PHP
Наиболее эффективный и современный способ управления конфигурацией в PHP - использование файлов .env в сочетании с библиотекой vlucas/phpdotenv. Этот подход позволяет отделить настройки от кода, хранить чувствительные данные (пароли, ключи) вне репозитория и легко менять конфигурацию для разных окружений.
Как загрузить настройки из .env файла в PHP приложении?
Установите библиотеку через Composer:
composer require vlucas/phpdotenvSrc config php (файл конфигурации в php)
Создайте в корне проекта файл .env:
APP_ENV=development
DB_HOST=localhost
DB_USER=root
DB_PASS=secret
Загрузите переменные в PHP:
<?php
require_once __DIR__ . '/vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
echo $_ENV['DB_HOST']; // выведет localhost
?>
Типичные ошибки: Файл .env не должен быть доступен из веб-сервера. Для production используйте только переменные окружения сервера, а не .env. Библиотека требует PHP 7.1+. Если файл .env отсутствует, будет выброшено исключение. Для продакшена можно загружать переменные через putenv или использовать отдельный механизм.
Как хранить конфигурацию в простом PHP-массиве?
Это классический подход: создается файл config.php, который возвращает массив с настройками.
<?php
// config.php
return [
'db' => [
'host' => 'localhost',
'name' => 'myapp',
'user' => 'root',
'pass' => ''
],
'debug' => true
];
?>
Использование:
<?php
$config = require 'config.php';
echo $config['db']['host'];
?>
Проблемы: Файл содержит чувствительные данные, которые могут быть случайно опубликованы в репозитории. Нет разделения по окружениям. Кеширование opcode может привести к устаревшим значениям.
Как задать глобальные константы через define()?
Можно определить константы для каждой настройки:
<?php
define('DB_HOST', 'localhost');
define('DB_NAME', 'myapp');
define('DEBUG', true);
?>
Использование:
<?php
echo DB_HOST;
?>
Ошибки: Константы нельзя переопределить, они глобальны и могут конфликтовать с другими библиотеками. Сложно организовать вложенные структуры. Для сложных проектов подход не рекомендуется.
Как использовать INI-файлы с parse_ini_file()?
Файл config.ini:
[database]
host = localhost
name = myapp
user = root
pass =
[app]
debug = 1
Загрузка:
<?php
$config = parse_ini_file('config.ini', true);
echo $config['database']['host'];
?>
Недостатки: INI-формат ограничен: нет массивов (кроме секций), все значения - строки. Не поддерживаются булевы значения напрямую (1/0 или true/false). Нет возможности использовать переменные окружения.
Как загрузить конфигурацию из JSON-файла?
Файл config.json:
{
"database": {
"host": "localhost",
"name": "myapp"
},
"debug": true
}
Загрузка:
<?php
$config = json_decode(file_get_contents('config.json'), true);
echo $config['database']['host'];
?>
Проблемы: JSON строгий - нельзя добавлять комментарии. Нет возможности вычислять значения. Файл должен быть корректным. Для больших конфигураций может быть неудобно редактировать.
Как использовать YAML для сложной конфигурации?
Требуется библиотека Symfony YAML или аналогичная. Файл config.yaml:
database:
host: localhost
name: myapp
debug: true
Загрузка:
<?php
require_once 'vendor/autoload.php';
use Symfony\Component\Yaml\Yaml;
$config = Yaml::parseFile('config.yaml');
echo $config['database']['host'];
?>
Ошибки: Добавляется внешняя зависимость. Отступы важны - легко допустить ошибку. Не подходит для минималистичных проектов.
Как хранить конфигурацию в сериализованном PHP-виде?
Можно использовать serialize() и unserialize():
<?php
$config = ['host' => 'localhost', 'port' => 3306];
file_put_contents('config.ser', serialize($config));
// Загрузка:
$config = unserialize(file_get_contents('config.ser'));
?>
Недостатки: Формат нечитаем для человека. Есть риски безопасности при десериализации данных из непроверенных источников. Не подходит для совместного редактирования.
Расширенные примеры конфигурации
Пример: работа с несколькими окружениями (.env)
Создайте файлы .env.development и .env.production. В скрипте загружайте нужный в зависимости от переменной APP_ENV:
<?php
require_once __DIR__ . '/vendor/autoload.php';
$environment = getenv('APP_ENV') ?: 'development';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__, '.env.' . $environment);
$dotenv->load();
echo 'Текущее окружение: ' . $environment . PHP_EOL;
echo 'DB_HOST: ' . $_ENV['DB_HOST'];
?>
Предположим, в .env.development: DB_HOST=localhost, в .env.production: DB_HOST=prod-db.example.com. При запуске с APP_ENV=production получится соответствующий хост.
Текущее окружение: production DB_HOST: prod-db.example.com
Пример: использование переменных в .env с подстановкой
Библиотека phpdotenv поддерживает подстановку переменных:
# .env
DB_HOST=localhost
DB_PORT=3306
DB_DSN=mysql:host=${DB_HOST};port=${DB_PORT}
После загрузки $_ENV['DB_DSN'] = 'mysql:host=localhost;port=3306'
Пример: каскадная конфигурация на основе PHP-массива с условиями
Создайте базовый конфиг и переопределяйте для разных окружений:
<?php
// config.php
$config = [
'database' => [
'host' => 'localhost',
'port' => 3306,
'name' => 'myapp'
],
'debug' => false
];
$env = getenv('APP_ENV') ?: 'development';
$envFile = __DIR__ . '/config.' . $env . '.php';
if (file_exists($envFile)) {
$envConfig = require $envFile;
$config = array_merge_recursive($config, $envConfig);
}
return $config;
?>
Файл config.production.php:
<?php
return [
'database' => [
'host' => 'prod-db.example.com',
'password' => 's3cr3t'
]
];
?>
Итоговый массив объединит production-параметры с базовыми.
Пример: загрузка YAML с вложенными структурами
# services.yaml
parameters:
app.path.upload: '/uploads'
app.limits.max_filesize: 10485760
services:
App\Service\FileUploader:
arguments:
- '%app.path.upload%'
- '%app.limits.max_filesize%'
<?php
require_once 'vendor/autoload.php';
use Symfony\Component\Yaml\Yaml;
$config = Yaml::parseFile('services.yaml');
echo $config['services']['App\Service\FileUploader']['arguments'][0];
// Результат: /uploads
?>
Пример: конфигурация с использованием .env и Docker
В Docker Compose можно передать переменные окружения:
# docker-compose.yml
version: '3'
services:
app:
image: myapp
environment:
- APP_ENV=production
- DB_HOST=db
В PHP-коде используйте getenv('DB_HOST') без загрузки .env файла.