++
# 1
Nouveautés PHP 5.3
« he who doesn't do anything, doesn't go wrong »Zeev Suraski
Cellule PHP R2SC
++
# 2
Introduction
Installation
Nouveautés de PHP 5.3
PHP.next
Sommaire
++
# 3
Objectifs de la présentation d'aujourd'huiNouveautés PHP 5.3
Par rapport à PHP 5.2
Spéculations sur l’avenir de PHPQu’est devenu PHP 6?De quoi sera faite la prochaine version de PHP?
Questions?
Introduction
++
# 4
Versions de PHP4.4.9 : Août 2008 – plus maintenu !
5.0.0 : juillet 2004
5.1.0 : Novembre 2005
5.2.0 : Novembre 20065.2.13 : Février 2010
PHP 5.3Versions « testables » : printemps 2008
1ère version alpha : 1er août 2008
Version 5.3.0 : 30 juin 2009Dernière version : 5.3.2, 4 mars 2010
PHP.next ?Disparition de PHP 6 en mars 2010
On en reparle à la fin de la présentation
Rappel : Historique de PHP
++
# 5
Introduction
Installation
Nouveautés de PHP 5.3
PHP.next
Sommaire
++
# 6
Récupération des sources http://www.php.net/downloads.php
Pour LinuxPHP 5.3 intégré dans les dernières versions d’Ubuntu et Fedora.
Pour windows : http://windows.php.net/download/
Plusieurs versions : Zip contenant les sources compiléesInstalleur windowsDebug Pack
Plusieurs compilations VC9 Thread Safe et VC9 Non Thread Safe pour IISVC6 Thread Safe pour Apache 2 et Apache 2.2 VC6 Non thread Safe pour Apache 1.3
Par contre plus de pecl4win y compris APC, mais on peut trouver quelques extensions :http://downloads.php.net/pierre/
Installation PHP 5.3
++
# 7
En hébergement Mise à jour en cours
Chez OVH, possibilité de switcher entre PHP 5.2 et PHP 5.3Pour cela éditer un fichier .htaccess et ajouter : SetEnv PHP_VER 5_TEST
En LocalPackage tout en un :
WampServerEasyPHPXAMPP
Sur une VM
Avec les outils cités précédemment
Tester PHP 5.3
++
# 8
Exemples et de tests :Couvrant la quasi-totalité des nouveautés de PHP 5.3
Téléchargementhttp://blog.pascal-martin.fr/public/php-5.3/php-5.3-exemples.tar.bz2
Et les applications ? Normalement compatible (attention au fonctions dépréciées)
En pratique peu de Framework ou applications optimisées pour PHP 5.3
A venir : Symfony 2 (PHP 5.3 only)Zend Framework 2.0 (PHP 5.3 only, fin d’année)Doctrine 2 (déjà disponible en bata)
Tester PHP 5.3
++
# 9
Sommaire
Introduction
Installation
Nouveautés de PHP 5.3
PHP.next
++
# 10
Plus « grosse » nouveauté de PHP 5.3
Objectif :Résoudre le problème des noms de classes très longs en PHP
class PHPUnit_Extensions_Database_DB_MetaData_MySQL extends PHPUnit_Extensions_Database_DB_MetaData_InformationSchema
Quelques notes« namespace » doit être la première instruction d'un fichier
Plusieurs fichiers pour le même namespace
Plusieurs namespaces dans un fichier
Mots-clefs« namespace » pour déclarer un namespace
« use » pour utiliser un espace de noms, en spécifiant éventuellement un alias
« \ » comme opérateur de résolution de namespace
PHP 5.3 : Namespaces
++
# 11
Déclarations de fonctions : namespace FWK;// Ce qui est déclaré maintenant l'est dans le namespace "FWK"function a() {echo 'FWK\a'."\n";}function b() {echo 'FWK\b'."\n";}
namespace APP;// Ce qui est déclaré maintenant l'est dans le namespace "APP"function a() {echo 'APP\a'."\n";}
Et à l'utilisation :use APP as APP;
a(); // APP\aAPP\a(); // APP\aFWK\a(); // FwK\a
FWK\b(); // FWK\bb(); // Fatal error: Call to undefined function APP\b()
Intérêt / Idées (Même si ce n’est pas l’objectif de départ !)Séparation des paquets logiciels
Framework dans un namespace, application dans un autre, un namespace par bibliothèque, ...
Namespaces : fonctions
++
# 12
Même chose avec des classesnamespace FWK;class A { public function a() {echo 'FWK\A\a'."\n";}}
namespace APP;class A { public function a() {echo 'FWK\A\a'."\n";}}
Et à l'utilisationuse APP as APP;
$obj = new A();var_dump($obj); // object(APP\A)#1 (0) {}var_dump(get_class($obj)); // string(6) "APP\A"$obj->a(); // APP\A\a
$obj = new FWK\A();var_dump($obj); // object(FWK\A)#2 (0) {}var_dump(get_class($obj)); // string(6) "FWK\A"$obj->a(); // FWK\A\a
Namespaces : classes
++
# 13
namespace NS7; // ns7-1.phpclass A {public static function a() {echo '[' . __NAMESPACE__ . ']\{' . __CLASS__ .
'}\(' . __METHOD__ . ")\n";}}
namespace NS7; // ns7-2.phpclass B {public static function b() {echo '[' . __NAMESPACE__ . ']\{' . __CLASS__ .
'}\(' . __METHOD__ . ")\n";}}
namespace NS7\TEST\GLOP; // ns7-3.phpclass C {public static function c() {echo '[' . __NAMESPACE__ . ']\{' . __CLASS__ .
'}\(' . __METHOD__ . ")\n";}}
// ns7.phprequire_once('ns7-1.php'); require_once('ns7-2.php'); require_once('ns7-3.php');echo NS7\A\a(); // [NS7]\{NS7\A}\(NS7\A\a)
use NS7 as X;//echo B\b(); // Fatal error: Class 'B' not foundecho X\B\b(); // [NS7]\{NS7\B}\(NS7\B\b)
use NS7\TEST\GLOP;echo GLOP\C\c(); // [NS7\TEST\GLOP]\{NS7\TEST\GLOP\C}\(NS7\TEST\GLOP\C\c)
« use » n'importe pas le contenu d'un namespaceDéfinit un alias, c'est tout !
Namespaces : « use » et alias
++
# 14
Ordre de résolutionnamespace NS;function strlen($str) {return "MECHANT";}
// même sans "use", on est dans le namespace NS !echo strlen('glop') . "\n"; // MECHANTecho NS\strlen('glop') . "\n"; // MECHANT
Dans un namespace, la résolution des fonctions, classes, et constantes se fait dans le namespace en premier
Et on remonte à l'espace de nom global si la résolution a échoué dans l'espace de noms courant
Accès direct à l'espace de noms globalUtilisation de l'utilisateur de résolution de portée « \ »
sans préciser de namespace
echo \strlen('glop') . "\n"; // 4
Namespaces : ordre de résolution
++
# 15
Fonction __autoload reçoit en paramètre« Namespace\className »
Ou « className » si pas d'espace de nom précisé
function __autoload($className) { echo "__autoload : $className\n"; $tab = explode('\', $className); require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ns-4-' .
strtolower($tab[0]) . '.php');}$obj = new CC(); // Pas d'appel à __autoload$obj = new A\AA(); // __autoload : A\AA (ok)$obj = new BB(); // __autoload : BB (échec)
class CC { function a() {}}
ExplicationLe nom « interne » de la classe inclut le nom du namespace !
Attentionquid du cas où plusieurs fichiers définissent le même espace de noms ?
Namespaces : __autoload
++
# 16
Espaces\de\nomsPossibilité d'utiliser des noms contenant des « \ »
Permet de dresser une hiérarchie d'espaces de noms
Nouvelle constante magique : __NAMESPACE__
namespace A\B;
class A { function a() {echo __NAMESPACE__ . "\n";}}
$obj = new A();$obj->a(); // A\B
Comparaison avec la notation PEAR / ZendZend_View_Helper_Placeholder_Registry_Exception
Notation qui change : Possibilités d'__autoload restent les mêmes, finalement
Namespaces : sucre syntaxique
++
# 17
Gain de performance globalConstaté en benchmarkant plusieurs logiciels PHP connus et répandus
Gain général entre 5 et 15%Drupal +20%, Typo3 +30%, Wordpress +15%, xoops +10%, Qdig +2%http://news.php.net/php.internals/36484
Détailsmd5 : 10 à 15% plus rapide
Déplacement des constantes vers mémoire en lecture-seule
Amélioration gestionnaire d'exceptions (plus simple, moins de code)
Suppression appel à « open » pour require/include_once
Utilisation de gcc4 pour la compilation
Amélioration perfs / mémoire
++
# 18
Gain jusqu'à 25% sur des applications réelles
Performances
++
# 19
PHP <= 5.2 Références cycliques => non libération de la mémoire
PHP 5.3 : Ajout Garbage Collector Fonctions « gc_* » Activé par défaut
Mais désactivable
Intérêt Faciliter le développement de grosses applications
BatchsApplications basées sur des frameworksPHP-GTK ?
PHP ne sert plus que pour du Web / des scripts légers
GC – Garbage Collector
++
# 20
Rouge : Sans Garbage Collector Bleu : Avec Garbage Collector Attention, ce graphe est un cas d’école : utilisation de références cycliques
GC – Garbage Collector
++
# 21
Bibliothèque spécialisée d'interfaçage PHP <-> mySQLConçue spécialement pour PHP
Perspectives d'évolutions futures facilitées
AvantagesPlus rapide (20-30% plus rapide que libmysql)
Amélioration de l'utilisation mémoire
Capacité de récupération de statistiques, pour tuning de perfs
Driver intégré : pas de dépendance externe
Intégration avec PHPCycle de release + rapide / + facile : MAJ en même temps que PHP
Intégration avec PDO
A privilégier par rapport à libmysql
mySQLnd
++
# 22
class A { public static function __callStatic($name, $args) { echo "__callStatic A::{$name}(" . implode(', ', $args) . ")\n"; } public static function methodS($p1) { echo 'A _methodS('.$p1.')'."\n"; } public function __call($name, $args) { echo "__call A::{$name}(" . implode(', ', $args) . ")\n"; } public function method($p1) { echo "A::method($p1)\n"; }}
Résultat PHP 5.3$obj = new A();$obj->method('param1'); // A::method(param1)$obj->test('param1', 'param2'); // __call A::test(param1, param2)
A::methodS('param1'); // A::methodS(param1)A::test('param1', 'param2'); // __callStatic A::test(param1, param2)
Résultat PHP 5.2Fatal Error : Call to undefined method A::test()
__callStatic
++
# 23
class A { public static function methodS($p1) { echo "A::methodS($p1)\n"; } public function method($p1) { echo "A::method($p1)\n"; }}
Résultat PHP 5.3$className = 'A';$methodName = 'method';$obj = new $className();$obj->$methodName('param1'); // A::method(param1)
$staticMethodName = 'methodS';$className::$staticMethodName('param1'); // A::methodS(param1)
Résultat PHP 5.2Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM
Appels statiques dynamiques
++
# 24
class Vehicule { public static function a() { echo __CLASS__ . "\n"; } public static function b() { //self::a(); // PHP 5.2 static::a(); }}
class Voiture extends Vehicule { public static function a() { echo __CLASS__ . "\n"; }}
Voiture::b();
Résultat PHP 5.3Résolution « tardive » : à l'exécution, et non à la compilation
« Voiture »
Résultat PHP 5.2« Vehicule »
1
2
3 (5.2)
3 (5.3)
Late Static Binding
++
# 25
Ajout de l'instruction « goto »Et de la notion de « label » (étiquette)
echo '<p>a</p>';
goto c;echo '<p>b</p>';
c:echo '<p>c</p>';
A noterPas de saut à l'intérieur d'une boucle / d'un switch
Autorisé à l'intérieur d'un if / else (utilité ?)
Pas de « goto $label; »
Instructions « break » et « continue » non modifiéesSortie de boucles imbriquées : « break 2; »Pas de « break label; »
Saut inconditionnel : « goto »
++
# 26
Depuis PHP 4, syntaxe Heredoc$str = <<<END_OF_STRING<h1>Hello, world!</h1><div> Démonstration syntaxe <strong>$syntaxe</strong></div>END_OF_STRING;
PHP 5.3 ajoute la syntaxe Nowdoc Simple-quotes : pas d'interpolation de variables
$str = <<<'END_OF_STRING'<h1>Hello, world!</h1><div> Démonstration syntaxe <strong>$syntaxe</strong></div>END_OF_STRING;
Doubles-quotes : Identique à HeredocPlus consistant avec Nowdoc simple-quotesMais : deux façons de faire la même chose
Syntaxe NOWDOC
++
# 27
Lambdas et Closures Ceux qui ont fait du Javascript connaitront !
PHP 5.3 introduit les « Lambdas » et « Closures »
Fonction anonyme Création
$func = function () { echo "<p>Hello, World!</p>";};
Appel$func();
Fonction anonyme avec paramètre(s)$func = function ($param) { echo "<p>Hello, $param!</p>";};$func('there');
Appel possible via call_user_func[_array] Fonctions « anonymes », mais fonctions quand même !
++
# 28
« use » : Import d'une variable externe
$var = 'World';$func1 = function () { echo "<p>Hello, $var!</p>";};$func2 = function () use ($var) { echo "<p>Hello, $var!</p>";};
$func1(); // Notice: Undefined variable: var … => Hello, !$func2(); // Hello, World!
Import en lecture-seule Ou par référence : réutilisation de « & »
Import en lecture-écriture
$func2 = function () use (& $var) { echo "<p>Début 2 : $var</p>"; $var = 2; echo "<p>Fin 2 : $var</p>";};
Lambdas et Closures
++
# 29
Lambdas et Closures
Création d'une closure$func = function ($arg) { $compteur = $arg; // Copie privée, en lecture seule return function () use ($compteur) { return ++$compteur; };};$a1 = $func(10);$a2 = $func(50);
echo 'a1 : ' . $a1() . "\n"; // 11echo 'a2 : ' . $a2() . "\n"; // 51echo 'a1 : ' . $a1() . "\n"; // 11echo 'a2 : ' . $a2() . "\n"; // 51echo 'a1 : ' . $a1() . "\n"; // 11echo 'a2 : ' . $a2() . "\n"; // 51
Fonction interne force la conservation de la valeur de $compteur
C'est le principe même d'une closure !Après Javascript, c'est maintenant possible en PHP !
++
# 30
Même chose, en lecture-écriture$func = function ($arg) { $compteur = $arg; // Copie privée, en lecture / écriture return function () use (& $compteur) { return ++$compteur; };};$a1 = $func(10);$a2 = $func(50);
echo 'a1 : ' . $a1() . "\n"; // 11echo 'a2 : ' . $a2() . "\n"; // 51echo 'a1 : ' . $a1() . "\n"; // 12echo 'a2 : ' . $a2() . "\n"; // 52echo 'a1 : ' . $a1() . "\n"; // 13echo 'a2 : ' . $a2() . "\n"; // 53
$compteur conservée par la fonction interne $compteur importée par référence Accessible en lecture-écriture, donc
Comme les closures de Javascript
Lambdas et Closures
++
# 31
Extension « intl » incluse en standard Option –enable-intl Objectif : faciliter l'internationalisation (« i18n ») et la localisation (« l10n ») d'applications
Afficher une date sur un site multilingue : « 31/12/2008 » ? « 2008-31-12 » ? « 12/31/2008 » ?
Et pour une monnaie : « 1,024.12 € » ? « $ 1.024,12 » ?
Plusieurs nouvelles classes IntlDateFormatter NumberFormatter Locale Collator
intl – Internationalisation
++
# 32
Nombres / monnaiesecho NumberFormatter::create('fr_FR', NumberFormatter::CURRENCY)->format(123456789.987654) . "\
n";echo NumberFormatter::create('en_US', NumberFormatter::CURRENCY)->format(123456789.987654) . "\
n";
123 456 789,99 € $123,456,789.99
Datesecho IntlDateFormatter::create('fr_FR', IntlDateFormatter::FULL, IntlDateFormatter::FULL)-
>format(time()) . "\n";echo IntlDateFormatter::create('zh-Hant-TW', IntlDateFormatter::FULL, IntlDateFormatter::FULL)-
>format(time(time())) . "\n";
jeudi 9 octobre 2008 04:21:10 GMT+00:00 2008年 10月 9 日星期四 上午 04時 21分 10 秒 GMT+00:00
Messages$format_FR = 'Le {0,date,full} à {1,time,short}, {2,number,integer} pommes coûtent
{3,number,currency}';$data = array(time(), time(), 5, 3.1415);echo MessageFormatter::formatMessage('fr_FR', $format_FR, $data) . "\n";
Le jeudi 9 octobre 2008 à 04:31, 5 pommes coûtent 3,14 €
Intl – Internationalisation
++
# 33
« PHP Archive » Équivalent des .jar du monde JAVA Regroupement de plusieurs fichiers en un seul Intégré à PHP 5.3 : indépendant de PEAR / PECL
Manipulation de fichiers Phar Inclusion
include 'library.phar'; Ajout d'un stream « phar »
include 'phar:///chemin/vers/monphar.phar/fichier.php'; Inclusion de fichiers packagés au sein d'une Phar
Y compris d'un fichier vers l'autre Manipulation des fichiers à l’aide d’une classe Phar :
$phar = new Phar(__DIR__ . '/application.phar.php'); $phar->addFile('index.php'); $phar->addFile('included.php');
Exemples de possibilités Distribution d'une application entière en un seul fichier
Pour les application CLI, et pour les applications Web !Comme installeur ?
Framework et bibliothèque packagé en un seul fichier
PHAR – PHP Archive
++
# 34
Ajout de la constante magique __DIR__Indique le répertoire du script
echo dirname(__FILE__) . "\n"; // PHP 5.2echo __DIR__ . "\n"; // PHP 5.3
Avantage : évalué à la compilation, et non à l'exécution
Nouvelles fonctionnalités SSLObjectif de départ : implémentation d'openID en PHP
Support de configuration par répertoirePar fichiers .ini
Pour ce qui est CGI / FastCGI
A la manière des .htaccess de Apache
Améliorations apportées à getopt()Support de windows
Support cross-platform des options longues (de la forme --option)
Implémentation native indépendante du système
Nouveautés « diverses »
++
# 35
Ajout de l'opérateur ?:Récupération de la valeur non vide parmi deux valeurs / expressions
var_dump(true ?: false); // bool(true)var_dump(false ?: true); // bool(true)var_dump(1 ?: 0); // int(1)var_dump('glop' ?: ''); // string(4) "glop"var_dump(array(10) ?: array()); // array(1) {[0]=>int(10)}var_dump(strlen('glop') ?: strlen('')); // int(4)var_dump(isset($a) ?: 10); // int(10) ; avec $a non setvar_dump(isset($b) ?: 10); // bool(true) ; avec $b set
Attention si deux valeurs fausses :var_dump(isset($a) ?: ''); // string(0) ""var_dump('' ?: isset($a)); // bool(false)
Ajout de fonctionnalité de profiling XSTL
Mode E_DEPRECATEDPremière victime : ereg
Améliorations SPLAjout GlobIterator
Ajout de classes gérant des structures de données : SplStack, SplQueue, SplHeap, SplDoublyLinkedList, ...
Nouveautés « diverses »
++
# 36
Améliorations extension DateAjout date_create_from_format
$ts1 = strtotime('25/04/2008 13:30:00');var_dump(date('Y-m-d', $ts1)); // string(10) "1970-01-01"
$date = date_create('25/04/2008 13:30:00');var_dump($date); // bool(false)
$date = date_create_from_format('d/m/Y H:i:s', '25/04/2008 13:30:00');var_dump($date->format('Y-m-d')); // string(10) "2008-04-25"
Ajout date_get_last_errorsMais messages d'erreurs d'une utilité toute relative :-(
Nouveautés « diverses »
++
# 37
Introduction
Installation
Nouveautés de PHP 5.3
PHP.next
Sommaire
++
# 38
HistoriqueEn développement depuis 2006
Objectif principal : Intégrer l’unicode à PHP
Objectif secondaire : nouveautés diversesNamespaces, LSB, etc.
Devait succéder à PHP 5.2
Premiers écueilsRetard dans le développement
Demande forte des nouveautés
Mise en route du projet PHP 5.3
Derniers rebondissementsRetard de la mise en place de l’unicode
Demande toujours fortes de nouvelles fonctionnalitésType Hinting, Traits, Patches de performances
Concurrence d’autres langages de scripts
Mort officielle de PHP 6 en mars 2010http://news.php.net/php.internals/47120
PHP 6
++
# 39
Discussions en route :Numéro de version (actuellement sur le SVN : 5.3.99dev)
Organisation du projet
Intégrer quoi et comment?
Que va t’on voir dans PHP.nextCertains sujets font consensus
Traits, Nettoyages des éléments obsolètes, Patch de performances
D’autre un peu moinsType Hinting
Renseignements : Liste internals et RFCMais aussi sur les blogs http://blog.mageekbox.net/
PHP.next
++
# 40
Traits ou Horizontal ReuseAméliorer la réutilisation du code entre les classes et la rendre plus flexible
Permet de regrouper des fonctions communes à des classes distincte
Exemple en PHP 5.3 et antérieur :
<?php class ezcReflectionMethod extends ReflectionMethod { /* ... */
function getReturnType() { /*1*/ } function getReturnDescription() { /*2*/ } /* ... */
} class ezcReflectionFunction extends ReflectionFunction { /* ... */
function getReturnType() { /*1*/ } function getReturnDescription() { /*2*/ } /* ... */
}
?>
Traits
++
# 41
En PHP 5.next (peut-être) ?<?php trait ezcReflectionReturnInfo {
function getReturnType() { /*1*/ } function getReturnDescription() { /*2*/ }
}
class ezcReflectionMethod extends ReflectionMethod { use ezcReflectionReturnInfo; /* ... */
}
class ezcReflectionFunction extends ReflectionFunction { use ezcReflectionReturnInfo; /* ... */
} ?>
Plus d’exemples sur http://wiki.php.net/rfc/horizontalreuse
Traits
++
# 42
Le langage s’améliore encoreOptimisation des algorithmes de hashage
Réorganisation des constantes du langage
Optimisation du modèle objet
En pratiqueGains de 10 à 25%
Diminution de la consommation mémoire
Retours d’expérience :Doctrine 2 : http://news.php.net/php.internals/48148 PHP Unit : http://news.php.net/php.internals/47612
RFC :http://wiki.php.net/rfc/performanceimprovements
Performances
++
# 43
PHP est un langage faiblement typéCast automatique
Pas d’obligation de déclarer une variable
Pas de déclaration de type dans les fonctions
Depuis PHP 5, on commence à voir apparaitre le typage implicite (en objet)function test(AutreClasse $autreclasse) {
echo $autreclasse->var;}
Fonctionne aussi sur les tableaux : function test(array $tableau) {
echo $tableau[0];}
A venir?Généraliser ce système aux fonctions
<?php function foo(int $anInteger, float $aFloat) {...}; ?>
Tout le monde n’est pas d’accord sur la manière de procéder : Notation, erreur (ou pas) à renvoyer, transtypage
Type Hinting
++
# 44
Fin des compatibilitésPHP 3 (et oui…)
Les constructeurs PHP 4
Les balises <% %>
Les propriétés : register_globalsregister_long_arraysmagic_quotes_*allow_call_time_pass_referencesql_safe_mode
Apprenez à les connaitresIncorporation du système DTrace (améliorer le debug)
FPM , nouveau système remplaçant Fast CGI
La liste internals
Divers
++
# 45
La grande inconnueUtilisation généralisée de mbstring?
Classe String?
Généralisation des fonctions d’internationalisation?
Ce qu’on ne verra sans doute jamais : Noms de fonctions en chinois/russe/japonais, comme tout le code PHP :
Unicode ?
function маймуница() {echo "文字化け \n";}маймуница(); // 文字化け
++
# 46
PHP est toujours vivant et…C’est tant mieux
Il y’a encore des marges de manoeuvre
Sais se remettre en question
A venir : Le passage massif à PHP 5.3
L’arrivée du web mobile
L’aventure de la compilation
Stay Tuned!
Conclusion
++
# 47
PHP 5.3LA référence : http://blog.pascal-martin.fr/tag/php-5.3
LSB : http://www.colder.ch/news/08-24-2007/28/late-static-bindings-expl.html
SPL : http://www.alberton.info/php_5.3_spl_data_structures.html
Nouveautés : http://ilia.ws/archives/187-Introduction-to-PHP-5.3-Slides.html
TODO PHP53 : http://wiki.php.net/todo/php53
PHP 6 et PHP.nextTODO php60 : http://wiki.php.net/todo/php60
Infos au quotidien : http://news.php.net/php.internals
http://blog.mageekbox.net/?category/PHP-X
« Divers »http://blog.roshambo.org/archives/A-brief-unofficial-history-about-register_globals-in-PHP.html
Sources / A Lire
Top Related