Röviden: Az OPcache a PHP beépített bájtkód-gyorsítótára. A kézikönyv szerint előre lefordított bájtkódot tárol a közös memóriában, így a PHP-nek nem kell minden kérésnél újra betöltenie és lefordítania a szkripteket. A PHP 5.5.0 óta része a szállított csomagnak. Az OPcache gyorsítja a PHP-t, de nem helyettesíti a frissítést: PHP-javítás után az összes PHP-folyamatot újra kell indítani, nem elég a gyorsítótárat üríteni.
Mit csinál pontosan az OPcache?
Minden kérésnél a PHP-nek be kell olvasnia egy szkriptet, szétbontania, és opcode-okká alakítania, vagyis a Zend Engine virtuális gépének utasításaivá. Egy több száz fájlból álló CMS esetén ez sok munka, amely folyamatosan ismétlődik.
Az OPcache ennek a fordításnak az eredményét a közös memóriában (shared memory) tárolja. Egy PHP-FPM-szolgáltatás összes workere vagy a mod_php-t használó összes Apache-folyamat hozzáfér. Ha egy fájl nem változik, a bájtkódját közvetlenül újra felhasználják.
Az OPcache-t Zend-bővítményként töltik be, nem szokásos bővítményként:
; Linux (a csomagtól függő útvonal)
zend_extension=opcache.so
; Windows
; zend_extension=php_opcache.dll
A kézikönyv szerint az OPcache-t az Xdebug előtt kell betölteni, ha mindkettő aktív.
Fontos, hogy kié a közös memória. PHP-FPM esetén a mester (master) folyamat hozza létre, és a szolgáltatás összes poolának összes workere használja. mod_php esetén az Apache főfolyamatához tartozik. A szolgáltatás újraindítása ezért teljesen kiüríti a gyorsítótárat, egyetlen új worker viszont nem. A parancssorban nincs hívások közötti közös memória, mert minden hívás önálló folyamat; ott az OPcache alapértelmezetten ki van kapcsolva.
Döntéshozóknak egy ökölszabály elég: az OPcache éles szervereken szinte mindig értelmes, de egyértelmű folyamatot kíván a telepítésekhez és a frissítésekhez.
Mely OPcache-beállítások számítanak?
A következő értékek a PHP-kézikönyv konfigurációs oldaláról származnak. A „Módosítható” oszlop azt mutatja, hol állítható be egy beállítás: az INI_SYSTEM csak a php.ini-ben vagy a szerverkonfigurációban, az INI_ALL bárhol.
| Direktíva | Alapérték | Módosítható | Jelentés |
|---|---|---|---|
opcache.enable |
1 | INI_ALL | gyorsítótár be- vagy kikapcsolása, futásidőben csak kikapcsolható |
opcache.enable_cli |
0 | INI_SYSTEM | gyorsítótár a parancssorhoz |
opcache.memory_consumption |
128 | INI_SYSTEM | a közös memória mérete MB-ban |
opcache.interned_strings_buffer |
8 | INI_SYSTEM | a közös karakterláncok memóriája MB-ban |
opcache.max_accelerated_files |
10000 | INI_SYSTEM | a gyorsítótárazott szkriptek legnagyobb száma |
opcache.validate_timestamps |
1 | INI_ALL | ellenőrzi, módosultak-e a fájlok |
opcache.revalidate_freq |
2 | INI_ALL | ellenőrzési időköz másodpercben, 0 = minden kérésnél |
opcache.restrict_api |
üres | INI_SYSTEM | az API-függvényeket csak egy útvonalról engedi |
opcache.validate_permission |
0 | INI_SYSTEM | a fájljogokat az aktuális felhasználóval veti össze |
opcache.validate_root |
0 | INI_SYSTEM | megakadályozza a névütközéseket chroot esetén |
opcache.file_cache |
üres | INI_SYSTEM | második gyorsítótár-szint a lemezen |
Egy tipikus éles konfiguráció így nézhet ki. Az értékeket előbb ellenőrizze az alkalmazásával:
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
Aki az opcache.validate_timestamps=0 értéket állítja be, nyer némi teljesítményt. Ilyenkor viszont az OPcache a módosult fájlokat egyáltalán nem ismeri fel, és minden telepítéshez a gyorsítótár visszaállítása vagy újraindítás kell.
A gyorsítótár megfigyelése és célzott ürítése
Az OPcache saját függvényeket hoz magával, köztük az opcache_get_status(), opcache_get_configuration(), opcache_invalidate() és opcache_reset() függvényeket. Egy rövid, csak olvasó pillantás a telítettségre:
<?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);
Több weboldalt kiszolgáló szervereken nem szabad, hogy minden alkalmazás kiürítse vagy kiolvashassa az összes többi gyorsítótárát. Erre való az opcache.restrict_api: csak a megadott útvonal alatti szkriptek hívhatják az API-függvényeket.
JIT: a gépikód-fordító az OPcache-ben
A PHP 8.0 óta az OPcache tartalmaz egy JIT-fordítót, amely az opcode-okat gépi kóddá alakítja. A JIT-RFC szerint az OPcache szinte önálló része, és az előállított kódot a közös memória egy saját területén tárolja. Az opcache.jit és az opcache.jit_buffer_size vezérli. A PHP 8.4.0 óta az opcache.jit alapértelmezetten disable értékű. Hogy mikor éri meg a JIT, azt a JIT és teljesítmény a PHP 8-ban cikk magyarázza el.
OPcache és biztonság: mi érvényes a PHP2Shell után
Az OPcache nem biztonsági eszköz, de következményei vannak a biztonságra. A PHP2Shell után három pont fontos:
- A gyorsítótár visszaállítása nem frissítés. Az
opcache_reset()csak a gyorsítótárazott szkripteket üríti. A CVE-2026-109618 és a CVE-2026-109619 réseket tartalmazó értelmező a memóriában marad, amíg az összes folyamatot újra nem indítják. Hogyan megy ez, azt a PHP-FPM és az összes worker újraindítása oldal írja le. - A beinjektált kód a gyorsítótárban tovább élhet. Ha egy fájlt manipuláltak, majd később lecseréltek, kikapcsolt időbélyeg-ellenőrzés esetén a régi változat tovább futhat. Takarítás után ezért az újraindítás is hozzátartozik.
- A közös memória szétválasztást kíván. Több ügyfelet kiszolgáló szervereken weboldalanként külön PHP-FPM-poolok, valamint az
opcache.validate_permissionés azopcache.restrict_apisegítenek. Azopcache.file_cachekönyvtárába csak a PHP-felhasználó írhat.
Minden frissítés után ellenőrizze, hogy a PHP-folyamatok indítási ideje a frissítés után van-e. A tele OPcache magas találati aránnyal nem bizonyíték arra, hogy az új értelmező fut.
Hogyan segít konkrétan a PHP SOS?
- Konfiguráció ellenőrzése: Üzemmódonként kiolvassuk az aktív OPcache-konfigurációt, és összevetjük az Ön alkalmazásával.
- Telepítések biztosítása: Rögzített folyamatot alakítunk ki a gyorsítótár-visszaállításhoz és az újraindításhoz, hogy ne fusson tovább régi kódváltozat.
- Ügyfelek elkülönítése: A szerver-megerősítés keretében külön poolokat,
restrict_apibeállítást és megfelelő jogokat állítunk be. - Ellenőrzés frissítések után: A folyamatok indítási idejével igazoljuk, hogy a frissített értelmező valóban aktív.
Gyakori kérdések
Alapértelmezetten aktív az OPcache?
Az OPcache a PHP 5.5.0 óta a PHP-val együtt érkezik, és a kézikönyv szerint opcache.enable=1 alapértékkel működik, amint a bővítmény be van töltve. Hogy be van-e töltve, az a csomagtól vagy a tárhelyszolgáltatótól függ. A parancssorban az OPcache ezzel szemben alapértelmezetten ki van kapcsolva (opcache.enable_cli=0).
Miért látom telepítés után még a régi kódot?
Valószínűleg az OPcache csak időnként vagy egyáltalán nem ellenőrzi a fájlváltozásokat. Az opcache.revalidate_freq alapértelmezetten két másodpercet vár, az opcache.validate_timestamps=0 beállítással soha. Ilyenkor csak a gyorsítótár visszaállítása (reset) vagy a PHP-FPM, illetve az Apache újraindítása segít.
Elég az opcache_reset() egy PHP-frissítés után?
Nem. Az opcache_reset() csak a lefordított szkripteket tartalmazó gyorsítótárat üríti. A PHP-frissítés magát az értelmezőt cseréli le, az pedig minden futó folyamatba be van töltve. Ehhez az összes PHP-folyamatot újra kell indítani.
Be van kapcsolva a JIT a PHP 8.4-ben?
A kézikönyv szerint az opcache.jit a PHP 8.4.0 óta alapértelmezetten disable értékű, az opcache.jit_buffer_size pedig 64M. Korábban fordítva volt: a jit értéke tracing, a puffer 0. Mindkét esetben a JIT tudatos beállítás nélkül nem aktív.