Trumpai: OPcache yra įtaisyta PHP baitkodo talpykla. Pasak vadovo, ji saugo iš anksto sukompiliuotą baitkodą bendroje atmintyje, todėl PHP nereikia kiekvienos užklausos metu iš naujo įkelti ir versti skriptų. Ji kartu su PHP pateikiama nuo PHP 5.5.0. OPcache pagreitina PHP, bet neatstoja atnaujinimo: po PHP pataisos reikia iš naujo paleisti visus PHP procesus, o ne tik išvalyti talpyklą.
Ką tiksliai daro OPcache?
Per kiekvieną užklausą PHP turi nuskaityti skriptą, jį išskaidyti ir paversti operacijų kodais (opcodes), t. y. komandomis Zend Engine virtualiai mašinai. CMS su šimtais failų tai daug darbo, kuris nuolat kartojasi.
OPcache šio vertimo rezultatą saugo bendroje atmintyje (shared memory). Prie jos kreipiasi visi PHP-FPM tarnybos darbiniai procesai (worker) arba visi Apache procesai su mod_php. Jei failas nepasikeitė, jo baitkodas naudojamas tiesiogiai.
OPcache įkeliamas kaip Zend plėtinys, o ne kaip įprastas plėtinys:
; Linux (kelias priklauso nuo paketo)
zend_extension=opcache.so
; Windows
; zend_extension=php_opcache.dll
Pasak vadovo, jei aktyvūs abu, OPcache turi būti įkeltas prieš Xdebug.
Svarbu, kam priklauso bendroji atmintis. PHP-FPM atveju ją sukuria pagrindinis (master) procesas, ir ją naudoja visi šios tarnybos visų baseinų (pool) darbiniai procesai. mod_php atveju ji priklauso Apache pagrindiniam procesui. Todėl tarnybos paleidimas iš naujo talpyklą išvalo visiškai, o atskiras naujas darbinis procesas ne. Komandinei eilutei bendros atminties tarp iškvietimų nėra, nes kiekvienas iškvietimas yra atskiras procesas; ten OPcache pagal numatymą išjungtas.
Sprendimų priėmėjams pakanka nykščio taisyklės: gamybiniuose serveriuose OPcache beveik visada prasmingas, bet diegimams ir atnaujinimams reikia aiškios eigos.
Kurie OPcache nustatymai svarbūs?
Toliau pateiktos reikšmės paimtos iš PHP vadovo konfigūracijos puslapio. Stulpelis „Keičiama“ rodo, kur nustatymą leidžiama nustatyti: INI_SYSTEM tik php.ini ar serverio konfigūracijoje, INI_ALL bet kur.
| Direktyva | Numatytoji | Keičiama | Reikšmė |
|---|---|---|---|
opcache.enable |
1 | INI_ALL | talpykla įjungta ar išjungta, vykdymo metu galima tik išjungti |
opcache.enable_cli |
0 | INI_SYSTEM | talpykla komandinei eilutei |
opcache.memory_consumption |
128 | INI_SYSTEM | bendros atminties dydis MB |
opcache.interned_strings_buffer |
8 | INI_SYSTEM | atmintis bendroms eilutėms MB |
opcache.max_accelerated_files |
10000 | INI_SYSTEM | didžiausias talpinamų skriptų skaičius |
opcache.validate_timestamps |
1 | INI_ALL | tikrina, ar failai pasikeitė |
opcache.revalidate_freq |
2 | INI_ALL | tikrinimo intervalas sekundėmis, 0 = per kiekvieną užklausą |
opcache.restrict_api |
tuščia | INI_SYSTEM | leidžia API funkcijas tik iš tam tikro kelio |
opcache.validate_permission |
0 | INI_SYSTEM | tikrina failų teises pagal dabartinį naudotoją |
opcache.validate_root |
0 | INI_SYSTEM | apsaugo nuo pavadinimų kolizijų naudojant chroot |
opcache.file_cache |
tuščia | INI_SYSTEM | antras talpyklos lygis diske |
Tipinė gamybinė konfigūracija galėtų atrodyti taip. Reikšmes prieš tai patikrinkite su savo programa:
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
Kas nustato opcache.validate_timestamps=0, šiek tiek laimi našumo. Tačiau tada OPcache pakeistų failų išvis nebemato, ir kiekvienam diegimui reikia talpyklos atstatymo arba paleidimo iš naujo.
Talpyklos stebėjimas ir tikslingas valymas
OPcache turi savas funkcijas, tarp jų opcache_get_status(), opcache_get_configuration(), opcache_invalidate() ir opcache_reset(). Trumpas, tik skaitantis žvilgsnis į užpildymą:
<?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);
Serveriuose su keliomis svetainėmis ne kiekviena programa turėtų galėti išvalyti ar nuskaityti visų kitų talpyklą. Tam skirtas opcache.restrict_api: API funkcijas gali iškviesti tik skriptai, esantys žemiau nurodyto kelio.
JIT: mašininio kodo kompiliatorius OPcache viduje
Nuo PHP 8.0 OPcache turi JIT kompiliatorių, kuris operacijų kodus paverčia mašininiu kodu. Pasak JIT RFC, jis yra beveik savarankiška OPcache dalis ir sukurtą kodą laiko atskiroje bendros atminties srityje. Valdomas per opcache.jit ir opcache.jit_buffer_size. Nuo PHP 8.4.0 opcache.jit pagal numatymą yra disable. Kada JIT atsiperka, paaiškina straipsnis JIT ir našumas PHP 8.
OPcache ir saugumas: kas galioja po PHP2Shell
OPcache nėra saugumo įrankis, bet turi pasekmių saugumui. Po PHP2Shell svarbūs trys dalykai:
- Talpyklos atstatymas nėra atnaujinimas.
opcache_reset()išvalo tik talpinamus skriptus. Interpretatorius su spragomis CVE-2026-109618 ir CVE-2026-109619 lieka atmintyje, kol visi procesai paleisti iš naujo. Kaip tai padaryti, aprašyta skyriuje PHP-FPM ir visų darbinių procesų paleidimas iš naujo. - Įterptas kodas gali gyventi talpykloje. Jei failas buvo suklastotas ir vėliau pakeistas, išjungus laiko žymų patikrą gali toliau būti vykdoma senoji versija. Todėl po išvalymo reikia ir paleidimo iš naujo.
- Bendrai atminčiai reikia atskyrimo. Serveriuose su keliais klientais padeda atskiri PHP-FPM baseinai kiekvienai svetainei bei
opcache.validate_permissioniropcache.restrict_api. Katalogasopcache.file_cacheturi būti įrašomas tik PHP naudotojui.
Po kiekvieno atnaujinimo patikrinkite, ar PHP procesų paleidimo laikas yra po atnaujinimo. Pilna OPcache su dideliu pataikymų rodikliu nėra įrodymas, kad veikia naujasis interpretatorius.
Kaip PHP SOS padeda konkrečiai?
- Konfigūracijos patikra: nuskaitome aktyvią OPcache konfigūraciją pagal veikimo režimą ir suderiname ją su jūsų programa.
- Diegimų apsauga: įrengiame tvirtą talpyklos atstatymo ir paleidimo iš naujo eigą, kad neveiktų sena kodo versija.
- Nuomininkų atskyrimas: serverio sutvirtinimo rėmuose nustatome atskirus baseinus,
restrict_apiir tinkamas teises. - Patikra po atnaujinimų: pagal procesų paleidimo laikus įrodome, kad atnaujintas interpretatorius tikrai aktyvus.
Dažni klausimai
Ar OPcache pagal numatymą aktyvus?
OPcache kartu su PHP pateikiamas nuo PHP 5.5.0 ir, pasak vadovo, veikia su opcache.enable=1 kaip numatytąja reikšme, kai tik plėtinys įkeltas. Ar jis įkeltas, priklauso nuo jūsų paketo ar hostingo teikėjo. Komandinėje eilutėje OPcache, priešingai, pagal numatymą išjungtas (opcache.enable_cli=0).
Kodėl po diegimo vis dar matau senąjį kodą?
Tikėtina, kad OPcache failų pakeitimus tikrina tik tam tikrais intervalais arba išvis netikrina. Su opcache.revalidate_freq pagal numatymą laukia dvi sekundes, su opcache.validate_timestamps=0 niekada netikrina. Tuomet padeda tik talpyklos atstatymas arba PHP-FPM ar Apache paleidimas iš naujo.
Ar po PHP atnaujinimo pakanka opcache_reset()?
Ne. opcache_reset() išvalo tik talpyklą su išverstais skriptais. PHP atnaujinimas pakeičia patį interpretatorių, o jis įkeltas kiekviename veikiančiame procese. Todėl reikia iš naujo paleisti visus PHP procesus.
Ar PHP 8.4 JIT įjungtas?
Pasak vadovo, nuo PHP 8.4.0 opcache.jit pagal numatymą nustatytas į disable, o opcache.jit_buffer_size yra 64M. Anksčiau buvo atvirkščiai: jit į tracing, buferis 0. Abiem atvejais be sąmoningos konfigūracijos JIT neaktyvus.