Pašinstallējošs PHP skripts
10. October, 2007, 17:19 PHPJaslabs: High performance Software blogā atradu nelielu skripta paraugu, kas, ja tiek palaists, izveido jaunu php skriptu. It kā nekas īpašs, bet pati metode ir interesanta.
Piemērā tiek izmantota __halt_compiler() funkcija, kas kad izsaukta, kā jau nosaukums saka priekšā, pārtrauc tālāku skripta pārsēšanu un kompilēšanu. Tādejādi aiz šīs funkcijas izsaukuma varam likt kādus vien datus vēlamies.
Darbības princips ir tāds:
- Palaižam skriptu,
- Skripts ielasa pats sevi sākot no baita, kas ir pieejams __COMPILER_HALT_OFFSET__ konstantē. Par šo konstanti var palasīt vairāk pie __halt_compiler() funkcijas apraksta. Šī konstante ir pieejama tikai skriptiem, kuros ir jau pieminētā funkcija,
- Skripts izveido jaunu failu un iekopē tajā iepriekš nolasītos datus,
Kāpēc vajadzīga šāda mahinācija, ja var vienkārši datus glabāt iekš stringa ? Īsti nezinu. Varbūt kāds no jums varētu pastāstīt ?


10. October, 2007, 18:10
Izplatot softu nevajadzēs dot simtus failu līdzi. Varēs iedot tikai vienu php failu, kuru palaižot tas pats “atarhivēsies” un saliks visus simtos failus vajadzīgajās vietās.
Linuxī dažkārt ir gadījies redzēt šāda veida spēļu instalācijas (piemēram Unreal Tournament, ja nemaldos). Ir parasts sh skripta fails, kuram galā bināri dati piekarināti un tas analoģiskā veidā dabū informāciju ārā no sevis.
10. October, 2007, 18:13
bubu, to jau sapratu - bet kāpēc gan to pašu nevar realizēt ar bināro datu glabāšanu parastos php mainīgajos ? Atmiņas problēmas ? Null byte characteri varbūt jauktu gaisu ?
10. October, 2007, 19:52
Viens no iemesliem varētu būt atmiņas taupīšana. Nezinu PHP uzbūvi tik smalki, bet varbūt ir tā, ka dati pēc halt_compiler() atrašanās vietas netiek lādēti atmiņā? Attiecīgi pieņemot, ka šo daļu nelādē atmiņā, ja tur ir 10mb binārs fails, mēs
1) neriskējam pārsniegt “memory_limit” konstanti
2) mazāk aizķēpājam heap atmiņu
Otra lieta, ja to grib ierakstīt vienkāršos mainīgajos, sanāk mazliet neērti strādāt ar pēdiņām, kuras nepārtraukti jāeskeipo (pardon my French)
10. October, 2007, 20:37
Par to lādēšanu/nelādēšanu atmiņā: tāpat jau pēc tam ar fopen vai ko līdzību ir jāielasa dati, kas ir aiz halt.
Par pēdiņām: var mēģināt izmantot heredoc sintaksi. http://lv2.php.net/heredoc
10. October, 2007, 21:37
Tieši tā, atverot ar fopen, mēs iegūstam resursu, kas netiek viss pilnībā ielasīts atmiņā, bet ir lasāms pa baitam. Tāpat arī pa baitam var pārrakstīt otrā failā.
Heredoc būtu labi, bet “Heredoc text behaves just like a double-quoted string, without the double-quotes. …. Variables are expanded, …. “, tātad mainīgie, kas pieejami instalācijas skripta izpildes laikā, būs aizstāti ;-)
10. October, 2007, 22:10
Taisnība. Bet par to fopen. Ja, piemēram, dati tiks saglabāti base64 formātā (kā ir tajā piemērā) vai pat saarhivēti kaut kā, tad nāksies jau vien visu reizē tāpat ielašit.
10. October, 2007, 22:22
pardon, piemēru nebiju apskatījies. Tādā variantā kā tur demonstrēts, tiešām bez kārtīgas ielādes atmiņā neiztikt - un domājams, ka uz tādiem teksta izmēriem, kā tur bija, nebūtu arī vērts ņemties.
Bet diezgan bieži jau sanāk tā, ka kaut ko darām tieši tā tikai tāpēc, ka tā arī var ;-)
14. October, 2007, 16:46
base64 var jau arī atkodēt neielasot visu stringu atmiņā. Var pa druskai, pa gabaliņam. Tas ka tas tur autors tā nemācēja/neuzrakstīja nenozīmē, ka visiem tagad jādara viņam pakaļ.