___ ___ ____ ___ __ _______ __ __ ______ | | | | | ; | | | |___ | |___ | | | .------. | | .- ---' , '-----'------'-----'--- ----'------- - -- - - - - ' _|________|__ ¦ | mkd.08 PHP 5 : aka 'OO in a webserver near you' ' _ ___ __ ____ : | | '-----.------- .-----.------.-----| |----- - ------- - - - ---- - - - ____| |____ |______| ____| |____ | | | | |___ _ ________ ___|___ ____|_________ _______ | ! Disclaimer : BOF ! 1: Si vous aimez ASP vous pouvez faire pagedown 7x des maintenant.. ou vous suicider :) 2: Si vous ne connaissez rien à PHP, envisagez les options précédentes. 3: Tout comme les libéraux, je ne suis responsable de rien... bon.. même pas des fautes cé clair ? :p 4: Cet article est à sont meilleur dans notepad version 5.1 (Build 2600xpsp2.030422-1633: Service pack 1) ! Disclaimer : EOF ! Intro ----- PhP est à mon avis un des plus bel exemple de réussite dans le monde de l'open source. Et avec l'arrivée de la version 5, ca ne fait que s'améliorer. J'ai attendu avec impatience cette version depuis qu'ils ont commencer à l'annoncer. Mais j'ai craqué avant :| j'ai downloadé et installé le beta 1, mais ne trouvant pas vraiment de documentation sur le net et manquant cruellement de temps, j'ai laissé tomber assez rapidement.. Mais alors que le RC2 (Release Candidate #2) venait de sortir, j'ai eu la surprise de ma vie quand j'ai vu dans la librairie un livre de 918 page portant sur PHP5 .. 3ieme édition ... c'est dans ses moment, qu'on se sent retardé :-/ L'auteur est Leon Atkinson des éditions CampusPress Référence. Je dois admettre que j'ai sauter quelques chapitres qui me touche moins. En général le livre est bien expliqué et complet. Dans cet article, je prends pour acquis que vous avez une base en PHP4. Dans le cas contraire, si vous savez programmer, vous devriez vous débrouiller assez bien quand même. Sinon envisagez de nouveaux la solution de l'option #1 du disclaimer. Trève de plaisanteries Dans le but de sauver un peu de temps, je vais éviter de parler des trucs déjà présents dans PHP4, je me concentrerai plutôt sur les nouvelles features :) De plus, je suis nouveau dans le monde de l'Object Oriented, alors c'est possible qu'il y ait quelques erreurs. L'interface OO de PHP4 était peu attrayante, mais m'a permis d'en comprendre les bases. J'ai toutefois pas trop pousser, car je savais que celle de PHP5 serait différente et meilleure en beaucoup de points. Je crois que j'ai eu un timing parfait de ce coté :) Core ---- Bon, je vais faire mon possible pour décrire la nouvelle interface objet de php5, mais se sont à peu près tous des principes nouveaux. J'espère seulement ne pas être dans l'erreur. L'auteur d'écrit l'interface comme étant à héritage simple avec possibilité de limiter l'acces aux membres et de surcharger des classes. Pour moi ca veut pas dire grand'chose :O Mais bon, un coups décortiqué, c'est un peu moin pire. Parmis les changements importants apportés à l'interface OO, il y a la possibilité d'accèder les membres d'une classe sans l'instancier de la façon suivante; Ils ont aussi introduit des namespaces pour remplacer (même s'il est encore supporté) le contreversé $this-> .. Maintenant, on peut y arriver de cette façon; L'une des plus grandes améliorations apportées au modèle objet de php est qu'il ne passe plus les objet par copie, mais par référence (avant on devait utiliser un & pour le faire..). Ce qui entraine une grande diminution des ressources requises pour manipuler les gros objets. De plus, il est possible de restreindre la portée des membres d'une classe. Pour ce faire, php nous fournit des types d'accès. - Public : Accessible sans contraintes par des éléments extérieurs de la classe - Private : Les membres privés sont accessibles en lecture/écriture seulement par les membres d'une meme classes - Protected : Ne peut être manipulé que par les membres dérivés de la classes (a mi-chemin entre public et private..) Ce mécanisme aide à encapsuler et sécuriser l'accès aux membres d'une classe. Comme on peut le voir dans l'exemple suivant: test(); } private function test() { return "hello :>"; } } class maSubClass { __constructor() { echo parent::Test(); # ne fonctionnera pas echo parent::touchTest(); # va fonctionner.. } } ?> Il est aussi possible de déclarer les membres d'une classe comme étant "static", ce qui a pour effet que d'une instance à l'autre la function ou la variable déclarée statique ne change pas. Un peu comme une variable globale, mais à l'intérieur d'une classe ou d'une fonction. C'est applicable aussi aux variables.. une variable static .. paradoxale :) Ca devient une pseudo constante ? :pp count = $this->count++; } __destructor() { echo $this->count(); } } # Il peut être employé seul ou couplé avec un type d'accès. # (l'ordre a de l'importance!) static public maFunction() { ... } ?> PHP a introduit aussi un mécanisme appelé type hint qui permet de spécifier le type d'argument passé à une fonction. Vous pouvez spécifier des "integer", des "array", des "objects".. Par exemple on peux exigner qu'un objet soit un dérivé d'un autre objet pour être accepté par la fonction, ou encore on peut exiger qu'il soit un entier ou un tableau. Si la variable $blah n'est pas dérivée de la classe maClasse, php déclenchera une erreur fatale. La même chose se produira si $num n'est pas un nombre entier. Vraiment pratique :) Surtout que j'étais du genre à vérifier exhaustivement mes types d'entrées avec des fonctions comme is_numeric. avec p. Avant, on pouvait créer une classe avec une fonction qui portait le même nom. Ceci avait pour effet que cette fonction était appelée à chaque instance crée de l'objet. Avec php5, cette norme est encore supportée, mais ils ont introduit un système de constructeur / destructeur. Il suffit d'ajouter une fonction avec le nom __construct() pour que cette fonction soit appelée à chaque fois que l'objet est instancié. Vous pouvez faire l'inverse (chaque fois que la classe finit sa routine) avec __destruct() pour détruire un objet explicitement. Vous devez affecter une nouvelle valeur (NULL ou unset:p) à toutes les variables qui pointent vers le dit objet. Vous pouvez utiliser ces fonctions comme des fonctions normales, à la seul différence qu'elles ne sont pas héritées par les classes "children", vous pouvez quand même y accèder à partir d'une classe parente comme ceci: parent::__construc(); Une autre function appelée __autoload($class). Elle permet de faire un include dynamique d'une class qu'on a tenté d'instancié, mais qui n'est pas définie. Si la function __autoload($class) est présente dans votre classe, php va la nommer d'après le nom de la classe non définie qui à été appelée, il ne reste qu'à l'inclure.. test(); # php tentera de trouver le fichier bleh.class.php, dans le répertoire local. ?> Php introduit un nouveau système de classe abstraite.. mot assez bien choisi. C'est pas évident de comprendre l'utilité.. Pour simplifier encore un peu la chose, l'auteur semble dire qu'il y a deux synthaxe pour le faire. Je donne un exemple avant d'essayer de l'expliquer. ". $i ."

"; } } class xml extends convertir { public function getOutput($i) { return "". $i .""; } } class deficiante extends convertir{ public function gimmeOutputMan($i) { return "<%". $i ."%>"; } } $HTMLobj = new html; echo $HTMLobj->getOutput("yo"); # retourne

yo

$XMLobj = new xml; echo $XMLobj->getOutput("sa"); # retourne sa $INVALIDobj = new deficiante; echo $INVALIDobj->gimmeOutputMan("sa"); # devrait retourner un erreur. # si j'ai bien compris la même chose serait possible avec les mots "implements" # et "interface" pour remplacer "extends" et "abstract" interface class convertir { interface function getOutput(); } class html implements convertir { public function getOutput($i) { return "

". $i ."

"; } } # Bon, vous voyez le genre :p Y'a une chose que je n'ai pas vue et je me # demande si c'est possible.. Si quelqu'un a la réponse, envoyez-moi un mail ;> class maClasse extends monAutreClass implements monInterface { } ?> Il est imposssile d'instancier une classe abstraite, elle sert seulement de "référence" pour la construction de classes similaires.. Selon l'auteur, pour travailler de façon efficace avec les objets, leur interface doit rester similaire d'une class à l'autres. Si je comprends bien, il faut seulement nommer les function de bases comme ceux pour les entrées/sorties de la class avec le même nom. Les classes abstraites ou interfaces, servent à s'assurer que les class qui l'utilisent répondent à certaines exigeances. J'aimerais être plus sur de moi à ce sujet, mais l'auteur n'est pas clair la-dessus. Son exemple est ambigue.. Mais bon, j'élaborerai peut-être un jours, quand j'utiliserai cette feature la.. Si je comprends bien, c'est surtout utile dans de "vraiments" gros projets ou plusieurs classes similaires doivent être dévloppées par plusieurs personnes.. Donc ca peut prendre un moment avant que ca me soit vraiment utile :) Mais j'ai l'intention de m'en servir pour au moins un de mes projets. Les functions Try, trow et catch C'est un principe nouveau pour moi. Ce que j'en comprends est que c'est un système implanté dans le but d'aider à gérer les erreurs (appelées exeptions) à l'intérieur d'une classe, au lieu d'envoyer un erreur au browser. Je crois qu'il est important de ne pas confondre ces fonctions avec le système d'error handling déjà implanté dans PHP4. Ses fonctions sont utiles dans le cadre d'une programmation OO. Un exemple vaut toujours 4.02387260077094e+2567 mots :p .. Si vous programmez java, vous serez famillié avec ca. morve = $morve; } } # Essayons d'attrapper un rhume. $morve = "jaune"; $morve = "vert"; $morve = "bleu"; $morve = "rouge"; # Si je comprends bien, try sert à contenir les exeptions, dans le livre # l'auteur utilise des if pour déclencher une exeptions, mais je présume # que c'est aussi valide avec un switch.. Le contraire serait vraiment stupide. try { switch($morve) { case 'bleu': throw new rhume("Votre morve est gelée."); break; case 'rouge': throw new rhume("Ce n'est pas un rhume c'est le virus du nil."); break; } echo $morve; } catch(rhume $exeption) { echo "Désolé vous n'avez pas le rhume, car: ". $exeption->morve ."
"; echo "Fichier: ". $exeption->file() .", ligne: ". $exeption->line() .""; } # Cette partie la semble servir a catcher tout les autre exeptions ne se # rapportant pas à rhume. La seule utilité que je peux y voir, c'est un # generic throw catch systeme pour un ensemble de classes. Mais je ne suis # pas certain de comprendre a 100% ce bout-la. catch(Exeption $exeption) { # autre exeption d'intercepté echo "Exeption interceptée dans:"
"; echo "Fichier: ". $exeption->file() .", ligne: ". $exeption->line() .""; } ?> Php supporte une nouvelle méthode pour transformer la nature d'une variable, on appele ca le typecasting , ou le transtypage en français .. urk. Grace à ça on peut transformer une variable string en array, ou object et vice versa.. ca l'air plus compliqué que ca l'est :p En réalité, ca peut être assez pratique.. Surtout pour un peu d'optimisation :> "world","salut"=>"monde"); # en string $str = (string)$array; # va retourner Array # en objet $obj = (object)$array; # $obj->hello va retourner world # en entier $int = (integer)$array(); # va retourner 1 ?> Outro ------ Une chose que je veux eclaircir.. moi et __2 regardant un code php de northox, on se demandait pour quelle raison, apparament illogique, il avait utilisé un OR au lieu d'un || dans une opération if .. La seule chose dont je me rappellait c'etait que les deux étaient valides, mais n'avaient pas la même priorité. J'ai trouvé l'explication plus tard dans mon livre. Voiçi un petit tableau des priorités, lequel est utilisé par le Zend Engine pour déterminer la priorité des opérations (exactement comme un math .. 2 + 2 * 4 = 10). Et à bien y penser c'est logique, l'engine doit savoir dans quelle priorité il doit exécuter les instructions, au primaire on nous montre que la multiplication/division on priorité sur l'addition/soustraction, pour d'autres opérations c'est moin évident.. Les opérateurs et leur priorité.. ------------------------------------ ______________________________________________________________________________ | Priorité Opérateur Opération Associativité | °-----------------------------------------------------------------------------° | 1 ! NON logique Droite | | 1 ~ NON binaire | | 1 ++ Incrémentation | | 1 -- Décrémentation | | 1 @ Opérateur de silence | | 1 (int) Transtypage* vers entier | | 1 (float) Transtypage* vers flottant | | 1 (string) Transtypage* vers chaine | | 1 (bool) Boolean cast | | 1 (array) Array cast | | 1 (object) Object cast | °-----------------------------------------------------------------------------° | 2 * Multiplication Gauche | | 2 / Division | | 2 % Modulo | °-----------------------------------------------------------------------------° | 3 + Addition Gauche | | 3 - Soustraction | | 3 . Concaténation | °-----------------------------------------------------------------------------° | 4 >> Décalage binaire à droite Gauche | | 4 << Décalage binaire à gauche | °-----------------------------------------------------------------------------° | 5 < Plus petit N/A** | | 5 <= Plus petit ou égale | | 5 > Plus grand | | 5 => Plus grand ou égal | °-----------------------------------------------------------------------------° | 6 == égal Gauche | | 6 != n'est pas égal | | 6 === identique | | 6 !== non identique | °-----------------------------------------------------------------------------° | 7 && ET logique Gauche | °-----------------------------------------------------------------------------° | 8 || OU logique Gauche | °-----------------------------------------------------------------------------° | 9 ? : Évaluation conditionnelle Gauche | °-----------------------------------------------------------------------------° | 10 = Affectation de valeur Droite | | 10 =& Affectation d'addresse | | 10 += Addition/affectation | | 10 -= Soustractio/affectation | | 10 *= Multiplication/affectation | | 10 /= Division/affectation | | 10 %= Modulo/affectation | | 10 ^= XOR/affectation | | 10 &= ET/affectation | | 10 |= ET/affectation | | 10 .= Concaténation/affectation | °-----------------------------------------------------------------------------° | 11 AND Et logique Gauche | °-----------------------------------------------------------------------------° | 12 XOR XOR logique Gauche | °-----------------------------------------------------------------------------° | 13 OR OU logique Gauche | °-----------------------------------------------------------------------------° | * typecasting en anglais.. | | ** Non Associatif | °-----------------------------------------------------------------------------° (Il y a une erreur à la page 50, l'auteur utilise "|||" au lieu de "||" dans la colone des opérateurs pour exprimer un "OU" logique :> ) une chose m'à marquer.. le nombre d'encryptations supportés par php :) ______________________________________________________________________________________________________ | Argument Description | °------------------------------------------------------------------------------------------------------° | MCRYPT_3DES Triple-DES | | MCRYPT_ARCFOUR RC4 | | MCRYPT_ARCFOUR_IV RC4 avec vecteur d'initialisation | | MCRYPT_BLOWFISH Blowfish | | MCRYPT_CAST_128 CAST avec la clés 128bits | | MCRYPT_CAST_256 CAST avec la clés 256bits | | MCRYPT_CRYPT Codage standard de crypt() (standard DES) | | MCRYPT_DES DES | | MCRYPT_GOST GOST (algorythme de cryptage soviétique.. dah) | | MCRYPT_IDEA IDEA (International Data Encryptation Algorythme) | | MCRYPT_LOKI97 LOKI97 (128bits) | | MCRYPT_MARS Chiffrement MARS d'IBM | | MCRYPT_PANAMA Panama | | MCRYPT_RC2 RC2 | | MCRYPT_RC6 RC6 | | MCRYPT_RIJNDAEL_128 Rijndael 128bits | | MCRYPT_RIJNDAEL_192 Rijndael 192bits | | MCRYPT_RIJNDAEL_256 Rijndael 256bits | | MCRYPT_SAFERPLUS Secure And Fast Encryption Routine + (?bits) | | MCRYPT_SAFER64 Secure And Fast Encryption Routine (64bits) | | MCRYPT_SAFER128 Secure And Fast Encryption Routine (128bits) | | MCRYPT_SERPENT Serpent | | MCRYPT_SKIPJACK Skipjack (chiffrement du circuit Clipper .. no idea) | | MCRYPT_THREEWAY 3-Way | | MCRYPT_TRIPLEDES Triple-DES (Surement un alias de _3DES ..) | | MCRYPT_TWOFISH Twofish | | MCRYPT_WAKE WAKE | | MCRYPT_XTEA xTEA, extension de Tiny Encryption Algorythm | |_____________________________________________________________________________________________________/ | Mode de cryptage | °------------------------------------------------------------------------------------------------------° | MCRYPT_MODE_ECB Elictronic codebook | | MCRYPT_MODE_CBC Cipher block chaining | | MCRYPT_MODE_CFB Cipher feedback | | MCRYPT_MODE_OFB Output feedback, 8-bit | | MCRYPT_MODE_NOFB Output feedback, variable block size | | MCRYPT_MODE_STREAM Elictronic codebook | | MCRYPT_MODE_STREAM Stram | °------------------------------------------------------------------------------------------------------° C'est pas mal tout le temps que j'avais.. j'aurais aimé couvrir plus de nouveauté, mais bon, je vais laisser de la place à une éventuelle suite :) J'espère que ca vous a aider à comprendre les pincipales différences entre php4 et 5. Quelques éléments que je n'ai pas abordés et que je risque d'aborder dans un prochain article. Si vous avez des demandes spéciales, je vais voir ce que je peux faire. - static & dynamic bindings - overloading - object sérialisation - namespaces .----------------------------------------------- - - --- - --- | h3 [h3 at mindkind dot org] www.mindkind.org '------ -- ----------- -- - - ---------- - - -- - - -- ----- - - - - -