Īsi: OPcache ir PHP iebūvētā baitkoda kešatmiņa. Saskaņā ar rokasgrāmatu tā glabā iepriekš kompilētu baitkodu koplietojamā atmiņā, tāpēc PHP skriptus nav jāielādē un jāpārveido katrā pieprasījumā. Tas ir komplektā kopš PHP 5.5.0. OPcache padara PHP ātrāku, bet neaizstāj atjauninājumu: pēc PHP ielāpa jāpārstartē visi PHP procesi, nepietiek tikai ar kešatmiņas iztīrīšanu.
Ko OPcache dara precīzi?
Katrā pieprasījumā PHP skripts jānolasa, jāsadala un jāpārveido opcodes, tas ir, komandās Zend Engine virtuālajai mašīnai. CMS ar simtiem failu tas ir liels darbs, kas pastāvīgi atkārtojas.
OPcache šīs pārveides rezultātu glabā koplietojamā atmiņā (Shared Memory). Tai piekļūst visi PHP-FPM pakalpojuma darbprocesi vai visi Apache procesi ar mod_php. Ja fails nemainās, tā baitkods tiek izmantots atkārtoti tieši.
OPcache ielādē kā Zend paplašinājumu, nevis kā parastu paplašinājumu:
; Linux (ceļš atkarībā no pakotnes)
zend_extension=opcache.so
; Windows
; zend_extension=php_opcache.dll
Saskaņā ar rokasgrāmatu OPcache jāielādē pirms Xdebug, ja abi ir aktīvi.
Svarīgi, kam pieder koplietojamā atmiņa. PHP-FPM gadījumā to izveido galvenais process (master), un to izmanto visi šī pakalpojuma visu pūlu darbprocesi. mod_php gadījumā tā pieder Apache galvenajam procesam. Pakalpojuma pārstartēšana tāpēc kešatmiņu iztīra pilnībā, bet atsevišķs jauns darbprocess ne. Komandrindai nav koplietojamas atmiņas starp izsaukumiem, jo katrs izsaukums ir atsevišķs process; tur OPcache pēc noklusējuma ir izslēgts.
Lēmumu pieņēmējiem pietiek ar vienu praktisku likumu: OPcache ražošanas serveros gandrīz vienmēr ir lietderīgs, bet prasa skaidru kārtību izvietošanai un atjauninājumiem.
Kuri OPcache iestatījumi ir svarīgi?
Turpmākās vērtības ņemtas no PHP rokasgrāmatas konfigurācijas lapas. Sleja „Mainīgums“ rāda, kur iestatījumu drīkst iestatīt: INI_SYSTEM tikai php.ini vai servera konfigurācijā, INI_ALL jebkur.
| Direktīva | Noklusējums | Mainīgums | Nozīme |
|---|---|---|---|
opcache.enable |
1 | INI_ALL | kešatmiņa ieslēgta vai izslēgta, izpildes laikā var tikai izslēgt |
opcache.enable_cli |
0 | INI_SYSTEM | kešatmiņa komandrindai |
opcache.memory_consumption |
128 | INI_SYSTEM | koplietojamās atmiņas lielums MB |
opcache.interned_strings_buffer |
8 | INI_SYSTEM | atmiņa kopīgajām virknēm MB |
opcache.max_accelerated_files |
10000 | INI_SYSTEM | kešoto skriptu maksimālais skaits |
opcache.validate_timestamps |
1 | INI_ALL | pārbauda, vai faili ir mainīti |
opcache.revalidate_freq |
2 | INI_ALL | pārbaudes intervāls sekundēs, 0 = katrā pieprasījumā |
opcache.restrict_api |
tukšs | INI_SYSTEM | atļauj API funkcijas tikai no norādīta ceļa |
opcache.validate_permission |
0 | INI_SYSTEM | pārbauda failu tiesības pret pašreizējo lietotāju |
opcache.validate_root |
0 | INI_SYSTEM | novērš nosaukumu sadursmes chroot vidē |
opcache.file_cache |
tukšs | INI_SYSTEM | otrais kešatmiņas līmenis diskā |
Tipiska ražošanas konfigurācija varētu izskatīties šādi. Vērtības iepriekš pārbaudiet ar savu lietojumprogrammu:
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 iestata opcache.validate_timestamps=0, iegūst nedaudz veiktspējas. Taču tad OPcache mainītus failus vairs neatpazīst vispār, un katrai izvietošanai vajadzīga kešatmiņas atiestatīšana vai pārstartēšana.
Kešatmiņas novērošana un mērķtiecīga tīrīšana
OPcache nāk ar savām funkcijām, to vidū opcache_get_status(), opcache_get_configuration(), opcache_invalidate() un opcache_reset(). Īss, tikai lasošs skats uz aizpildījumu:
<?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);
Serveros ar vairākām vietnēm ne katrai lietojumprogrammai vajadzētu būt iespējai iztīrīt vai nolasīt visu pārējo kešatmiņu. Tam paredzēts opcache.restrict_api: API funkcijas drīkst izsaukt tikai skripti zem norādītā ceļa.
JIT: mašīnkoda kompilators OPcache
Kopš PHP 8.0 OPcache ir JIT kompilators, kas opcodes pārveido mašīnkodā. Saskaņā ar JIT RFC tas ir gandrīz patstāvīga OPcache daļa un izveidoto kodu glabā savā koplietojamās atmiņas apgabalā. Vada to ar opcache.jit un opcache.jit_buffer_size. Kopš PHP 8.4.0 opcache.jit pēc noklusējuma ir disable. Kad JIT ir vērts izmantot, izskaidro raksts JIT un veiktspēja PHP 8.
OPcache un drošība: kas spēkā pēc PHP2Shell
OPcache nav drošības rīks, taču tam ir sekas drošībai. Pēc PHP2Shell svarīgi trīs punkti:
- Kešatmiņas atiestatīšana nav atjauninājums.
opcache_reset()iztīra tikai kešotos skriptus. Interpretators ar ievainojamībām CVE-2026-109618 un CVE-2026-109619 paliek atmiņā, līdz visi procesi ir pārstartēti. Kā to izdarīt, skatiet sadaļā PHP-FPM un visu darbprocesu pārstartēšana. - Ievadīts kods var turpināt dzīvot kešatmiņā. Ja fails tika manipulēts un vēlāk aizstāts, ar izslēgtu laika zīmogu pārbaudi var turpināt izpildīt veco versiju. Pēc tīrīšanas tāpēc obligāti jāpārstartē.
- Koplietojamai atmiņai vajadzīga nošķiršana. Serveros ar vairākiem klientiem palīdz atsevišķi PHP-FPM pūli katrai vietnei, kā arī
opcache.validate_permissionunopcache.restrict_api. Direktorijamopcache.file_cachejābūt rakstāmam tikai PHP lietotājam.
Pēc katra atjauninājuma pārbaudiet, vai PHP procesu startēšanas laiks ir vēlāks par atjauninājumu. Pilna OPcache ar augstu trāpījumu līmeni nav pierādījums, ka darbojas jaunais interpretators.
Kā PHP SOS palīdz konkrēti?
- Pārbaudīt konfigurāciju: Mēs nolasām aktīvo OPcache konfigurāciju katram darbības režīmam un salīdzinām to ar jūsu lietojumprogrammu.
- Nodrošināt izvietošanu: Mēs ieviešam stingru kārtību kešatmiņas atiestatīšanai un pārstartēšanai, lai neturpinātu darboties vecā koda versija.
- Nošķirt klientus: Servera nostiprināšanas ietvaros mēs iestatām atsevišķus pūlus,
restrict_apiun piemērotas tiesības. - Kontrolēt pēc atjauninājumiem: Mēs pēc procesu startēšanas laikiem pierādām, ka atjauninātais interpretators patiešām ir aktīvs.
Biežāk uzdotie jautājumi
Vai OPcache pēc noklusējuma ir aktīvs?
OPcache tiek piegādāts kopā ar PHP kopš PHP 5.5.0, un saskaņā ar rokasgrāmatu ar opcache.enable=1 pēc noklusējuma darbojas, tiklīdz paplašinājums ir ielādēts. Vai tas ir ielādēts, atkarīgs no jūsu pakotnes vai hostinga sniedzēja. Komandrindā OPcache pēc noklusējuma ir izslēgts (opcache.enable_cli=0).
Kāpēc pēc izvietošanas (deployment) joprojām redzu veco kodu?
Visticamāk, OPcache failu izmaiņas pārbauda tikai ar intervāliem vai nemaz. Ar opcache.revalidate_freq tas pēc noklusējuma gaida divas sekundes, ar opcache.validate_timestamps=0 nekad. Tad palīdz tikai kešatmiņas atiestatīšana vai PHP-FPM vai Apache pārstartēšana.
Vai pēc PHP atjauninājuma pietiek ar opcache_reset()?
Nē. opcache_reset() iztīra tikai kešatmiņu ar pārveidotajiem skriptiem. PHP atjauninājums nomaina pašu interpretatoru, un tas ir ielādēts katrā darbojošamies procesā. Tāpēc jāpārstartē visi PHP procesi.
Vai JIT PHP 8.4 ir ieslēgts?
Saskaņā ar rokasgrāmatu opcache.jit kopš PHP 8.4.0 pēc noklusējuma ir iestatīts uz disable, savukārt opcache.jit_buffer_size ir 64M. Iepriekš bija otrādi: jit uz tracing, buferis uz 0. Abos gadījumos JIT bez apzinātas konfigurācijas nav aktīvs.