Стандартные настройки PHP: как задать параметры по умолчанию для своего проекта
Основные подходы к заданию настроек по умолчанию в PHP приложении
При создании веб-приложения на PHP важно определить, какие конфигурационные параметры будут использоваться по умолчанию. Это касается директив php.ini, переменных окружения и настроек самого приложения. Ниже рассмотрено несколько подходов с примерами кода и типичными проблемами.
Централизованная установка через скрипт инициализации (рекомендованный способ)
Создайте файл config/init.php, который будет подключаться в начале каждого запроса (например, через автозагрузчик или в index.php). В нём можно установить все необходимые параметры с помощью ini_set(), подключить конфигурацию из .env и проверить требуемые расширения.
<?php
// config/init.php
// Установка временной зоны (должна быть первой)
date_default_timezone_set('Europe/Moscow');
// Отображение ошибок только в режиме разработки
if (getenv('APP_ENV') === 'dev') {
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
} else {
ini_set('display_errors', 0);
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
}
// Лимиты памяти и времени выполнения
ini_set('memory_limit', '256M');
ini_set('max_execution_time', 30);
ini_set('max_input_time', 60);
// Размер загружаемых файлов
ini_set('upload_max_filesize', '20M');
ini_set('post_max_size', '22M');
// Настройки сессий
ini_set('session.cookie_httponly', 1);
ini_set('session.use_only_cookies', 1);
ini_set('session.cookie_secure', 1); // если HTTPS
// Проверка необходимых расширений
$required = ['json', 'mbstring', 'pdo']; // пример
foreach ($required as $ext) {
if (!extension_loaded($ext)) {
throw new RuntimeException("Расширение '$ext' не загружено");
}
}
echo "Настройки по умолчанию применены";
?>
Php веб сервисы (php веб-сервисы)
Типичные ошибки: вызов ini_set() после начала вывода буфера может не сработать для некоторых директив (session.* нужно устанавливать до старта сессии). Также если APP_ENV не задана, getenv вернёт false – рекомендуется задавать через .env или веб-сервер.
Цель: единая точка управления всеми настройками приложения. Подходит как для разработки, так и для продакшена при смене APP_ENV.
Как изменить глобальные настройки PHP для всех приложений на сервере?
Используйте файл php.ini (главный конфигурационный файл PHP). Расположение можно узнать через phpinfo(). Пример содержимого для продакшена:
; /etc/php/8.3/apache2/php.ini
display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
memory_limit = 256M
upload_max_filesize = 20M
post_max_size = 22M
date.timezone = Europe/Moscow
session.cookie_httponly = 1
session.use_only_cookies = 1
Php веб страница (веб-страница на php)
Типичные ошибки: после изменения php.ini необходимо перезапустить веб-сервер или PHP-FPM. Изменения вступят только для новых процессов.
Цель: глобальное применение для всех виртуальных хостов. Подходит для shared-хостинга, где нет доступа к .htaccess.
Как задать настройки для конкретного каталога без доступа к основному php.ini?
Используйте файл .user.ini (для CGI/FPM) или .htaccess (для Apache mod_php).
Пример .user.ini в корне приложения:
; public/.user.ini
display_errors = 1
error_reporting = E_ALL
upload_max_filesize = 10M
веб приложения php (веб-приложения на php)
Пример .htaccess:
# public/.htaccess
php_value display_errors 1
php_value upload_max_filesize 10M
php_flag session.cookie_httponly On
Config app php (конфигурация php приложения)
Типичные ошибки: в .user.ini нельзя использовать php_flag (только значения). Для .htaccess требуется AllowOverride Options и AllowOverride All (или Indexes). Если файл не читается, проверьте права доступа (обычно 644).
Цель: локальная переопределённая конфигурация для одного приложения. Удобно при отсутствии доступа к серверу.
Как хранить секретные настройки (пароли, ключи) по умолчанию?
Используйте файл .env и библиотеку vlucas/phpdotenv. Пример:
# .env (не должен попасть в репозиторий)
APP_ENV=production
DB_HOST=localhost
DB_USER=root
DB_PASS=secret
App php route (маршрутизация в php приложении)
В коде:
<?php
require_once __DIR__ . '/vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
$host = $_ENV['DB_HOST'] ?? 'localhost';
$user = $_ENV['DB_USER'] ?? 'root';
$pass = $_ENV['DB_PASS'] ?? '';
?>
Default php app (настройки по умолчанию в php приложении)
Типичные ошибки: загрузка .env после того, как окружение уже установлено (например, через веб-сервер). Лучше вызывать load() как можно раньше. Не используйте getenv() без проверки, если .env не загружен.
Цель: разделение конфигурации и кода, безопасность секретов. Подходит для любых сред (dev, staging, production).
Как установить настройки по умолчанию в самом коде без внешних файлов?
Используйте константы или массивы в файле конфигурации приложения. Пример config/app.php:
<?php
return [
'timezone' => 'Europe/Moscow',
'debug' => false,
'db' => [
'host' => 'localhost',
'port' => 3306,
'charset' => 'utf8mb4',
],
];
?>
App php domain (работа с доменами в php)
Загрузка:
<?php
$config = require __DIR__ . '/config/app.php';
date_default_timezone_set($config['timezone']);
?>
App path php (работа с путями файлов в php)
Типичные ошибки: при изменении настроек нужно перезагружать весь кеш опкода (OPcache). Также неудобно для быстрой смены между окружениями.
Цель: полный контроль, отсутствие зависимости от серверных настроек. Подходит для приложений без доступа к .env.
Дополнительные рекомендации
При комбинировании разных методов помните о приоритете: ini_set() переопределяет .user.ini, который переопределяет php.ini. Переменные окружения ($_ENV) не влияют на директивы PHP напрямую, только через код.
Всегда проверяйте, что установка прошла успешно, используя ini_get():
$mem = ini_get('memory_limit');
echo "Текущий memory_limit: $mem";
Расширенные примеры настроек по умолчанию
1. Автоматическая генерация конфигурации на основе окружения
Скрипт, который проверяет наличие файла .env и устанавливает настройки со значениями по умолчанию, если переменная не задана.
<?php
// bootstrap.php
define('ROOT', __DIR__);
// Загрузка .env, если существует
if (file_exists(ROOT . '/.env')) {
$lines = file(ROOT . '/.env', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
if (str_starts_with(trim($line), '#')) continue;
list($key, $value) = explode('=', $line, 2);
$key = trim($key);
$value = trim($value);
// Не перезаписывать уже заданные переменные
if (!getenv($key)) {
putenv("$key=$value");
}
}
}
// Установка значений по умолчанию для критичных директив
$defaultDir = [
'date.timezone' => 'UTC',
'display_errors' => '0',
'memory_limit' => '128M',
'log_errors' => '1',
'error_log' => ROOT . '/var/log/php_errors.log',
];
foreach ($defaultDir as $directive => $value) {
$value = getenv('PHP_' . strtoupper(str_replace('.', '_', $directive))) ?: $value;
ini_set($directive, $value);
}
// Дополнительная проверка
if (ini_get('display_errors') === '1') {
error_reporting(E_ALL);
} else {
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
}
?>
Результат: если в системе установлены переменные PHP_DATE_TIMEZONE, PHP_MEMORY_LIMIT и т.д., они будут использованы. Иначе применяются захардкоженные значения.
2. Изменение настроек сессии для повышения безопасности
Подробный пример настройки сессий по умолчанию с проверкой поддержки HTTPS.
<?php
session_name('MYAPP');
$secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443;
ini_set('session.cookie_secure', $secure ? '1' : '0');
ini_set('session.cookie_httponly', '1');
ini_set('session.use_strict_mode', '1');
ini_set('session.gc_maxlifetime', 7200); // 2 часа
ini_set('session.cookie_lifetime', 0); // до закрытия браузера
ini_set('session.use_cookies', '1');
ini_set('session.use_only_cookies', '1');
ini_set('session.cookie_samesite', 'Lax');
session_start();
?>
Типичные ошибки: session.use_strict_mode появилась в PHP 5.5.2. На старых версиях может вызвать ошибку. Установка session.cookie_secure в 1 на HTTP запросе приведёт к тому, что сессионная кука не будет отправлена браузером.
Результат: сессия защищена от XSS (httponly), от манипуляции через JavaScript, от кражи через нешифрованный канал (если HTTPS).
3. Настройка отчёта об ошибках с логированием
Пример, когда в продакшене ошибки пишутся в файл, а на экран не выводятся. Дополнительно отправляется email критических ошибок.
<?php
// в config/errors.php
define('LOG_FILE', __DIR__ . '/../var/log/app.log');
if (getenv('APP_ENV') === 'prod') {
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', LOG_FILE);
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
// Пользовательский обработчик для email-уведомлений
set_error_handler(function($level, $message, $file, $line) {
if (error_reporting() & $level) {
$msg = "[$level] $message в $file:$line";
error_log($msg, 1, 'admin@example.com'); // mail()
error_log($msg, 3, LOG_FILE);
return true;
}
return false;
});
} else {
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
ini_set('log_errors', 1);
ini_set('error_log', LOG_FILE);
}
?>
Результат: ошибки логируются в файл, в продакшене ещё и отправляются email. Пользователь не видит технических деталей.
4. Использование .htaccess для тонкой настройки через веб-сервер
Многие директивы можно задавать через php_value и php_flag. Пример с ограничением на директорию загрузок:
# public/uploads/.htaccess
# Запретить выполнение PHP в этой папке
php_flag engine off
# Установить максимальный размер загрузки только для этой папки
php_value upload_max_filesize 5M
# Отключить отображение ошибок
php_flag display_errors off
Результат: в /uploads/ нельзя запустить PHP-скрипт, максимальный размер файла для загрузки ограничен 5 МБ.
5. Сравнение методов: производительность и гибкость
Скрипт, который выводит текущие значения нескольких директив, полученных разными способами.
<?php
echo "<table border='1'>";
echo "<tr><th>Директива</th><th>php.ini (ini_get)</th><th>_SERVER</th><th>getenv</th></tr>";
$dirs = ['memory_limit', 'max_execution_time', 'upload_max_filesize'];
foreach ($dirs as $d) {
$val_ini = ini_get($d);
$server_key = 'PHP_' . strtoupper(str_replace('.', '_', $d));
$val_server = $_SERVER[$server_key] ?? 'не установлена';
$val_env = getenv($server_key) ?: 'не установлена';
echo "<tr><td>$d</td><td>$val_ini</td><td>$val_server</td><td>$val_env</td></tr>";
}
echo "</table>";
?>
Результат: покажет, какие значения реально используются, и можно ли переопределить через переменные окружения.