Fil-qosor: PHP jeħles il-memorja l-aktar permezz tal-għadd ta' referenzi: kull valur jaf kemm varjabbli jipponta lejh, u jitħassar hekk kif dan il-kontatur jilħaq iż-żero. Għal referenzi ċirkulari, li hekk qatt ma jinħelsu, hemm garbage collector taċ-ċikli. Fi tmiem kull talba PHP jirranġa wkoll dak kollu li t-talba okkupat. Iż-żewġ vulnerabbiltajiet ta' PHP2Shell jibdew minn stati tal-memorja: minn stat ta' Out-of-Memory waqt l-ipproċessar tat-talba u minn stat intern li jibqa' wisq wara li jinħeles.
Kif PHP jamministra l-memorja: ħarsa ġenerali
F'lingwi bħal C il-programmatur irid jitlob u jeħles il-memorja waħdu. PHP jeħodha mill-ispallejn. Kull varjabbli, kull array u kull oġġett jokkupa memorja li PHP jamministra permezz tal-memory manager tiegħu stess. Il-limitu għal dan jistabbilixxih memory_limit, skont il-manwal b'mod awtomatiku 128M.
Għal min jieħu d-deċiżjonijiet punt wieħed huwa ċentrali: fit-tħaddim klassiku b'PHP-FPM jew mod_php jaħdmu proċessi worker li jgħixu fit-tul u jittrattaw ħafna talbiet wara xulxin. Dak li talba tħalli warajha għandu jkun irranġat b'mod affidabbli qabel it-talba li jmiss. Eżatt f'dan il-punt tinsab waħda mill-vulnerabbiltajiet ta' PHP2Shell.
Għadd ta' referenzi: jgħodd min juża valur
PHP jaħżen kull valur f'kontenitur imsejjaħ zval. Minbarra tip u kontenut, skont il-manwal iżomm kontatur tar-referenzi (refcount) u marka jekk il-valur huwiex parti minn referenza ta' PHP b'& (is_ref).
<?php
$a = str_repeat('x', 1000); // valur wieħed, refcount 1
$b = $a; // ebda kopja, refcount 2
$b .= 'y'; // biss issa tinħadem kopja (Copy-on-Write)
unset($a); // ir-refcount tal-oriġinal jinżel
// Jekk kontatur jilħaq 0, PHP jeħles il-memorja immedjatament.
Il-prinċipju jissejjaħ Copy-on-Write: PHP jikkopja valur biss meta waħda mill-varjabbli tbiddlu. Dan iħasseb ħafna memorja. Il-kontatur ta' varjabbli jista' jsir viżibbli bl-estensjoni Xdebug u l-funzjoni xdebug_debug_zval(). Il-manwal jindika li n-numri eżatti jistgħu jvarjaw skont il-verżjoni ta' PHP.
Ċikli: meta l-għadd ta' referenzi ma jaqbilx
L-għadd ta' referenzi għandu dgħufija magħrufa. Jekk struttura tipponta lejha nfisha, il-kontatur tagħha qatt ma jinżel għal żero.
<?php
$a = ['eins'];
$a[] = &$a; // l-array fih referenza għalih innifsu
unset($a); // ħadd ma jista' jaċċessah aktar, imma r-refcount jibqa' 1
Skont il-manwal referenzi ċirkulari bħal dawn jinstabu b'mod speċjali f'oġġetti, pereżempju f'strutturi ġenitur-tifel jew f'parsers. Tnixxijiet individwali huma bla ħsara, għax PHP inaddaf fi tmiem it-talba. Fi proċessi li jaħdmu fit-tul, bħal workers ta' kodi jew testijiet kbar, miljuni minnhom jistgħu madankollu jinġabru f'problema vera tal-memorja.
Il-garbage collector taċ-ċikli
Minn PHP 5.3.0 PHP juża algoritmu ta' Bacon u Rajan biex isib ċikli bħal dawn. L-idea bażika: ċiklu jista' jinħoloq biss meta kontatur jinżel għal valur akbar minn żero. Dawn il-valuri biss PHP jiftakarhom bħala għeruq possibbli.
- L-għeruq possibbli jispiċċaw f'buffer. Il-manwal jisemmi bħala daqs standard 10,000 entrata; il-limitu validu bħalissa jurih
gc_status()fil-qasamthreshold. - Meta l-buffer jimtela, PHP jgħaddi minn kull valur li jista' jintlaħaq u jbaxxi b'mod provviżorju l-kontaturi tagħhom.
- Fit-tieni mogħdija: valuri b'kontatur żero huma skart, għall-oħrajn it-tnaqqis jiġi mħassar.
- L-għeruq jitneħħew mill-buffer u l-valuri kollha rikonoxxuti bħala skart jinħelsu.
Dan jiġi kkontrollat permezz ta' zend.enable_gc (mixgħul b'mod awtomatiku) jew waqt it-tħaddim b'gc_enable() u gc_disable(). gc_collect_cycles() iġġiegħel ċiklu u jirritorna l-għadd taċ-ċikli miġbura.
Kejl u osservazzjoni tal-memorja
| Funzjoni | Skop |
|---|---|
memory_get_usage() |
il-memorja okkupata bħalissa mill-iskript |
memory_get_usage(true) |
il-memorja riżervata mill-memory manager mas-sistema; kontra dan il-valur jiġi vverifikat memory_limit |
memory_get_peak_usage() |
l-ogħla livell tal-memorja okkupata |
gc_status() |
ċikli, ċikli miġbura, limitu, għeruq; minn PHP 8.3.0 anki ħinijiet tat-tħaddim |
gc_collect_cycles() |
iqajjem il-ġbir taċ-ċikli immedjatament |
WeakMap |
assenjazzjoni għal oġġetti mingħajr ma tipprevjeni l-ħelsien tagħhom, minn PHP 8.0 |
Skont il-manwal memory_get_usage() jirreġistra biss il-memorja li PHP jitlob permezz tal-memory manager tiegħu stess. Dak li l-estensjonijiet jieħdu direttament mis-sistema operattiva ma jidhirx f'dawn in-numri. Għal-limitu tal-memorja tal-proċess kollu huma għalhekk responsabbli s-sistema operattiva jew il-container.
Ġestjoni tal-memorja u PHP2Shell
Id-deskrizzjonijiet taż-żewġ vulnerabbiltajiet jwasslu direttament f'dan is-suġġett. F'CVE-2026-109618 stat ta' Out-of-Memory jista' jinterrompi PHP waqt li d-data tat-talba hija inizjalizzata biss parzjalment; waqt it-tindif data invalida tista' mbagħad tiġi ttrattata bħala valida. X'jiġri ġewwa waqt overflow tal-memorja tispjegah il-paġna memory_limit u Out-of-Memory. F'CVE-2026-109619 stat intern ta' talba jista' jibqa' wara li titħeles il-memorja u jintuża minn talba aktar tard fl-istess worker qabel ma jiġi rrisettjat. Il-fluss minn meta jibda sa meta jitnaddaf jiddeskrivih il-paġna Iċ-ċiklu tal-ħajja tat-talba.
Bħala miżura temporanja php.net jirrakkomanda li memory_limit=-1 jiġi ssettjat b'mod li l-applikazzjonijiet ma jistgħux jissostitwuh, pereżempju b'php_admin_value fil-pool ta' FPM, u li l-memorja tiġi llimitata minflok permezz ta' containers jew cgroups, mhux permezz ta' RLIMIT_AS jew RLIMIT_DATA. Kif dan isir b'systemd juri l-artikolu Issettja l-limiti tal-memorja b'systemd u cgroups.
; Pool ta' FPM: miżura temporanja skont php.net, wara erġgħu ibdew il-workers kollha
php_admin_value[memory_limit] = -1
Mingħajr limitu permezz ta' container jew cgroup, proċess individwali jista' jgħabbi s-server kollu. U l-ebda issettjar ma jieħu post l-aġġornament għal PHP 8.5.12, 8.4.27, 8.3.36 jew 8.2.35 flimkien mar-restart tal-workers kollha, għax biss ir-restart ineħħi proċessi qodma mill-memorja.
Kif jgħin PHP SOS konkretament?
- Niċċekkjaw l-issettjar effettiv tal-memorja għal kull pool u jekk l-applikazzjonijiet jistgħux jissostitwuh.
- Napplikaw il-miżuri temporanji b'limitu tal-memorja fil-livell ta' container jew cgroup u nittestjaw it-tagħbija.
- Napplikaw l-aġġornament, nerġgħu nibdew il-workers kollha u nuru li ma jaħdmu l-ebda proċessi qodma aktar, bħala parti mis-Servizz ta' patch għal PHP tagħna.
- Nevalwaw żbalji tal-memorja u workers interrotti fil-logs mill-20 ta' Ottubru 2026.
Mistoqsijiet frekwenti
X'inhu l-għadd ta' referenzi f'PHP?
PHP jgħodd għal kull valur kemm varjabbli jew elementi jirreferu għalih. Meta l-kontatur jinżel għal żero, il-memorja tinħeles immedjatament. Hekk il-biċċa l-kbira tal-memorja tingħata lura mingħajr ċiklu ta' tindif proprju.
Għaliex PHP xorta jeħtieġ garbage collector?
Għaċ-ċikli. Jekk array jirreferi għalih innifsu jew żewġ oġġetti jafu lil xulxin, il-kontatur ma jinżilx qatt għal żero, anki jekk ħadd ma jaċċessah aktar. Il-garbage collector taċ-ċikli jsib u jneħħi strutturi bħal dawn.
PHP jeħles il-memorja fi tmiem talba?
Iva, il-memorja li skript jokkupa waqt talba, PHP inaddafha fi tmiem it-talba. Fil-każ ta' PHP2Shell, madankollu, CVE-2026-109619 jikkonċerna eżattament każ fejn stat intern jista' jibqa' wara li jinħeles u jintuża minn talba aktar tard fl-istess worker.
Għaliex php.net jirrakkomanda memory_limit=-1 bħala miżura temporanja?
Il-vulnerabbiltà CVE-2026-109618 hija relatata ma' stat ta' Out-of-Memory. php.net jirrakkomanda li memory_limit=-1 jiġi ssettjat b'mod li l-applikazzjonijiet ma jistgħux jissostitwuh, u li l-memorja tiġi llimitata minflok permezz ta' containers jew cgroups. Din mhix protezzjoni sħiħa u ma tieħux post l-aġġornament.