Trenutno stanje: PHP2Shell. Dve kritični ranljivosti PHP (CVSS 9,2) omogočata izvedbo škodljive kode brez prijave. Popravki od 21. 10. 2026.Kaj je zdaj treba storiti →

OPcache razložen: predpomnilnik bajtne kode PHP

OPcache hrani prevedeno kodo PHP v skupnem pomnilniku. To prihrani računski čas, a zahteva skrbnost pri namestitvah, ponovnih zagonih in na strežnikih z več strankami.

Stanje 4 min branjaZnanje o PHP

Na kratko: OPcache je vgrajeni predpomnilnik bajtne kode PHP. Po priročniku v skupni pomnilnik shrani vnaprej prevedeno bajtno kodo, tako da PHP skript ob vsaki zahtevi ni treba znova nalagati in prevajati. V dobavljenem obsegu je od PHP 5.5.0. OPcache PHP pospeši, vendar ne nadomešča posodobitve: po popravku PHP je treba znova zagnati vse procese PHP, ne samo izprazniti predpomnilnika.

Kaj točno počne OPcache?

Ob vsaki zahtevi mora PHP skripto prebrati, razčleniti in prevesti v opcode, torej v ukaze za navidezni stroj Zend Engine. Pri CMS-ju s stotinami datotek je to veliko dela, ki se nenehno ponavlja.

OPcache rezultat tega prevajanja shrani v skupni pomnilnik (shared memory). Do njega dostopajo vsi workerji storitve PHP-FPM ali vsi procesi Apache z mod_php. Če se datoteka ne spremeni, se njena bajtna koda neposredno ponovno uporabi.

OPcache se naloži kot razširitev Zend, ne kot navadna razširitev:

; Linux (pot je odvisna od paketa)
zend_extension=opcache.so
; Windows
; zend_extension=php_opcache.dll

Po priročniku naj se OPcache naloži pred Xdebug, kadar sta aktivna oba.

Pomembno je, čigav je skupni pomnilnik. Pri PHP-FPM ga ustvari glavni proces, uporabljajo pa ga vsi workerji vseh poolov te storitve. Pri mod_php pripada glavnemu procesu Apache. Ponovni zagon storitve zato predpomnilnik v celoti izprazni, en sam nov worker pa ne. Za ukazno vrstico skupnega pomnilnika med klici ni, ker je vsak klic samostojen proces; tam je OPcache privzeto izklopljen.

Za odločevalce zadošča pravilo palca: OPcache je na produkcijskih strežnikih skoraj vedno smiseln, a zahteva jasen potek namestitev in posodobitev.

Katere nastavitve OPcache štejejo?

Naslednje vrednosti izvirajo iz strani s konfiguracijo v priročniku PHP. Stolpec „Spremenljivo“ kaže, kje se nastavitev sme določiti: INI_SYSTEM samo v php.ini ali konfiguraciji strežnika, INI_ALL povsod.

Direktiva Privzeto Spremenljivo Pomen
opcache.enable 1 INI_ALL predpomnilnik vklopljen ali izklopljen, med izvajanjem ga je mogoče samo izklopiti
opcache.enable_cli 0 INI_SYSTEM predpomnilnik za ukazno vrstico
opcache.memory_consumption 128 INI_SYSTEM velikost skupnega pomnilnika v MB
opcache.interned_strings_buffer 8 INI_SYSTEM pomnilnik za skupne nize znakov v MB
opcache.max_accelerated_files 10000 INI_SYSTEM največje število predpomnjenih skript
opcache.validate_timestamps 1 INI_ALL preverja, ali so se datoteke spremenile
opcache.revalidate_freq 2 INI_ALL razmik preverjanja v sekundah, 0 = ob vsaki zahtevi
opcache.restrict_api prazno INI_SYSTEM funkcije API dovoli samo iz ene poti
opcache.validate_permission 0 INI_SYSTEM preverja pravice datotek glede na trenutnega uporabnika
opcache.validate_root 0 INI_SYSTEM preprečuje trke imen pri chroot
opcache.file_cache prazno INI_SYSTEM druga raven predpomnilnika na disku

Značilna produkcijska konfiguracija bi lahko izgledala takole. Vrednosti pred tem preverite z vašo aplikacijo:

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

Kdor nastavi opcache.validate_timestamps=0, pridobi nekaj zmogljivosti. Takrat pa OPcache spremenjenih datotek sploh ne prepozna več in vsaka namestitev potrebuje ponastavitev predpomnilnika ali ponovni zagon.

Opazovanje in ciljno praznjenje predpomnilnika

OPcache prinaša lastne funkcije, med njimi opcache_get_status(), opcache_get_configuration(), opcache_invalidate() in opcache_reset(). Kratek bralni pogled na zasedenost:

<?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);

Na strežnikih z več spletnimi stranmi ne bi smela vsaka aplikacija moči izprazniti ali brati predpomnilnika vseh drugih. Za to je namenjen opcache.restrict_api: funkcije API smejo klicati samo skripte pod navedeno potjo.

JIT: prevajalnik strojne kode v OPcache

Od PHP 8.0 OPcache vsebuje prevajalnik JIT, ki opcode prevede v strojno kodo. Po RFC za JIT je skoraj samostojen del OPcache in ustvarjeno kodo shrani v lasten predel skupnega pomnilnika. Upravlja se ga z opcache.jit in opcache.jit_buffer_size. Od PHP 8.4.0 je opcache.jit privzeto na disable. Kdaj se JIT splača, razlaga prispevek JIT in zmogljivost v PHP 8.

OPcache in varnost: kaj velja po PHP2Shell

OPcache ni varnostno orodje, a ima posledice za varnost. Po PHP2Shell so pomembne tri točke:

  1. Ponastavitev predpomnilnika ni posodobitev. opcache_reset() izprazni samo predpomnjene skripte. Interpreter z ranljivostma CVE-2026-109618 in CVE-2026-109619 ostane v pomnilniku, dokler niso vsi procesi znova zagnani. Kako, piše na strani Ponovni zagon PHP-FPM in vseh workerjev.
  2. Vnesena koda lahko živi naprej v predpomnilniku. Če je bila datoteka spremenjena in pozneje zamenjana, se pri izklopljenem preverjanju časovnih žigov lahko stara različica še naprej izvaja. Po čiščenju zato sodi zraven ponovni zagon.
  3. Skupni pomnilnik zahteva ločevanje. Na strežnikih z več strankami pomagajo lastni pooli PHP-FPM za vsako spletno stran ter opcache.validate_permission in opcache.restrict_api. Imenik za opcache.file_cache sme biti zapisljiv samo za uporabnika PHP.
Nasvet

Po vsaki posodobitvi preverite, ali je čas zagona procesov PHP po posodobitvi. Poln OPcache z visokim deležem zadetkov ni dokaz, da teče novi interpreter.

Kako PHP SOS pomaga konkretno?

  • Preverjanje konfiguracije: preberemo aktivno konfiguracijo OPcache za vsak način delovanja in jo uskladimo z vašo aplikacijo.
  • Zavarovanje namestitev: vzpostavimo trden potek ponastavitve predpomnilnika in ponovnega zagona, da ne teče nobena stara različica kode.
  • Ločevanje strank: v okviru utrjevanja strežnika nastavimo ločene poole, restrict_api in ustrezne pravice.
  • Kontrola po posodobitvah: prek časov zagona procesov dokažemo, da posodobljeni interpreter resnično teče.

Pogosta vprašanja

Ali je OPcache privzeto aktiven?

OPcache se dobavlja s PHP od različice 5.5.0 in po priročniku teče z opcache.enable=1 kot privzeto vrednostjo, ko je razširitev naložena. Ali je naložena, je odvisno od vašega paketa ali ponudnika gostovanja. V ukazni vrstici je OPcache privzeto izklopljen (opcache.enable_cli=0).

Zakaj po namestitvi še vedno vidim staro kodo?

Verjetno OPcache spremembe datotek preverja samo v presledkih ali sploh ne. Z opcache.revalidate_freq privzeto čaka dve sekundi, z opcache.validate_timestamps=0 nikoli. Takrat pomaga samo ponastavitev predpomnilnika ali ponovni zagon PHP-FPM oziroma Apacheja.

Ali po posodobitvi PHP zadošča opcache_reset()?

Ne. opcache_reset() izprazni samo predpomnilnik s prevedenimi skriptami. Posodobitev PHP zamenja interpreter sam, ta pa je naložen v vsakem tekočem procesu. Za to je treba znova zagnati vse procese PHP.

Ali je JIT v PHP 8.4 vklopljen?

Po priročniku je opcache.jit od PHP 8.4.0 privzeto nastavljen na disable, opcache.jit_buffer_size pa znaša 64M. Prej je bilo obratno: jit na tracing, medpomnilnik na 0. V obeh primerih JIT brez zavestne konfiguracije ni aktiven.

Viri

Takojšnji stik

Vsaka ura šteje. Pišite nam zdaj.

Na kratko opišite sistem, različico PHP in opažanje. Odzovemo se, razjasnimo stanje in delamo na daljavo, dokler incident ni zaključen in dokumentiran.

Takojšnja pomoč