ugrás a tartalomhoz

Kód és adat együtt - most már PHP-ben is lehetséges

Hojtsy Gábor · 2005. Jún. 5. (V), 10.22
Ismét egy olyan újdonságról számolhatok be, ami a PHP 5.1-ben jelenik majd meg. Ezúttal Ilia Alshanetsky ismerteti az új lehetőséget, amelynek lényege, hogy a PHP szkriptünket a fájl befejezése előtt lezárhassuk úgy, hogy az azt követő adatokat a Zend motor már ne dolgozza fel, de elérhetőek legyenek számunkra a hagyományos fájlkezelő utasításokkal.

A technika teljesen egybecsomagolt szkriptek kialakításakor hasznos, és Perlben már régóta ismert. Ott a __DATA__ jelölőt kell elhelyezni a fájlban, ami a Perl kód végét jelzi, és az ezt követő részt a main::DATA (azaz pontosabban csomagneve::DATA) fájlkezelőről olvashatjuk be.

A PHP 5.1-es megoldás úgy fest, hogy a __HALT_COMPILER() utasítást adjuk ki, és a szkript fájlból olvasva a __COMPILER_HALT_OFFSET__ pozíciótól kaphatjuk meg a lezárás utáni adathalmazt. Ez lehetővé teszi, hogy telepítő szkripteknél szükséges fájlokat (akár több megabájtnyi adatot) is a fájl végére fűzzünk, és egyetlen PHP állományként tegyük elérhetővé azt.

<?php
// A szkriptfájl megnyitása a HALT pozíciótól
echo file_get_contents(__FILE__, NULL, NULL, __COMPILER_HALT_OFFSET__);
?>
<?php __HALT_COMPILER();
ide bármi kerülhet, akár bináris adat is
Ilia tájékoztatása szerint a több megabájtos adattartalom sem okoz majd gondot a feldolgozásnál, hiszen ezt a Zend Engine már nem dolgozza fel, így nem terheli a PHP memória korlátját. A file_get_contents() hívás természetesen már a memóriába emeli az adatokat, ezért itt legyünk körültekintőek, ha sok adatot kívánunk beemelni egyidőben.
 
1

Ronda

Bártházi András · 2005. Jún. 5. (V), 11.09
Hát, ezt ennél szebben is ki lehetett volna vitelezni. Miért függvényhívásként kellett ezt megvalósítani? :(

-boogie-
3

mindegy

Hojtsy Gábor · 2005. Jún. 5. (V), 11.46
Nem mindegy, hogy __HALT_COMPILER__ vagy __HALT_COMPILER()? Úgyse függvény, mint ahogy sok más nyelvi elem sem, ami annak látszik.
5

nem mindegy

Bártházi András · 2005. Jún. 5. (V), 12.35
Egyáltalán nem mindegy. Egyrészt, a kezdők azt fogják hinni, hogy ez egy függvény, s még azt is el tudom képzelni, hogy a program közepén is megpróbálják használni. Ettől függetlenül is, miért kell függvényként jelölni?

Ezen felül bár lehet, hogy konkrétan a fordítónak jelez, hogy itt fejezd be a fordítást, mint nyelvi elem, egyáltalán nem ez a feladata. Sokkal szebb lett volna egy __CODE_END__, vagy bármi más, ami a funkcióra utal.

Nekem ebből a teljes tervezetlenség és adhoc megvalósítás esik le, melyet máshol is látni a PHP kapcsán (például a különböző koncepciókra gondolok a függvények elnevezésénél - egybeírjuk, aláhúzással jelöljük, stb.).

Persze ettől még maga a funkció jó, csak ezután ne mondja senki se a Perlre, hogy olvashatatlan. :)

-boogie-
6

funkció == function

Hojtsy Gábor · 2005. Jún. 5. (V), 12.48
Figyeled, hogy funkcióról beszélsz, ami angolul function :) Ez egy utasítás, nem egy konstans, amit PHP-ben valóban __CODE_END__ módon lehetne jelölni. Ez nem egy érték, hanem egy utasítás! Aki a kód közepén használja, az majd megkapja az eredményét. Tudomásom szerint a tokenizer számára teljesen mindegy, hogy hol van a kódban ez a dolog, és van e zárójel utána vagy nincs, úgyhogy ez egy felhasználói szempontok alapján megállapított szintakszis szerintem. Az include_once is függvényként jelenik meg például!
8

funkció == feature

Bártházi András · 2005. Jún. 5. (V), 14.51
Én inkább feautre-nek fordítanám... Én nem utasításnak venném, hanem jelölőnek. Ezt a függvényt "nem hajtja végre semmi", itt egyszerűen vége van a kódnak. Ez legjobb esetben is egy fordítási jelzés, s nem egy futás közben végrehajtandó függvény. Szerintem. Az include_once az végrehajtásra is kerül, futásidőben hajtódik végre, részemről egyértelmű, hogy függvény. :) De látom úgyse tudlak meggyőzni... Valóban a PHP-s konstansok miatt nem feltétlenül jó a __CODE_END__ jelölés, de a függvénnyel se vagyok kibékülve. ;)

-boogie-
9

új jelölés meg minek?

Hojtsy Gábor · 2005. Jún. 5. (V), 15.24
Van egy csomó beépített konstans, ami úgy néz ki, hogy __FILE__, __LINE__ meg hasonlók. Most ilyen funkcionalitást ilyen néven nem lehet bevezetni, mert ez a konstansok szintakszisa. Új jelölést meg minek kitalálni erre, a C preprocesszor utasításainak kistestvéreit nem kell itt feltalálni szerintem... Lehetne kulcsszóval megoldani, de az kisbetűs a hagyományok szerint, és nem ütközik ki. A Perlben sem véletlenül __DATA__ a jelölés... Mi marad? Függvények!
11

perl gyökerek ;)

Hodicska Gergely · 2005. Jún. 6. (H), 12.07
Szia!


Szerintem a Perles megoldás miatt érzed ezt csúnyának. Szerintem ezzel semmi gond. Sokkal inkább az egyéb sok-sok nem teljesen átgondolt, illetve nem egységesen használt koncepció, ami PHP sajátja, sajnos.

Mai napig egy in_array() esetén fogalmam sincs, hogy a tömb van-e elöl.
(Bár ez már az én bajom ;))


Felhő
14

csatlakozom...

gerzson · 2005. Jún. 9. (Cs), 21.02
Attól függetlenül, h. lehet-e ezt másképp jelölni vagy sem, ez csúnya, szerintem. Nem lehetett volna valamit játszani a ?>-el esetleg... mindegy úgysem látjuk sokat, remélem.
testing can reveal the presence of errors, but never their absence. - Edsger Dijkstra
2

miért?

bbalint · 2005. Jún. 5. (V), 11.42
(én) sok hasznát nem látom...
miért és mikor van/volna erre szükség?

bbalint
4

belinkeltem

Hojtsy Gábor · 2005. Jún. 5. (V), 11.47
Nem véletlenül linkeltem be, de ide is beidézem:
The logic behind this feature was to simplify the process of creating single-script installers, such as the one used by FUDforum. The installer is a single script that at the end of it contains a code archive of the application being installed, which the installation process places into the set locations.
7

nemtom. én ezt egy éve

suidroot · 2005. Jún. 5. (V), 13.00
nemtom. én ezt egy éve már elintéztem egy szkripttel, ami {ilyen} tag-eket helyettesített be fájlok tartalmával, és php4 alatt is működött; részemről erről ennyit.
10

exit();

kgyt · 2005. Jún. 5. (V), 23.04
A $subj nem jó?


--
Szeretettel: Károly György Tamás
kgyt&kgyt.hu - http://kgyt.hu
12

nem jó!

Hojtsy Gábor · 2005. Jún. 6. (H), 13.51
Nem jó, mert itt arról van szó, hogy a token elérése után a Zend Engine nem tokenizálja (nem fordítja le) tovább a szkriptet, tehát abban bármilyen bináris kód is lehet akár. Az exit() erre nem elég...
13

:-)

kgyt · 2005. Jún. 6. (H), 16.48
Erre godoltam: "exit();?>".
Persze nem lehet benne a lezárás után "<?".
Elvileg ezt sem kell fordítani. Persze átnézi a fordító, de funkcionálisan megoldhatja a problémát...


--
Szeretettel: Károly György Tamás
kgyt&kgyt.hu - http://kgyt.hu