Mit is tud a PHP 5.3
Már egy ideje forgatom a fejemben a gondolatot, hogy kellene egy gyakorlatorientált miniprojektet gyártani a PHP 5.3 képességei felderítésére. Jelentem, elérkezett a pillanat, úgyhogy ihun a reggeli kávé mellé a tapasztalatok.
Már egy ideje körvonalazódni látszik, hogy Zendék abba az irányba szeretnének elmenni, hogy hasonlítson a PHP a Javara. Ennek egyetlen és legfőbb akadálya az a kiscsillió kiterjesztés, ami abszolút procedurális szemléletben lett megírva. Avagy konyhanyelven, nem kivételt dobnak, hanem hagyományos hibát. Ennek aztán nem örül a programozó, mert bonyolult elkapni, nem örül a rendszergazda, mert tele lesz a log szeméttel.
Na, a kis kitérő után lássuk tehát a feladatot. Miután Java, hát legyen Java. Készítsük el a mappastruktúrát, aminek nagyjából így kéne kinéznie:
- bootstrap
- classes
- PHP
- IO
- Lang
- Tests
- PHP
- IO
- Lang
- PHP
- PHP
A Javaban jártasak már láthatják, miféle szentségtörésre készülök itt. Először is nézzük az Object
osztályunkat a classes/PHP/Lang
mappában:
<?php
namespace PHP\Lang;
/**
* Ez a generikus ososztaly lesz minden rendszerbeli osztaly atyja.
*/
abstract class Object {
/**
* Ez tarolja a peldany egyedi azonositojat. A hashCode() fuggvenybol kell
* kiolasni az erteket.
* @var int
*/
private $hashCode;
/**
* Konstruktor.
*/
public function __construct() {}
/**
* Destruktor.
*/
public function __destruct() {}
/**
* Visszaadja a kurrens peldany osztalyanak a nevet.
* @return string
*/
public final function className() {
return get_class($this);
}
/**
* Visszaadja az objektumpeldany egyedi azonositojat.
* @return int
*/
public function hashCode() {
if (!$this->hashCode) {
$this->hashCode = rand(1, getrandmax());
}
return $this->hashCode;
}
/**
* Osszehasonlitja parameterek szerint ezt a peldanyt egy masikkal.
* @param self $object
* @return bool
*/
public function equals($object) {
return $object == $this ? true : false;
}
/**
* Ezt az osztalyt stringge alakitja.
* @return string
*/
public function __toString() {
return $this->className() . "@" . base_convert($this->hashCode(), 10, 16);
}
/**
* Megmondja, hogy ez a peldany gyerek-osztalya-e egy masiknak.
* @param string $class
* @return bool
*/
public function isSubclass($class) {
return is_subclass_of($this, $class);
}
/**
* Megmondja, hogy ez a peldany az adott osztaly vagy interface peldanya-e.
* @param string $class
* @return bool
*/
public function isInstance($class) {
return ($this instanceof $class ? true : false);
}
/**
* Gondoskodik arrol, hogy csak a PHP\Lang\Clonable interface-t megvalosito
* osztalyok legyenek klonozhatok.
* @throws \PHP\Lang\CloneNotSupportedException
*/
public function __clone() {
if (!$this->isInstance('\PHP\Lang\Clonable')) {
throw new CloneNotSupportedException();
}
}
/**
* Ez a fuggveny akkor hivodik meg, ha az osztalyt szerializaljuk.
* Azt szeretnenk, hogy ha csak a \PHP\IO\Serializable interface-t
* megvalosito osztalyok lennenek szerializalhatoak.
* @throws \PHP\IO\NotSerializableException
*/
public function __sleep() {
if (!$this->isInstance('\PHP\IO\Serializable')) {
throw new \PHP\IO\NotSerializableException($this->className());
}
}
/**
* Ez a fuggveny akkor hivodik meg, ha az osztalyt unszerializaljuk.
* Azt szeretnenk, hogy ha csak a \PHP\IO\Serializable interface-t
* megvalosito osztalyok lennenek szerializalhatoak.
* @throws \PHP\IO\NotSerializableException
*/
public function __wakeup() {
if (!$this->isInstance('\PHP\IO\Serializable')) {
throw new \PHP\IO\NotSerializableException($this->className());
}
}
}
Akkor most lehet engem bunkósbottal kergetni, megvalósítottam a Java.Lang.Object
osztályt PHP-ban. Elképzelésem szerint Zendék is szeretnének majd egyszer valami hasonlót alkotni, csak hát amolyan Zend-módon kicsit elcseszve, kicsit rosszabbul. Hogy miért gondolom ezt, arra mindjárt kitérek.
Ahhoz, hogy ez az ördögfajzat működni tudjon, szükség lesz még egy Exception
osztályra is. Szerencsére a névtereknek köszönhetően tudunk trükközni és lehet Exception
az osztály neve:
<?php
namespace PHP\Lang;
/**
* Ez a generikus kivetel osztaly
*/
abstract class Exception extends \Exception implements \PHP\IO\Serializable {
/**
* Ez tarolja a peldany egyedi azonositojat. A hashCode() fuggvenybol kell
* kiolasni az erteket.
* @var int
*/
private $hashCode;
/**
* Konstruktor
*/
public function __construct($message = '', $code = 0, Exception $previous = null) {
parent::__construct($message, $code, $previous);
}
/**
* Destruktor
*/
public function __destruct() {
}
/**
* Visszaadja a kurrens peldany osztalyanak a nevet.
* @return string
*/
public final function className() {
return get_class($this);
}
/**
* Visszaadja az objektumpeldany egyedi azonositojat.
* @return int
*/
public function hashCode() {
if (!$this->hashCode) {
$this->hashCode = rand(1, getrandmax());
}
return $this->hashCode;
}
/**
* Osszehasonlitja parameterek szerint ezt a peldanyt egy masikkal.
* @param self $object
* @return bool
*/
public function equals($object) {
return $object == $this ? true : false;
}
/**
* Ezt az osztalyt stringge alakitja.
* @return string
*/
public function __toString() {
return $this->className() . "@" . base_convert($this->hashCode(), 10, 16);
}
/**
* Megmondja, hogy ez a peldany gyerek-osztalya-e egy masiknak.
* @param string $class
* @return bool
*/
public function isSubclass($class) {
return is_subclass_of($this, $class);
}
/**
* Megmondja, hogy ez a peldany az adott osztaly vagy interface peldanya-e.
* @param string $class
* @return bool
*/
public function isInstance($class) {
return ($this instanceof $class? true : false);
}
/**
* Szerializalasban segit. Elvileg nem kellene, de hat az interfesz
* kotelez minket.
* @return array
*/
public function __sleep() {
return array(
'message',
'code',
'file',
'line'
);
}
/**
* Szerializalasban segit. Elvileg nem kellene, de hat az interfesz
* kotelez minket.
*/
public function __wakeup() {}
}
Na és akkor itt mindjárt ki is bukik a dolog egyik rákfenéje. Többszörös öröklődés ugyanis a Javahoz hasonlóan nincs, valamint nem létezik Throwable
interfész sem, amitől Exception
stílusban hasznosíthatóvá válna egy tetszőleges osztály. Innentől kezdve persze újra kell implementálni az Object
osztály összes tulajdonságát is.
A dolog másik, sokkal súlyosabb buktatója (amibe Zendék is bele fognak futni), hogy ha egy Exception
-t próbál az ember klónozni, akkor az azonnali hatállyal fatal error
-ral elszáll. Ezzel füstbe is ment az a terv, hogy dobjunk rá Exception
-t, ugyanis nem lehet. Na és akkor visszatérnék a Zend-féle tákolás fejlesztés hiányosságára: addig, amíg a nyelvből nem takarítják ki ezeket az apró, de bosszantó inkonzisztenciákat, ők sem fogják tudni ezt a nagyvolumenű tervet megvalósítani. Persze a kérdés az, hogy vajon lesz-e elég energiájuk felnőni a Javahoz és kihasználni azt, hogy a bérelt tárhelyes szektorban gyakorlatilag egyeduralommal bírnak.
Ha valaki szeretne játszani a projekttel, letölthető a teljes forráskód phpUnitos tesztekkel, 100% kódlefedettségel. :) Köszönöm Tyrael segítségét a kód bugmentesítésében.
■
az alapötlet jó
Szívesen látnék - az Array-hez hasonló - típus-osztályokat azzal az extrával, hogy minden a tipusra használható függvény már metódus formájában is elérhető legyen (következetesebb paraméterezéssel, mint most (lásd: str_*(); függvények)). Azt hiszem az Array osztályban nincs benne minden.
Viszont nem szeretném, ha a PHP-ból egy lassú csillagromboló válna. Nem szeretném, ha erősen tipusos lenne, pont jó ez a tipusok közötti átjárás, de ahol kell, ott lehessen megkövetelni a tipust, pl.:
( Logikai buktató, hogy a var_dumpot nem tudtam hova helyezni :D )
ArrayObject
igen, néztem
- nincs minden array_* függvény metódusként implementálva
- ha deklarálok, nem lesz automatikusan ArrayObject
Nem tudom biztosra, de azt hiszem, hogy a $tomb[] = "fityfene"; se működik ArrayObject-tel.
- nincs minden array_*
a fontosabbak meg vannak, a tobbit meg tudod csinalni te, vagypedig a __call fuggvenyen keresztul bemappelheted a nativ array fuggvenyekre
ezt nem ertem
array(1,2,3) helyett new ArrayObject(array(1,2,3)) -t kell irnod, nem tragedia.
pedig mukodik...
Tyrael
Csak a cím rossz.
Tervezetlenseg
- Minek? Ott van mar a Java. Mostani projektemen is mar elgondolkoztunk parszor, hogy nem biztos, hogy PHP-ben kellett volna ezt elkezdeni.
- Olyan nagy merteku torest jelentene a nyelv eleteben, hogy nagyon csunyan torne a visszafele kompatibilitast. Ez egy programozasi nyelv eseten szvsz. elfogadhatatlan.
- Komolyan vehetoseget erosen rontja, hogy neha x.y.z+1 verziokban kepesek modositani egy-egy fuggveny viselkedesen.
- Tovabba kismillio helyen leri a nyelvrol, hogy atgondolatlan. Ezer helyen leirtak mar, nem irom le ujra.
- Agyserult modon torteno otletmasolasok. __set()/__get() szvsz. okorseg. Egy .NET szeru property kezeles sokkal jobb lenne.
- Bugos. De alapveto dolgok. Es raadasul nem is nagyon akarnak foglalkozni egyes bugokkal. Pl. belefutottam abba a bugba, hogy a CRC32 nem elojeles int -t hasznal 64 biten, hanem valamilyen long -t. Ezt nem is akarjak javitani, helyette workaroundoljuk meg hexa string-l. Hat kossz, ez nem megoldas. Vagy pl. orvendetes, hogy PHP 5.3-ra megoldottak, hogy menjen a $classname::function(), ami PHP 5.2 alatt meg parse errort adott, csakhogy azota elrontottak azt, hogy call_user_func() -l statikus metodust meg lehessen hivni, ha ki van kenyszeritve a fuggvenydeklaracioban a referencia szerinti atadas. Erre jon a masik kedvencem, a ne duplikalj bugreportot, persze, hogy minek a duplikatuma az sose derul ki. Ha meg megis van valodi duplikatuma (sokszor nincs), akkor azzal se foglalkoztak meg/nem akarnak. Helyette inkabb masoljak a Java-t (bugosan) tovabb. De ezt is reggelig lehetne folytatni.
Mondjuk szemelyes kulon kedvenc a gyenge tipusossag. Szerintem egy programozasi nyelv nem programozasi nyelv tipusok nelkul. (Jo, ertem en, hogy a "tipus, csak illuzio", de attol meg jo dolog :)
Igazabol egyre kevesbe ertem
nem konkretan a java-t masoljak, ha igy lenne, akkor legalabb konzisztens lenne a nyelv, meg ha bloat is.
hat, igazabol masfele mar nem nagyon tudnak fejlodni.
nem feltetlen a kalapacs hibaja, hogy te mindent szognek nezel. :)
azert eleg keves olyan elterjedt nyelv van, amelyik ne valtozott/fejlodott volna az evek soran.
a php3 es 4 kozott eg es fold volt, ugyanigy a 4 es 5 kozott.
de nem a php az egyetlen nyelv, a "konkurencia" a ruby, perl, python ugyanigy nem garantalja, hogy a major verziovaltasnal menni fog a regebbi verziora irt kodod.
Az a baj, hogy az 6-os verzioval nagyon beragadtak a fejlesztok, elkeszult egy csomo feature/bugfix, de evekig rohadt bent a 6osban, ami csak nem akart elkeszulni, ezert bizonyos dolgok elkezdtek beszivarogni a minor verziokkal.
emiatt pl. az 5.1 es az 5.2 eleg sok mindenben elter (lasd migration guide/changelog), pedig csak minor verziougras, valamint az egesz 5.3 ennek koszonheti a letet.
Ja, es az 5.0 pedig sok helyen atgondolatlan, bugos volt, emiatt kellett pl. jopar dolgot 5.1-ben megvaltoztatni.
Ez szerintem pont hogy a tulzott visszafele kompatibilitas miatt van igy, ott van pl. a register_globals safe_mode, vagy a magic_quotes amit mar vagy 5? eve probalnak kiirtani szepen lassan (deprecated majd removed), de most pl. a 6os verzio rebootja miatt megint nem tudni biztosra, hogy mikor fog megszunni a safe_mode es a magic_quotes.
ebbol a szempontbol a magic_method-okat ugy ahogy van faszsagnak tartom, sokkal jobban tetszene egy interface-es megoldas, mint ahogy pl. az spl altal biztositott extrak lettek megvalositva, az is black magic, de egyszerubb megneznem, hogy egy osztaly milyen interface-eket valosit meg, de ez csak az en ket centem.
Mindenesetre a jelenlegi megoldas kozelebb all a php mentalitasahoz, mint a .NET-es property kezeles.
Igy csak egy WTF feature van a nyelvben, nem 2.
Elofordul, bar en inkabb edge case-ekben, meg kevesbe hasznalt feature-okben szoktam ilyesmivel talalkozni.
reportolni kell, ja, es neha tenyleg nagyon lerazosan zarjak a bugreportokat (jani taskien peldaul eleg surun csinal ilyet), pl:
http://bugs.php.net/50255
ilyenkor vallalni kell, hogy esetleg meg nagyobb hulyet csinalsz magadbol, es reklamalni kell, altalaban ez eleg ahhoz, hogy rendesen megnezze valaki a bugot, de ha nincs reakcio, akkor meg lehet keresni emailben a ticketet lezaro fejlesztot, vagy rakerdezni a php-internals-on, hogy mivan.
Szerintem fejlesztesi tempon gyorsit a gyenge tipusossag, illetve a type juggling, de konyebb igy erdekes, nehezen reprodukalhato hibakat csinalni.
Viszont nem ertek egyet vele, hogy minden alkalmazasnak es programozonak szuksege lenne erosen tipusos nyelvre, ergo nem hiszem, hogy nincs letjogosultsaga a gyengen tipusos nyelveknek.
Sot, igazabol a PHP terjedesenek egyik fo oka imho, hogy menedzselt, gyengen tipusos scriptnyelv.
Kb. 0 szaktudassal be lehet uzemelni egy lamp stacket, nem kell a fejlesztonek bonyolult IDE-t megtanulni hasznalni(forditashoz, debugolashoz) ha nem akar, egyszeruen egy notepadbol megirhato a kod, egy ftp-vel felrakod, es mukodik.
nincs bonyolult deploy procedure (ha nem akarod).
Csak mondjuk ezek olyan elonyok, amik a jo fejlesztonek inkabb hatranyok.
Tyrael
A gyenge típusosság
;-)
az elejen jo dolog, mert
aztan egyszer belefutsz egy olyanba, hogy
"0" == false // true
0 == "false" // true
0 == false // true
DE
"0" == "false" // false
akkor majd lehet hogy elgondolkozol rajta, hogy biztos, hogy jo otlet-e ez.
Tyrael
visszafele kompatibilitás
Én speciel örülnék ennek a törésnek, ha ez tényleg azért következne be hogy végleg kigyomlálják a hülyeségeket, régi függvényeket (pl 3X dátum függvény mikor ott van a Dátum osztály(ok)). De amíg ez nincs addig tényleg csak foltozgatás toldozgatás az egész.
szemely szerint egyetertek,
Tyrael
Re
Ezzel az erovel egy kovetkezo projektnel mondhatnam azt is, hogy nem fogom PHP-ben elkezdeni, mert fene tudja, hogy nem kapok a projekt kozepen egy eleg brutalis modositasi kerelmet :)
Mondom, nem ezekkel van a bajom. Altalaban nalunk ugy nez ki, hogy meghatarozzuk, hogy meghatarozunk egy verziot, hogy mire fejlesztunk, aztan az lesz a vegleges kornyezetben is (mostansag 5.2, bar az egyik gepen mar tesztelgetem az 5.3 hulyesegeit is). A problemam azzal van, hogy pl. 5.2.3->5.2.4-re modositanak egy fuggveny mukodesen. Nem kene...
Ezt en ertem, de ettol meg szamomra szimpatikusabb az a hozzaallas, amikor valamit elkeszitenek egyszer, es az utana egy fix stabil alap. Releasek meg kiszamithato idokozonkent vannak. Ertem en a bazari modelnek es a RERO-nak is az ertelmet, de vannak dolgok, ahol egyre kevesbe szimpatikusak.
Eszrevettem :) Igazabol nem lenne vele bajom, ha legalabb normalisan megindokolna es nem fogna lezarna valami semmitmondo uzenettel.
Osszessegeben szerintem nem gyorsabb. type juggling valoban hasznos tud lenni, valoban egyszerubb, mint mindenhova egy Convert.ToInt32(), de nagyon veszelyes tud lenni.
Amiben viszont lassitani tud, meghozza nem keveset az nagyobb, komolyabb OOP-vel megtamogatott, tobb emberes projekteknel van. Nezzunk pl. egy trivialis osztalyt:
Hatjo, egeszitsuk ki a tipusokkal, PHPDoc-ban:
Tapasztalataim szerint mar az is marha sokat szamit, hogy hogy nevezem el a fuggvenyeket. Sajnos egyik projektunkben kisse ossze lettek keverve az elnevezesi konvenciok. Gyk. idoben merheto volt, mikor az Eclipse altal felajanlott listaban kotortan a metodus nevet, mert azt hittem, hogy a masik konvencio alapjan lett megirva.
Osszehasonlitasnak egy .NET -s peldat azert hoznek:
Igen, el kellene mar donteni, hogy akkor mit akarnak a fejlesztok. Nekem ugy tunik, hogy inkabb a jo fejlesztoket celozzak meg, de ehhez kicsit gatyaba kellene razni a nyelvet.
Nincs jobb?
Tudsz jobbat?
:-)
Azért mert
Én örülnék, ha a PHP helyett a Java élvezne ilyen támogatást a hoszting piacon, azzal együtt, hogy nem a kedvenc nyelvem.
Hidd el én is. :-) Php-t
Php-t kezdőként tényleg könnyebb tanulni, mint java-t, asszem 4 éve kezdtem el php-vel foglalkozni, szerintem akkor még nem ment volna a java, hamar feladtam volna. Php-hez nem feltétlen kell OO szemlélet, aztán azért könnyebb.
Viszont én a helyükben nem erőltetném ezt a java-hoz hasonulást, pont amiatt, hogy a php-t használók 99%-ának egyszerűen nincs szüksége további bonyolításra, komplexebb programokat meg egyszerűen nincs értelme php-ban írni, nincsenek megfelelő eszközök hozzá. Szóval szerintem értelmetlen, amit csinálnak, mert nem az a piacuk, és a java vagy c# piacára semmi esélyük betörni.
Milyen komplexebb programokra
Én nem azt mondtam, hogy
Hosting
A php az php
A php egy szerver oldali script nyelv, a java objektumorientált programozási nyelv. (köszi a wikipediának a szép kifejezésért)
Kb. 8 éve dolgozom php-val és nagyon elégedett vagyok vele. Agilisan lehet fejleszteni benne, gyakorlattal és józan paraszti ésszel bármit meg lehet oldani vele. Eddig nem találkoztam olyan feladattal, amit ne tudtam volna megvalósítani vele. Gányolás nélkül is, okosan, rendszerben gondolkodva. A php a gyurma, amiből bármit ki lehet alakítani.
Ne próbáljuk az almát összemérni az körtével. Mert az egyik alma a másik körte.
Lájk
Üdv:
Gábor
Egyetértek!
Azért valamilyen szinten összehasonlítható
A lényeg, hogy nincs kikövezett út, az adott probléma ismerete nélkül nem lehet kijelenteni, hogy webes fejlesztésekre java, asp.net, PHP, Pyton, asm, vagy ruby lenne az ultimate megoldás. Annyira utálom, hogy közhelyeket kell írogatnom, de attól még, hogy valami közhely, attól még igaz.
Szerintem - egyelőre - nincsen hype
Ha Thomas írásában a "bármit meg lehet oldani vele" részt kicseréled mondjuk "a legtöbb dolgot meg lehet oldani vele"-re, akkor már nem is olyan túlzó, és mindjárt nem kerül szóba a hype és a vallás.
Szerintem nem arról van szó, hogy nincsenek bizonyos esetekben használhatóbb eszközök (természetesen vannak), hanem inkább arról, hogy a PHP azért a sok – többnyire hasznos - változás közben őrizzen meg valamit az eredeti jellegéből, különben már JHP (Java Hypertext Preprocessor) lesz belőle. :)
a PHP azért a sok – többnyire
Jah, pont ezt akartam feljebb megfogalmazni, csak valahogy nem ment át.
azt azert tudjuk, hogy vannak
amit nem szeretek, az az, ha valaki zsigerbol azt allitja, hogy nagy terhelesu, es vagy rendelkezesreallasu rendszert nem lehet PHP-ban megcsinalni.
illetve a masik veglet, mikor valaki azt irja, hogy azert lehet mindent PHP-ban megcsinalni, mert eddig o mindent meg tudott PHP-ban valositani.
egyszeruen fel kell ismerni, hogy meg mindig a feladathoz valasztjuk az eszkozt.
Tyrael
a masik veglet, mikor valaki
Pedig ez egy proof-of-concept érvelés legalább. :)
Sokmindent meg is lehet csinálni PHP-val, csak nem biztos, hogy érdemes.