-
De cand a fost lansat PHP 5.3 anul trecut m-am intrebat daca Zend vor introduce si o certificare ZCE aferenta acestei versiuni.
Se pare ca o data cu abandonul versiunii PHP 6 cu ceva timp in urma directia a fost catre o certificare pentru PHP 5.3.
Perioada cred ca nu a fost intamplatoare avand in vedere ca se apropie Zend Con, cea mai mare conferinta PHP.
Ce este nou?
Diferentele de la PHP 5 la PHP 5.3 se gasesc in manual aici.
Cateva mai importante:
Materiale
Programa pentru examen se gaseste pe site-ul Zend.
Dupa ce la certificarea pentru Zend Framework am vazut ca exista un guide complet gratuit pentru membrii inregistrati, ma intrebam de ce nu exista asa ceva si pentru aceasta certificare. Se pare ca acum exista: Zend-PHP-5.3-Study-Guide-v1-3.pdf, in versiune beta! Si este gratuit!
Evident cel mai important material ramane manualul PHP, pentru ca ghidul se foloseste impreuna cu acesta.
Se pare ca nu mai exista mock tests, cum nu au existat nici pentru certificarea de Zend Framework.
Pret
Pretul se pare ca a mai crescut, nu mai este 160$ ci 190$! Pretul oricum ramane unul foarte mic avand in vedere ca un examen la Sun era 200$, iar acum 300$ la Oracle.
Persoanele care au deja o certificare PHP au un discaunt de 20% pana la finalul anului, deci daca esti deja certificat vei plati 152$.
Mult succes!
-
CodeIgniter este un framework open-source scris in PHP care se bazeaza pe principiul RAD.
Cartea CodeIgniter 1.7 de la PacktPublishing, scrisa de Jose Argudo Blanco si David Upton urmareste formarea unei imagini de ansamblu asupra framework-ului CodeIgniter, venind in completarea manualului.Cartea nu este o referinta, iar acest lucru este evident in fiecare capitol cand se foloseste una dintre facilitatiile framework-ului, cititorul este mai apoi directionat catre pagina din user guide sau wiki care corespunde modulului respectiv. Ba chiar mai mult exista si sugestii catre module alternative care realizeaza aceeasi sarcina.
Autorii sustin ca pentru a citi aceasta carte sunt necesare doar cunostinte minime de PHP, o promisiune destul de greu de respectat dupa parerea mea, in general cartile care au ca target cititorii incepatori-medii sustin acest lucru. Spre surprinderea mea au avut dreptate, cititorul are nevoie doar de cunostinte de PHP4. Iar cand vine vorba de OOP nici macar nu sunt necesare cunostinte de PHP5 ci pur si simplu modelul obiectual din PHP4. In carte exista chiar si explicatie pentru copierea prin referinta! Evident copierea prin referinta nu mai este relevanta in PHP5, dar avand in vedere ca este un framework de PHP4 probabil ca trebuia mentionata. Se pare ca inca mai exista servere de PHP4 pe internet… pur si simplu trist…
Citind cartea au inceput sa-mi vina flashback-uri cu bucati de cod scrise direct in PHP si chinul de a face debugging pe ele, incercand sa inteleg munca altora… ce vremuri… groaznice desigur. Explicatia mi se pare foarte buna pentru a intelege concenptul de refolosire din spatele unui framework: “Possibly you like typing regex. Some people like lying on a bed of nails…”. Cred ca pentru un programator, in special incepator, sa citesti asa ceva te face sa realizezi ca nu trebuie sa reinventezi roata de fiecare data ci pur si simplu sa folosesti solutii gasite de altii.
Comparatia intre solutii, cred ca este cea mai amuzanta parte dintr-o carte de acest gen. Este greu sa compari de exemplu Zend Framework sau chiar CakePHP cu CodeIgniter. Pana la urma fiecare din framework-uri spun acelasi lucru, descarci si incepi sa lucrezi. Eu personal cand vreau sa folosesc un modul din Zend pur si simplu incarc autoloader-ul si trec la treaba. Din comparatie rezulta cum era de asteptat ca CodeIgniter este cea mai potrivita in general, motivatia sa spunem ca este relativ buna si destul de cinstita. Pana la urma este un framework mic si nu are facilitati complexe cum ar fi generare automata de CRUD. Imi amintesc de o carte de Java unde autorul prezenta faptul ca C++ este mai rapid decat Java ca pe un dezavantaj, evident este ridicol.
Am avut de cateva ori impresia ca exprimarea este gresita. Autorul se foloseste de “mici” greseli in termeni pentru a explica ce se intampla de fapt in spate. Cand lucrezi cu framework-uri MVC unele lucruri sunt simple si evidente, dar pentru un programator care nu este familiar cu notiunile sunt destul de greu de inteles.
Iar ca sa continui cu greselile, am gasit cateva in carte. Un moment destul de dificil cand inveti ceva nou. Din fericire sunt destul de evidente pentru ca se concretizeaza in erori, iar daca citesti cartea capitol dupa capitol vei sti ce ai de facut ca sa le repari.
Exemplele mi se par destul de consistente si bine explicata. Cand se introduce o notiune noua aceasta este explicata destul de in detaliu.
Aplicatiile rezultate nu sunt foarte complexe, de exemplu la final nu rezulta o aplicatie complexa cum ar fi cu CMS, mai degraba sunt explicate module si modul de folosire impreuna a acestora. Cititorul la final va trebui sa decida ce si cum va arata aplicatia lui. De exemplu in capitolul 13 se explica paginarea si ordonarea. Cand se face paginarea totul e ok, dar cand se face si ordonarea paginarea incepe sa dea rateuri. Mi-a luat cam 5-10 minute sa remediez problema, dar ar fi fost frumos ca aceasta problema sa fie rezolvata de catre autori.
In ansamblu mi se pare o carte reusita, in special daca nu ai cunostiinte de CodeIgniter, este asa cum o prezinta si autorii, o carte pentru dezvoltatori care vor mai multa productivitate in munca lor sau pur si simplu sunt la inceput si vor sa vada ce unelte exista. Cartea totusi nu prezinta solutii mai complexe cum ar fi un CMS sau un shopping cart ci pur si simplu ce are acest framework de oferit.
Un programator avansat poate intelege din aceasta carte structura framework-ului CodeIgniter, eventual pentru a o compara cu alte framework-uri concutente, fara sa piarda vremea cu exemple complexe si irelevante.
-
Factory method design pattern introdus de GoF (Gang of Four) pe care l-am abordat si eu intr-un blog anterior, are la baza ideea unei metode care genereaza obiecte. In general implementarea este destul de “slaba” pentru ca “factory”-ul este destul de hardcodat (la fel ca mine in blogul anterior).
PHP 5.3 ofera totusi posibilitatea unei implementari foarte interesante folosind “Late static bindings“.
Clasele pe baza carora se vor genera obiectele:
1// clasa abstracta de baza care urmeaza sa fie mostenita 2abstract class Drink { 3 4 // ingrediente 5 protected $ingredients; 6 7 // metoda publica care genereaza bautura 8 abstract public function MakeDrink(); 9} 10 11// o clasa derivata pentru ceai 12class Tea_Drink extends Drink { 13 14 // ingrediente pentru ceai 15 protected $ingredients = array('tea', 'sugar', 'mink', 'water'); 16 17 // generare ceai 18 public function MakeDrink() { 19 20 // fa ceai 21 } 22} 23 24// clasa derivata pentru Bloody Mary 25class BloodyMary_Drink extends Drink { 26 27 // ingrediente Bloody Mary 28 protected $ingredients = array('votka', 'salt', 'tomato juice'); 29 30 // generare Bloody Mary 31 public function MakeDrink() { 32 33 // fa BloodyMary 34 35 } 36}
Idea este de a avea o clasa abstracta care va fi extinsa intr-un mod cat mai simplu pentru a genera noi clase factory.
PHP 5
In PHP 5 clasa ar arata cam asa:
1// clasa Factory abstracta 2abstract class absFactory { 3 4 // numele clasei de baza 5 static protected $base_class = ''; 6 7 // metoda factory 8 public static function getInstance($type) { 9 10 // numele clasei rezultat 11 $class_name = $type . '_' . self::$base_class; 12 13 // se testeaza daca clasa exista 14 // aici se poate adauga si un autoloader eventual 15 if(!class_exists($class_name)) { 16 throw new Exception( 'Class ' . $class_name . ' not loaded!'); 17 } 18 19 // se verifica daca clasa mosteneste clasa de baza 20 if(!is_subclass_of($class_name, self::$base_class)) { 21 throw new Exception( 22 'Class ' . $class_name . ' is not a child of ' . self::$base_class 23 ); 24 } 25 26 // noul obiect 27 return new $class_name; 28 29 } 30 31}
Pentru ca metoda getInstance este statica si proprietatea este statica.
Daca incercam:
1class DrinkFactory extends absFactory { 2 3 static protected $base_class = 'Drink'; 4} 5 6try { 7 8 $obj = DrinkFactory::getInstance('Tea'); 9 10} catch (Exception $e) { 11 12 echo $e->getMessage(); 13}
Output-ul va fi:
1Class Tea_ not loaded!
Din pricina “self”, nu putem apela pur si simplu metoda getInstance() din clasa copil pentru ca valoarea lui $base_class va fi “” in loc de “Drink”, trebuie suprascrisa metoda getInstance(). Lucru prea “complicat”.
O versiune functionala in PHP 5 ar fi:
1class DrinkFactory extends absFactory { 2 3 public static function getInstance($type) { 4 5 self::$base_class = 'Drink'; 6 7 // metoda factory a clasei factory de baza 8 parent::getInstance($type); 9 10 } 11 12} 13 14try { 15 16 $obj = DrinkFactory::getInstance('Tea'); 17 18} catch (Exception $e) { 19 20 echo $e->getMessage(); 21}
Dar nu mi se pare tocmai “elegant”.
PHP 5.3
Aici avem “Late static bindings”, care in principiu este introducerea cuvantului “static”.
Clasa de baza factory arata cam asa:
1// clasa Factory abstracta 2abstract class absFactory { 3 4 // numele clasei de baza 5 static protected $base_class = ''; 6 7 // metoda factory 8 public static function getInstance($type) { 9 10 // numele clasei rezultat 11 $class_name = $type . '_' . static::$base_class; 12 13 // se testeaza daca clasa exista 14 // aici se poate adauga si un autoloader eventual 15 if(!class_exists($class_name)) { 16 throw new Exception( 'Class ' . $class_name . ' not loaded!'); 17 } 18 19 // se verifica daca clasa mosteneste clasa de baza 20 if(!is_subclass_of($class_name, static::$base_class)) { 21 throw new Exception( 22 'Class ' . $class_name . ' is not a child of ' . static::$base_class 23 ); 24 } 25 26 // noul obiect 27 return new $class_name; 28 29 } 30 31}
O schimbare atat de mica permite totusi o clasa factory mult mai “atragatoare”:
1class DrinkFactory extends absFactory { 2 3 static protected $base_class = 'Drink'; 4 5} 6 7try { 8 9 $obj = DrinkFactory::getInstance('Tea'); 10 11} catch (Exception $e) { 12 13 echo $e->getMessage(); 14}
Practic in aceasta varianta nu se inlocuieste decat proprietatea statica relevanta in acest context.
-
Pana la versiunea mult asteptata 6, PHP 5.3 este deja la RC 2.
PHP 5.3 vine cu multe lucruri noi, de fapt sunt atat de multe incat putea sa fie cu succes versiunea 6, dar de ce nu este PHP 6? Pentru ca toata lumea se asteapta ca versiunea 6 sa aiba suport Unicode, iar cand o comunitate de programatori asteapta de mai bine de 3 ani asta, nu poti pur si simplu sa le spui ca te-ai gandit sa lasi suportul pentru Unicode pentru versiunea 7.
Namespaces
Printre noutati se afla si namespaces, mi se pare o idee interesanta dar nu fantastica, initial acestea nu erau pe lista de prioritati pentru ca se considera ca problema lor se poate rezolva relativ simplu folosind prefixuri si clase.
Un exemplu de namespace:
1<?php 2// clasa.php 3 4// definirea namespace-ului, in cazul asta trebuie sa fie prima instructiune din fisier 5namespace teste; 6 7// o clasa cu un conscturctor 8class clasaTest { 9 function __construct() { 10 echo "in constrcutor"; 11 } 12} 13 14// o functie 15function funcTest() { 16 echo "in functie"; 17} 18 19// o constanta 20const CONSTANTA = 'global'; 21?>
Acelasi fisier se mai poate defini intr-un anumit namespace si in felul urmator:
1<?php 2// clasa.php 3 4// definirea namespace-ului 5namespace teste { 6 7 // o clasa cu un conscturctor 8 class clasaTest { 9 function __construct() { 10 echo "in constrcutor"; 11 } 12 } 13 14 // o functie 15 function funcTest() { 16 echo "in functie"; 17 } 18 19 // o constanta 20 const CONSTANTA = 'global'; 21 22} 23?>
Fisierul in care fac testele:
1<?php 2 3// includem fisierul de mai sus 4require('clasa.php'); 5 6$obj = new clasaTest(); // Fatal Error:clasa 'clasaTest' not found in ... 7 8$obj2 = new teste\clasaTest(); // afisaza "in constructor" 9 10// aparent suprascriem constanta 11const CONSTANTA = 'local'; 12 13echo CONSTANTA; // afisaza "local" 14 15echo teste\CONSTANTA; // afisza "global" 16 17teste\funcTest(); // afisaza "in functie" 18 19?>
iar daca vrem sa nu mai folosim operatorul “” si numele namespace-ului:
1<?php 2// trebuie sa fie prima insctructiune 3namespace teste; 4 5// includem fisierul de mai sus 6require('clasa.php'); 7 8$obj = new clasaTest(); // afisaza "in constructor"; 9 10// suprascriem constanta 11const CONSTANTA = 'local'; // Notice: Constant teste\CONSTANTA already defined in... 12 13echo CONSTANTA; // afisaza global 14 15?>
Si acestea sunt functiile de baza, folosindu-le pe acestea o sa ajute portabilitatea, si scalabilitatea. Acum numele de clase si functii nu mai trebuie sa fie unice, trebuie pur si simplu sa fie in namespace-uri diferite.
Functile lambda si “closures”
Cele mai interesante facilitati mi se par functile lambda si “closures”.
Suna cunoscut? Poate pentru ca sunt foarte folosite in JavaScript:
1<script language="javascript"> 2closure = function(text) { 3 alert(text); 4} 5 6closure("hello"); 7</script>
Iar acum in php este posibil:
1<?php 2$closure = function ($text) { 3 return $text; 4}; 5 6echo $closure("hello"); 7?>
Tot la functii lambda si “closures” a mai fost introdus si “use”, care permite folosirea unor variabile din exterior:
1<?php 2$x = 'Claudiu'; 3$closure = function ($text) use ($x) { 4 return $text.' '.$x; 5}; 6 7echo $closure("hello"); // afisaza "hello Claudiu" 8?>
Iar daca in exemplul de mai sus vrem sa modificam variabilele care sunt parametri la “use” nu trebuie decat sa le trimitem prin referinta:
1<?php 2$x = 'Claudiu'; 3$closure = function ($text) use (&$x) { 4 $x = 'utilizator'; 5 return $text; 6}; 7 8echo $closure("hello"); // afisaza "hello" 9 10echo $x; // afisaza "utilizator" 11?>
Iar ca sa luam un exemplu concret unde pot fi utile, sa zicem functia “usort“:
1<?php 2function cmp($a, $b) 3{ 4 if ($a == $b) return 0; 5 return ($a < $b) ? -1 : 1; 6} 7 8$a = array(3, 2, 5, 6, 1); 9 10usort($a, "cmp"); 11 12// este echivalent cu: 13 14$a = array(3, 2, 5, 6, 1); 15 16usort($a, function ($a, $b){ 17 if ($a == $b) return 0; 18 return ($a < $b) ? -1 : 1; 19}); 20?>
Dragut, nu? Cred ca asa se vede si mult mai clar ce se intampla in functie si la ce foloseste aceasta.
De asemenea obiectele se pot comporta ca niste closures folosind noua “metoda magica” __invoke():
1<?php 2 3class testCl { 4 function __invoke() { 5 return "metoda de closure"; 6 } 7} 8 9$obj = new testCl(); // instantiem clasa 10echo $obj(); // o apelam ca pe un closure si afisaza "metoda de closure" 11 12?>
NOWDOC
NOWDOC este similar cu HEREDOC doar ca nu interpreteaza variabilele si caracterele speciale. Cu alte cuvinte HEREDOC era echivalentul ghilimelelor duble, NOWDOC este echivalentul ghilimelelor simple:
1<?php 2 3$var = "5"; 4 5// ghilimele duble 6echo "Valoarea este: $var <br>"; // "Valoarea este 5" 7 8// ghilimele simple 9echo 'Valoarea este: $var <br>'; // "Valoarea este $var" 10 11// HEREDOC 12echo <<<HEREDOC 13Valoarea este: $var <br> 14HEREDOC; 15// "Valoarea este 5" 16 17// NOWDOC 18echo <<<'NOWDOC' 19Valoarea este: $var <br> 20NOWDOC; 21// "Valoarea este $var" 22 23?>
Operatorul “?”
Acest operator a fost putin “inbunatatit”:
1<?php 2// inainte 3echo $_GET['ceva']?$_GET['ceva']:false; 4 5// acum 6echo $_GET['ceva']?:false; 7 8?>
Cu alte cuvinte acum conditia poate fi folosita ca valoare pentru adevarat.
goto
Sincer… nuprea vad de ce era nevoie de asa ceva, dar poate nu e chiar asa rau. Si un mic exemplu:
1<?php 2 3$x = 1; 4 5label1: 6echo "la label1 $x <br>"; 7$x++; 8 9if($x>3) goto label2; 10goto label1; 11 12label2: 13echo "la label2"; 14 15// va afisa: 16// la label1 1 17// la label1 2 18// la label1 3 19// la label2 20?>
Arata mai mult a Basic decat a PHP dar chiar functioneaza.
Mai sunt si alte noutati, am incercat sa le enumar doar pe cele care mi se pare mie mai interesante.
Din pacate toate aceste lucruri nu vor ajunge sa fie folosite cu adevarat pe scara larga decat poate peste 2-3 ani, sau chiar mai mult. Poate nu este PHP 6 dar eu cred ca toate schimbarile vor fi mai degraba asociate cu PHP 6 decat cu PHP 5, nu cred ca vrea nimeni sa riste o intreaga aplicatie care foloseste namespace-uri sau closures pentru ca nu este versiunea “noua” de PHP 5.
-
Este decembrie, frigul a venit, vitrinele magazinelor sunt pline de decoratiuni de Craciun iar PHP6 inca nu este aici… poate anul viitor…
Se pare ca versiunea 4 a fost cea mai populara versiune de PHP, PHP5 a avut viteza cea mai mica de penetrare in piata iar PHP6… cea mai asteptata.
Dupa cum sunt schitate lucrurile, PHP6 nu o sa aduca o schimbare atat de mare cum au adus versiuniile precedente, mai degraba o sa aduca schimbari calitative, probleme vechi vor fi rezolvare, REGISTER GLOBALS o sa dispara de tot, la fel si Magic Quotes, care nu este o problema atat de mare de securitate cat de performanta. Vechea si alta data populara gama de functii ereg vor disparea in favoarea preg, aceasta din urma fiind mult mai rapida. Pe de alta parte, cel mai mare avantaj o sa fie suportul pentru Unicode.
Pana atunci exista totusi versiunea de test, iar versiunea finala initial se credea ca o sa fie lansata in 2007, iar acum la finalul lui 2008 este inca in lucru.
Dar intre timp pe 4 decembrie pe site-ul PHP.net, a fost lansata versiunea 5.2.7. Totul bine si frumos, pana pe 7 decembrie cand a fost retrasa pentru ca Magic Quotes nu mai functiona. Sfatul era asteptarea versiunii 5.2.8. A doua zi aceasta a fost lansata, oricum nu cred ca cineva care se grabea sa faca update folosea si Magic Quotes pe on.
Iar acum ma retrag in liniste sa o astept… poate anul viitor…