Trenutno stanje: PHP2Shell. Dvije kritične PHP ranjivosti (CVSS 9.2) omogućuju zlonamjerni kod bez prijave. Zakrpe od 21. 10. 2026.Što sada učiniti →

OPcache objašnjen: PHP-ova predmemorija bytecodea

OPcache drži preveden PHP kod u zajedničkoj memoriji. To štedi računalno vrijeme, ali traži pažnju pri deploymentima, ponovnim pokretanjima i na poslužiteljima s više klijenata.

Stanje 4 min čitanjaPHP znanje

Ukratko: OPcache je ugrađena PHP-ova predmemorija bytecodea. Prema priručniku pohranjuje unaprijed kompiliran bytecode u zajedničku memoriju, pa PHP skripte ne mora pri svakom zahtjevu iznova učitavati i prevoditi. Dio je isporuke od PHP-a 5.5.0. OPcache ubrzava PHP, ali ne zamjenjuje ažuriranje: nakon PHP zakrpe moraju se ponovno pokrenuti svi PHP procesi, a ne samo isprazniti predmemorija.

Što točno radi OPcache?

Pri svakom zahtjevu PHP mora pročitati skriptu, rastaviti je i prevesti u opcodeove, dakle u naredbe za virtualni stroj Zend Enginea. Kod CMS-a sa stotinama datoteka to je puno posla koji se neprestano ponavlja.

OPcache rezultat tog prevođenja sprema u zajedničku memoriju (shared memory). Pristupaju joj svi workeri jedne PHP-FPM usluge odnosno svi Apache procesi s mod_php-om. Ako se datoteka ne promijeni, njezin se bytecode izravno ponovno koristi.

OPcache se učitava kao Zend ekstenzija, a ne kao obična ekstenzija:

; Linux (putanja ovisi o paketu)
zend_extension=opcache.so
; Windows
; zend_extension=php_opcache.dll

Prema priručniku OPcache treba učitati prije Xdebuga ako su oba aktivna.

Važno je kome pripada zajednička memorija. Kod PHP-FPM-a nju stvara master proces, a koriste je svi workeri svih poolova te usluge. Kod mod_php-a pripada glavnom procesu Apachea. Ponovno pokretanje usluge stoga potpuno prazni predmemoriju, a jedan novi worker ne. Za naredbeni redak ne postoji zajednička memorija među pozivima jer je svaki poziv zaseban proces; tamo je OPcache prema zadanim postavkama isključen.

Za donositelje odluka dovoljno je jedno pravilo: OPcache je na produkcijskim poslužiteljima gotovo uvijek smislen, ali traži jasan slijed za deploymente i ažuriranja.

Koje OPcache postavke vrijede?

Sljedeće vrijednosti potječu sa stranice konfiguracije PHP priručnika. Stupac „Promjenjivo“ pokazuje gdje se postavka smije podešavati: INI_SYSTEM samo u php.ini ili konfiguraciji poslužitelja, INI_ALL posvuda.

Direktiva Zadano Promjenjivo Značenje
opcache.enable 1 INI_ALL predmemorija uključena ili isključena, tijekom rada može se samo isključiti
opcache.enable_cli 0 INI_SYSTEM predmemorija za naredbeni redak
opcache.memory_consumption 128 INI_SYSTEM veličina zajedničke memorije u MB
opcache.interned_strings_buffer 8 INI_SYSTEM memorija za zajedničke nizove znakova u MB
opcache.max_accelerated_files 10000 INI_SYSTEM najveći broj skripti u predmemoriji
opcache.validate_timestamps 1 INI_ALL provjerava jesu li se datoteke promijenile
opcache.revalidate_freq 2 INI_ALL razmak provjere u sekundama, 0 = pri svakom zahtjevu
opcache.restrict_api prazno INI_SYSTEM dopušta API funkcije samo iz jedne putanje
opcache.validate_permission 0 INI_SYSTEM provjerava prava datoteka u odnosu na trenutnog korisnika
opcache.validate_root 0 INI_SYSTEM sprječava sukobe naziva kod chroota
opcache.file_cache prazno INI_SYSTEM druga razina predmemorije na disku

Tipična produkcijska konfiguracija mogla bi izgledati ovako. Vrijednosti prije provjerite sa svojom aplikacijom:

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

Tko postavi opcache.validate_timestamps=0, dobiva malo učinkovitosti. No tada OPcache uopće više ne prepoznaje izmijenjene datoteke i svaki deployment traži reset predmemorije ili ponovno pokretanje.

Promatrati predmemoriju i ciljano je prazniti

OPcache donosi vlastite funkcije, među ostalim opcache_get_status(), opcache_get_configuration(), opcache_invalidate() i opcache_reset(). Kratak pogled samo za čitanje na popunjenost:

<?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 poslužiteljima s više web-stranica ne bi svaka aplikacija smjela moći prazniti ili čitati predmemoriju svih ostalih. Za to služi opcache.restrict_api: API funkcije smiju pozivati samo skripte ispod navedene putanje.

JIT: kompilator strojnog koda u OPcacheu

Od PHP-a 8.0 OPcache sadrži JIT kompilator koji opcodeove prevodi u strojni kod. Prema JIT RFC-u gotovo je samostalan dio OPcachea i stvoreni kod sprema u zasebno područje zajedničke memorije. Upravlja se putem opcache.jit i opcache.jit_buffer_size. Od PHP-a 8.4.0 opcache.jit je prema zadanim postavkama disable. Kada se JIT isplati, objašnjava članak JIT i performanse u PHP-u 8.

OPcache i sigurnost: što vrijedi nakon PHP2Shella

OPcache nije sigurnosni alat, ali ima posljedice za sigurnost. Tri su točke važne nakon PHP2Shella:

  1. Reset predmemorije nije ažuriranje. opcache_reset() prazni samo skripte u predmemoriji. Interpreter s ranjivostima CVE-2026-109618 i CVE-2026-109619 ostaje u memoriji dok se svi procesi ne pokrenu iznova. Kako to ide, piše na stranici Ponovno pokretanje PHP-FPM-a i svih workera.
  2. Ubačeni kod može živjeti u predmemoriji. Ako je datoteka bila manipulirana, a kasnije zamijenjena, uz isključenu provjeru vremenskih oznaka stara se izvedba može i dalje izvršavati. Nakon čišćenja zato treba i ponovno pokretanje.
  3. Zajednička memorija traži razdvajanje. Na poslužiteljima s više klijenata pomažu vlastiti PHP-FPM poolovi po web-stranici te opcache.validate_permission i opcache.restrict_api. Direktorij za opcache.file_cache smije biti upisiv samo za PHP korisnika.
Savjet

Nakon svakog ažuriranja provjerite je li vrijeme pokretanja PHP procesa poslije ažuriranja. Pun OPcache s visokom stopom pogodaka nije dokaz da radi novi interpreter.

Kako PHP SOS konkretno pomaže?

  • Provjeriti konfiguraciju: Očitavamo aktivnu OPcache konfiguraciju po načinu rada i uspoređujemo je s Vašom aplikacijom.
  • Osigurati deploymente: Uspostavljamo čvrst slijed za reset predmemorije i ponovno pokretanje kako nijedna stara izvedba koda ne bi nastavila raditi.
  • Razdvojiti klijente: U okviru ojačavanja poslužitelja postavljamo odvojene poolove, restrict_api i odgovarajuća prava.
  • Provjeriti nakon ažuriranja: Putem vremena pokretanja procesa dokazujemo da je ažurirani interpreter stvarno aktivan.

Česta pitanja

Je li OPcache prema zadanim postavkama aktivan?

OPcache se isporučuje s PHP-om od verzije 5.5.0 i prema priručniku radi s opcache.enable=1 kao zadanom vrijednosti čim se ekstenzija učita. Je li učitana, ovisi o Vašem paketu ili pružatelju hostinga. U naredbenom retku OPcache je, naprotiv, prema zadanim postavkama isključen (opcache.enable_cli=0).

Zašto nakon deploymenta još vidim stari kod?

Vjerojatno OPcache izmjene datoteka provjerava samo u razmacima ili uopće ne. S opcache.revalidate_freq prema zadanim postavkama čeka dvije sekunde, a s opcache.validate_timestamps=0 nikad. Tada pomaže samo reset predmemorije ili ponovno pokretanje PHP-FPM-a odnosno Apachea.

Je li opcache_reset() dovoljan nakon ažuriranja PHP-a?

Ne. opcache_reset() prazni samo predmemoriju s prevedenim skriptama. Ažuriranje PHP-a zamjenjuje sam interpreter, a on je učitan u svakom pokrenutom procesu. Zato se moraju ponovno pokrenuti svi PHP procesi.

Je li JIT uključen u PHP-u 8.4?

Prema priručniku opcache.jit je od PHP-a 8.4.0 prema zadanim postavkama postavljen na disable, dok opcache.jit_buffer_size iznosi 64M. Prije je bilo obrnuto: jit na tracing, međuspremnik na 0. U oba slučaja JIT bez svjesne konfiguracije nije aktivan.

Izvori

Hitni kontakt

Svaki sat se računa. Pišite nam odmah.

Ukratko opišite sustav, verziju PHP-a i opažanje. Javit ćemo Vam se, razjasniti situaciju i raditi na daljinu dok incident nije zaključen i dokumentiran.

Hitna pomoć