Текуща ситуация: PHP2Shell. Две критични уязвимости в PHP (CVSS 9,2) позволяват злонамерен код без вход. Корекции от 21.10.2026 г.Какво да направите сега →

OPcache, обяснен: кешът за байткод на PHP

OPcache държи преведения PHP код в споделената памет. Това спестява изчислително време, но изисква внимание при внедряване, рестартиране и на сървъри с няколко клиента.

Актуалност 5 мин. четенеЗнания за PHP

Накратко: OPcache е вграденият кеш за байткод на PHP. Според ръководството той съхранява предварително компилиран байткод в споделената памет, така че PHP не трябва да зарежда и превежда скриптовете при всяка заявка. Част е от доставката от PHP 5.5.0. OPcache прави PHP по-бърз, но не замества актуализацията: след PHP корекция всички PHP процеси трябва да се рестартират, а не само да се изчисти кешът.

Какво точно прави OPcache?

При всяка заявка PHP трябва да прочете скрипта, да го разчлени и да го преведе в опкодове, т.е. в командите за виртуалната машина на Zend Engine. При CMS със стотици файлове това е много работа, която непрекъснато се повтаря.

OPcache съхранява резултата от това превеждане в споделената памет (shared memory). Всички работни процеси на една услуга PHP-FPM или всички процеси на Apache с mod_php я ползват. Ако даден файл не се промени, неговият байткод се използва директно повторно.

OPcache се зарежда като Zend разширение, а не като обикновено разширение:

; Linux (пътят зависи от пакета)
zend_extension=opcache.so
; Windows
; zend_extension=php_opcache.dll

Според ръководството OPcache трябва да се зарежда преди Xdebug, когато и двете са активни.

Важно е на кого принадлежи споделената памет. При PHP-FPM главният процес я създава и всички работни процеси на всички пулове на тази услуга я ползват. При mod_php тя принадлежи на главния процес на Apache. Рестартирането на услугата затова изчиства кеша напълно, а един отделен нов работен процес не го прави. За командния ред няма споделена памет между отделните извиквания, защото всяко извикване е самостоятелен процес; там OPcache е изключен по подразбиране.

За вземащите решения е достатъчно едно правило на палеца: OPcache почти винаги е смислен на продукционни сървъри, но изисква ясна процедура за внедряване и актуализации.

Кои настройки на OPcache са важни?

Следващите стойности са от страницата за конфигурация в ръководството на PHP. Колоната „Променяемо“ показва къде може да се задава една настройка: INI_SYSTEM само в php.ini или в конфигурацията на сървъра, INI_ALL навсякъде.

Директива По подразбиране Променяемо Значение
opcache.enable 1 INI_ALL кеш включен или изключен, по време на изпълнение може само да се изключи
opcache.enable_cli 0 INI_SYSTEM кеш за командния ред
opcache.memory_consumption 128 INI_SYSTEM размер на споделената памет в MB
opcache.interned_strings_buffer 8 INI_SYSTEM памет за споделени низове в MB
opcache.max_accelerated_files 10000 INI_SYSTEM максимален брой кеширани скриптове
opcache.validate_timestamps 1 INI_ALL проверява дали файловете са променяни
opcache.revalidate_freq 2 INI_ALL интервал на проверка в секунди, 0 = при всяка заявка
opcache.restrict_api празно INI_SYSTEM позволява функциите на API само от определен път
opcache.validate_permission 0 INI_SYSTEM проверява правата на файловете спрямо текущия потребител
opcache.validate_root 0 INI_SYSTEM предотвратява колизии на имена при chroot
opcache.file_cache празно INI_SYSTEM второ ниво на кеша на диска

Типична продукционна конфигурация може да изглежда така. Проверете стойностите предварително с Вашето приложение:

opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=1
opcache.revalidate_freq=60
opcache.restrict_api=/var/www/admin-tools

Който зададе opcache.validate_timestamps=0, печели малко производителност. Тогава обаче OPcache изобщо не разпознава променени файлове и всяко внедряване изисква нулиране на кеша или рестартиране.

Наблюдение на кеша и целенасочено изчистване

OPcache носи собствени функции, сред които opcache_get_status(), opcache_get_configuration(), opcache_invalidate() и opcache_reset(). Кратък, само четящ поглед към запълването:

<?php
$status = opcache_get_status(false);
if ($status === false) {
    exit("OPcache ist nicht aktiv.\n");
}
printf("Gecachte Skripte: %d\n", $status['opcache_statistics']['num_cached_scripts']);
printf("Freier Speicher: %.1f MB\n", $status['memory_usage']['free_memory'] / 1048576);

На сървъри с няколко уебсайта не бива всяко приложение да може да изчиства или чете кеша на всички останали. За това служи opcache.restrict_api: само скриптове под зададения път могат да извикват функциите на API.

JIT: компилаторът към машинен код в OPcache

От PHP 8.0 OPcache съдържа JIT компилатор, който превежда опкодове в машинен код. Според JIT-RFC той е почти самостоятелна част от OPcache и поставя създадения код в собствена област на споделената памет. Управлява се чрез opcache.jit и opcache.jit_buffer_size. От PHP 8.4.0 opcache.jit по подразбиране е disable. Кога JIT си струва, обяснява статията JIT и производителност в PHP 8.

OPcache и сигурност: какво важи след PHP2Shell

OPcache не е инструмент за сигурност, но има последици за сигурността. След PHP2Shell три момента са важни:

  1. Нулирането на кеша не е актуализация. opcache_reset() изчиства само кеширани скриптове. Интерпретаторът с уязвимостите CVE-2026-109618 и CVE-2026-109619 остава в паметта, докато всички процеси не бъдат рестартирани. Как става това, е описано в Рестартиране на PHP-FPM и на всички работни процеси.
  2. Вмъкнат код може да продължи да живее в кеша. Ако даден файл е бил манипулиран и по-късно заменен, при изключена проверка на времевите отпечатъци старата версия може да продължи да се изпълнява. След почистване затова е необходимо рестартиране.
  3. Споделената памет изисква разделяне. На сървъри с няколко клиента помагат отделни PHP-FPM пулове за всеки уебсайт, както и opcache.validate_permission и opcache.restrict_api. Директорията за opcache.file_cache трябва да е достъпна за запис само за потребителя на PHP.
Съвет

След всяка актуализация проверявайте дали времето на стартиране на PHP процесите е след актуализацията. Пълен OPcache с висок процент попадения не е доказателство, че работи новият интерпретатор.

Как помага PHP SOS конкретно?

  • Проверка на конфигурацията: Четем активната конфигурация на OPcache за всеки режим на работа и я съгласуваме с Вашето приложение.
  • Защита на внедряванията: Въвеждаме твърда процедура за нулиране на кеша и рестартиране, за да не продължи да работи стара версия на кода.
  • Разделяне на клиентите: В рамките на заздравяването на сървъра задаваме отделни пулове, restrict_api и подходящи права.
  • Контрол след актуализации: Доказваме чрез времената на стартиране на процесите, че актуализираният интерпретатор действително е активен.

Често задавани въпроси

OPcache активен ли е по подразбиране?

OPcache се доставя с PHP от версия 5.5.0 и според ръководството работи с opcache.enable=1 по подразбиране, щом разширението е заредено. Дали е заредено, зависи от Вашия пакет или хостинг доставчик. В командния ред OPcache е изключен по подразбиране (opcache.enable_cli=0).

Защо след внедряване все още виждам стария код?

Вероятно OPcache проверява за промени във файловете само през определени интервали или изобщо не проверява. С opcache.revalidate_freq по подразбиране чака две секунди, с opcache.validate_timestamps=0 никога. Тогава помага само нулиране на кеша или рестартиране на PHP-FPM, респективно Apache.

Достатъчно ли е opcache_reset() след актуализация на PHP?

Не. opcache_reset() изчиства само кеша с преведени скриптове. Актуализацията на PHP заменя самия интерпретатор, а той е зареден във всеки работещ процес. За това всички PHP процеси трябва да бъдат рестартирани.

JIT включен ли е в PHP 8.4?

Според ръководството opcache.jit е зададен по подразбиране на disable от PHP 8.4.0, докато opcache.jit_buffer_size е 64M. Преди беше обратното: jit на tracing, буфер 0. И в двата случая JIT не е активен без съзнателна конфигурация.

Източници

Незабавен контакт

Всеки час има значение. Пишете ни сега.

Опишете накратко системата, версията на PHP и какво сте забелязали. Ние се свързваме с Вас, уточняваме ситуацията и работим отдалечено, докато инцидентът бъде приключен и документиран.

Незабавна помощ