# php_admin_value: заключване на настройки срещу презаписване

> php_admin_value и php_admin_flag: как да заключите стойности на PHP в пула на FPM и в Apache срещу ini_set(), .htaccess и .user.ini и да го проверите.

Източник: https://phpsos.de/bg/blog/php-admin-value-sperren/  
Актуалност: 25.10.2026  
Доставчик: PHP SOS, Спешна помощ за PHP и сигурност на сървъри. Незабавна помощ по WhatsApp: https://wa.me/491736494914?text=%D0%97%D0%B4%D1%80%D0%B0%D0%B2%D0%B5%D0%B9%D1%82%D0%B5%2C%20PHP%20SOS%2C%20%D0%B8%D0%BC%D0%B0%D0%BC%D0%B5%20%D0%BD%D1%83%D0%B6%D0%B4%D0%B0%20%D0%BE%D1%82%20%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%20%D1%81%20%D0%BD%D0%B0%D1%88%D0%B8%D1%8F%20PHP%20%D1%81%D1%8A%D1%80%D0%B2%D1%8A%D1%80.%20%D0%A4%D0%B8%D1%80%D0%BC%D0%B0%3A%20%E2%80%A6%20%D0%A3%D0%B5%D0%B1%D1%81%D0%B0%D0%B9%D1%82%3A%20%E2%80%A6

**Накратко:** `php_admin_value` и `php_admin_flag` задават настройки на PHP в пула на PHP-FPM или в конфигурацията на Apache така, че приложенията не могат да ги променят нито чрез `ini_set()`, нито чрез `.htaccess`. php.net изисква точно това за преходните мерки при PHP2Shell, например за `memory_limit=-1`. След задаването услугата трябва да се рестартира, а стойността да се провери в уеб контекст.

## Защо „зададено“ не значи „заключено“

През дните след 21 октомври 2026 г. много администратори записаха преходните мерки на php.net в своя php.ini. Един детайл от препоръката често се изгуби: `memory_limit=-1` трябва да е зададен така, че приложенията да не могат да го презапишат. php.net изрично посочва за това `php_admin_value` в пула на FPM или в конфигурацията на Apache.

Причината е проста. Много CMS, магазини и рамки задават свои собствени стойности, например по-висок лимит на паметта за импорти. Ако стойността стои само в php.ini, приложението я презаписва при следващото извикване. Защитната мярка тогава съществува на хартия, но не и в работещия процес.

Това не засяга само PHP2Shell. Всяко заздравяване, от изключени изходи на грешки до лимити за качване, е толкова силно, колкото е най-слабото му ниво.

## Кой изобщо може да променя настройките на PHP

PHP познава четири режима на промяна. Всяка настройка има един от тях и той определя на кои места може да бъде зададена. Значенията идват от ръководството на PHP.

| Режим | Къде може да се задава стойността | Примери |
|---|---|---|
| `INI_USER` | в скрипта чрез `ini_set()` и в `.user.ini` | малко стойности за времето на изпълнение |
| `INI_PERDIR` | php.ini, `.htaccess`, `httpd.conf`, `.user.ini` | `post_max_size`, `session.upload_progress.enabled` |
| `INI_SYSTEM` | само php.ini или `httpd.conf` | `file_uploads`, `disable_functions` |
| `INI_ALL` | навсякъде, и чрез `ini_set()` | `memory_limit`, `display_errors`, `open_basedir` |

Опасни са най-вече стойностите `INI_ALL`: те могат да се променят от всеки скрипт. Стойностите `INI_PERDIR` наистина не могат да се променят чрез `ini_set()`, но могат чрез `.htaccess` при mod_php или `.user.ini` при PHP-FPM. Който има права за писане в уеб корена, тоест и внедреният код, може да създава такива файлове.

## php_admin_value в пула на FPM и в Apache

При PHP-FPM стойностите стоят във файла на пула. Ръководството на PHP отбелязва: стойности, зададени с `php_admin_value` и `php_admin_flag`, не могат да се презаписват чрез `ini_set()`. За стойности включено-изключено ползвайте `php_admin_flag`, за всички останали `php_admin_value`.

```ini
; /etc/php/8.3/fpm/pool.d/seite1.conf (откъс)
[seite1]
user = seite1
group = seite1
listen = /run/php/seite1.sock

php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M
php_admin_flag[session.upload_progress.enabled] = off
php_admin_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php/seite1-fehler.log
php_admin_value[open_basedir] = /var/www/seite1/:/tmp/seite1/
```

Според php.net `memory_limit=-1` принадлежи в конфигурацията само заедно с лимит на паметта чрез контейнер или cgroup. Как това се постига със systemd, е описано в статията [Задаване на лимити на паметта със systemd и cgroups](https://phpsos.de/bg/blog/speichergrenzen-systemd-cgroups/).

При Apache с mod_php директивите принадлежат в конфигурацията на сървъра или във VirtualHost. Според ръководството на PHP те не са позволени в `.htaccess`, а веднъж зададени, нито `.htaccess`, нито `ini_set()` могат да ги променят.

```apache
<VirtualHost *:443>
    ServerName www.example.de
    DocumentRoot /var/www/seite1/public
    <IfModule php_module>
        php_admin_value memory_limit -1
        php_admin_value post_max_size 32M
        php_admin_value upload_max_filesize 24M
        php_admin_flag session.upload_progress.enabled off
        php_admin_flag display_errors off
    </IfModule>
</VirtualHost>
```

Две тънкости от ръководството: за да изтриете предишно зададена стойност, използвайте `none` като стойност. А константите на PHP като `E_ALL` нямат значение в конфигурацията на Apache; за `error_reporting` там трябва да посочите числовата стойност.

## Кои стойности да заключите

Не всяка настройка трябва да е заключена. Смислено е това за всичко, което засяга сигурността или служи като преходна мярка:

1. Преходните стойности на php.net за PHP2Shell: `memory_limit`, `post_max_size`, `upload_max_filesize`, `session.upload_progress.enabled` и за PHP 8.5 `fatal_error_backtraces`.
2. Изход на грешки и протоколиране: `display_errors`, `display_startup_errors`, `log_errors`, `error_log`.
3. Достъп до файлове и изолация: `open_basedir`, `upload_tmp_dir`, `session.save_path`.
4. Мрежови достъпи от PHP: `allow_url_include` и, ако приложението не го изисква, `allow_url_fopen`.
5. Блокирани функции чрез `disable_functions`, които в пула според ръководството допълват списъка от php.ini, а не го заместват. Подробности в ръководството [Правилно използване на disable_functions](https://phpsos.de/bg/ratgeber/disable-functions/).

При `session.upload_progress.enabled` заключването е особено важно, защото иначе стойността би могла да бъде включена отново чрез `.user.ini`. Повече по темата в [Изключване на session.upload_progress: правилно и трайно](https://phpsos.de/bg/blog/session-upload-progress-abschalten/).

## Проверка дали заключването действа

След всяка промяна рестартирайте услугата и проверете стойността в уеб контекст. Кратък проверочен файл, изтрит веднага след това, показва дали пулът държи стойността, дори когато приложението иска да я промени:

```php
<?php
// Проверочен файл: поставете го за кратко, извикайте го веднъж през домейна, изтрийте го веднага
header('Content-Type: text/plain');
$vorher = ini_get('memory_limit');
$versuch = @ini_set('memory_limit', '256M');
echo "memory_limit: $vorher\n";
echo 'Änderung per ini_set() ', ($versuch === false ? 'blockiert' : 'MÖGLICH'), "\n";
```

Очаква се `-1` и „blockiert“. Ако изходът е „MÖGLICH“, стойността не е зададена чрез `php_admin_value` или услугата още не е рестартирана. Повторете проверката за всеки пул и всяка версия на PHP.

> **Съвет:**
> Водете заключените стойности централно, например в шаблон на пул или във Вашето управление на конфигурацията. Хостинг панелите понякога презаписват ръчно променени файлове на пулове при следващото запазване; там стойностите принадлежат в предвидените от панела полета.

Как PHP подрежда принципно нивата на конфигурация, обяснява [php.ini обяснен: структура, нива и приоритет](https://phpsos.de/bg/php/php-ini-erklaert/). Пълните преходни мерки са в [Незабавни мерки, когато още не можете да пачнете](https://phpsos.de/bg/php2shell/sofortmassnahmen-ohne-patch/).

## Извод: едва заключената стойност е наистина зададена

Преходните мерки на php.net за PHP2Shell изведоха на преден план едно разграничение, което преди често се пренебрегваше: стойност в php.ini е за много настройки само предложение, а стойност в `php_admin_value` е изискване. За удобни стойности като часовата зона разликата е без значение. За настройки на сигурността и преходни мерки тя решава дали мярката изобщо действа в работата.

Усилието е обозримо: шепа редове за всеки пул или VirtualHost, едно рестартиране, една кратка проверка. Дръжте списъка със заключени стойности малък и обоснован, за да могат разработчиците да разберат защо тяхното приложение не бива да променя дадена стойност. И поддържайте списъка във Вашите шаблони, за да го наследяват автоматично новите сайтове.

## Как помага PHP SOS конкретно?

- **Прочитане на нивата:** установяваме за всеки сайт кои стойности от php.ini, пула, Apache, `.htaccess` или `.user.ini` действително важат.
- **Задаване на заключвания:** вписваме свързаните със сигурността стойности и преходните мерки за PHP2Shell като `php_admin_value` респективно `php_admin_flag` и рестартираме услугите.
- **Тест на приложението:** проверяваме дали приложението работи безгрешно със заключените стойности и анализираме лога за грешки.
- **Поддържане на шаблоните:** в рамките на [заздравяването на сървъра](https://phpsos.de/bg/leistungen/server-haertung/) пренасяме стойностите в шаблони на пулове и в документацията.


## Често задавани въпроси

**Каква е разликата между php_value и php_admin_value?**  
И двете задават настройка на PHP. Стойности от php_value приложението може по-късно да промени отново, например чрез ini_set() или .htaccess. Стойности от php_admin_value и php_admin_flag според ръководството на PHP са заключени за ini_set(), а при Apache и за .htaccess.

**Мога ли да запиша php_admin_value във файл .htaccess?**  
Не. Според ръководството на PHP php_admin_value не е позволено във файлове .htaccess. То принадлежи в конфигурацията на сървъра Apache или във VirtualHost, а при PHP-FPM във файла на пула.

**Какво се случва, когато приложение иска да промени заключена стойност?**  
Извикването на ini_set() се проваля и връща false, заключената стойност остава. Добре програмираните приложения се справят с това. След прехода все пак проверете лога за грешки и най-важните функции.

**Трябва ли да рестартирам след промяна в пула?**  
Да. PHP-FPM чете файловете на пуловете при стартиране или при презареждане на услугата. При Apache с mod_php същото важи за конфигурацията на сървъра. Без рестартиране старата стойност продължава да работи.

**Може ли disable_functions да се разшири в пула?**  
Да, със особеност: според ръководството на PHP disable_functions в пула на FPM не презаписва стойностите от php.ini, а ги допълва. Пулът може да блокира още функции, но не може да освободи такива.

## Източници

- [Ръководство на PHP: конфигурация на FPM](https://www.php.net/manual/en/install.fpm.configuration.php)
- [Ръководство на PHP: промяна на конфигурацията](https://www.php.net/manual/en/configuration.changes.php)
- [Ръководство на PHP: режими на промяна на настройките](https://www.php.net/manual/en/configuration.changes.modes.php)
- [php.net: Съобщения за сигурност](https://www.php.net/)
