Файлы конфигурации PHP: от простого к сложному

Раздел: PHP -> Настройка и конфигурация

Основные подходы к хранению конфигурации в PHP

Наиболее эффективный и современный способ управления конфигурацией в PHP - использование файлов .env в сочетании с библиотекой vlucas/phpdotenv. Этот подход позволяет отделить настройки от кода, хранить чувствительные данные (пароли, ключи) вне репозитория и легко менять конфигурацию для разных окружений.

Как загрузить настройки из .env файла в PHP приложении?

Установите библиотеку через Composer:

composer require vlucas/phpdotenv

Src 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 файла.

Файл конфигурации в PHP - comments

En
Src config php (php)