<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://www.nikrou.net/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
  <title>Le Journal de Nikrou - PHP</title>
  <link>http://www.nikrou.net/</link>
  <description></description>
  <language>fr</language>
  <pubDate>Wed, 18 Jun 2008 19:56:28 +0200</pubDate>
  <copyright></copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Envoyer des mails avec php</title>
    <link>http://www.nikrou.net/post/2007/09/16/130-envoyer-des-mails-avec-php</link>
    <guid isPermaLink="false">urn:md5:20507765f7520609f46f73f32829ddb1</guid>
    <pubDate>Sun, 16 Sep 2007 21:35:53 +0000</pubDate>
    <dc:creator>Nicolas</dc:creator>
        <category>PHP</category>
        <category>php</category>    
    <description>&lt;p&gt;Quoi de plus simple que d'envoyer des mails avec php avec la fonction &lt;a href=&quot;http://fr.php.net/manual/fr/function.mail.php&quot;&gt;mail&lt;/a&gt; ! Les choses se compliquent légèrement si on n'a pas de serveur de mail ! Et c'est peu de le dire. Evidemment on peut se lancer dans l'installation d'un serveur de mail (sendmail ou postfix par exemple) mais ce n'est pas à la portée de monsieur tout le monde si on ne veut pas servir de relais de spam! Une solution simple: &lt;a href=&quot;http://untroubled.org/nullmailer/&quot; hreflang=&quot;en&quot;&gt;nullmailer&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;Hier en voulant tester le module d'envoi de mail de mon application utilisant &lt;a href=&quot;http://www.symfony-project.com/&quot; hreflang=&quot;en&quot;&gt;symfony&lt;/a&gt;, je me suis apperçu que je ne pouvais pas envoyer de mail pour tester ! Ne voulant pas installer un serveur de mail j'ai installé &lt;strong&gt;nullmailer&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Après un &lt;strong&gt;apt-get install nullmailer&lt;/strong&gt;, les trois-quarts du boulot étaient faits. L'installeur pose deux questions:&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;Nom de courrier de votre système ?&lt;/li&gt;
 &lt;li&gt;Machines relais ?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A la première question, j'ai répondu &lt;strong&gt;free.fr&lt;/strong&gt; et à la deuxième j'ai répondu &lt;strong&gt;smtp.free.fr smtp&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;Le serveur de mail (qui n'en est en fait pas un &lt;sup&gt;[&lt;a href=&quot;http://www.nikrou.net/post/2007/09/16/#pnote-130-1&quot; id=&quot;rev-pnote-130-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;!) se lance et après ça marche!!! &lt;/p&gt;
&lt;p&gt;Il ne reste plus qu'à modifier la configuration de php pour qu'il utilise nullmailer au lieu de chercher en vain sendmail ! J'ai juste modifier le &lt;em&gt;sendmail_path&lt;/em&gt;: sendmail_path = /usr/bin/nullmailer-inject -fmoi@free.fr&lt;/p&gt;
&lt;p&gt;La modification de la configuration de php ne me plait qu'à moitié et je pense que je vais écrire un wrapper pour ne pas avoir à la modifier.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;h4&gt;Notes&lt;/h4&gt;
  &lt;p&gt;[&lt;a href=&quot;http://www.nikrou.net/post/2007/09/16/#rev-pnote-130-1&quot; id=&quot;pnote-130-1&quot;&gt;1&lt;/a&gt;] Et oui contrairement à ce qu'on pourrait croire nullmailer n'est pas un serveur de mail. Ce n'est qu'un &lt;acronym title=&quot;Mail Transfer Agent&quot;&gt;MTA&lt;/acronym&gt;. Il ne fait que transférer les messages à un autre MTA ou à un &lt;acronym title=&quot;Mail Delivery Agent&quot;&gt;MDA&lt;/acronym&gt; qui se charge de l'envoyer à destination.&lt;/p&gt;
&lt;/div&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Mettre fin à une authentification http</title>
    <link>http://www.nikrou.net/post/2006/10/02/115-mettre-fin-a-une-authentification-http</link>
    <guid isPermaLink="false">urn:md5:147650b27e99a888a3fe685b3437bab3</guid>
    <pubDate>Mon, 02 Oct 2006 10:06:43 +0000</pubDate>
    <dc:creator>Nicolas</dc:creator>
        <category>PHP</category>
        <category>apache</category><category>php</category>    
    <description>&lt;p&gt;Le but du jeu est de mettre fin à une authentificaiton http faite avec le mécanisme des fichiers &lt;em&gt;.htaccess&lt;/em&gt;    &lt;p&gt;Tout le monde connait l'authentification http fournie par &lt;a href=&quot;http://httpd.apache.org/docs/1.3/&quot;  hreflang=&quot;en&quot;&gt;apache&lt;/a&gt; que l'on met en place aisément avec un fichier &lt;em&gt;.htaccess&lt;/em&gt;. Vous trouverz tous les détails sur &lt;a href=&quot;http://httpd.apache.org/docs/1.3/howto/auth.html#basic&quot; hreflang=&quot;en&quot;&gt;la doc d'apache&lt;/a&gt;. Ce type de protection a l'avantage d'être standard mais aussi de protéger tout le contenu d'un répertoire, contrairement &lt;a href=&quot;http://www.nikrou.net/2006/09/02/112-ouverture-d-une-session-avec-php&quot;&gt;aux sessions php&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Mais la question que l'on se pose est comment mettre fin à cette &quot;session&quot; ? Une solution pour le moins bancale est de proposer au visiteur de fermer son navigateur. On oublie tout de suite. Les visiteurs utilisant &lt;a href=&quot;http://www.mozilla.com/firefox/&quot; hreflang=&quot;en&quot;&gt;firefox&lt;/a&gt; et l'extension &lt;a href=&quot;http://chrispederick.com/work/webdeveloper/&quot; hreflang=&quot;en&quot;&gt;web developer&lt;/a&gt; peuvent le faire aussi aisément sans fermer leur navigateur en cliquant sur:&lt;/p&gt;
&lt;pre&gt;
&lt;b&gt;Miscellaneous &gt; Clear Private Data &gt; Clear HTTP Authentification&lt;/b&gt;. 
&lt;/pre&gt;
&lt;p&gt;Cette solution n'est pas non plus une solution satisfaisante. Tout le monde n'utilise malheureusement pas encore firefox!&lt;/p&gt;
&lt;p&gt;Il n'y a alors pas de solution comme nombreux le prétendent (ils se reconnaitront et ne resteront peut-être pas dans leur ignorance!), allant jusqu'à me modérer parce que j'avais l'affront de prétendre que c'était possible. C'est dur de reconnaitre que l'on a tort et c'est plus facile de ramener la cavalerie pour essayer d'enfoncer la personne qui met un coup de pied dans la fourmillière.&lt;/p&gt;
&lt;p&gt;Revenons à nos moutons. Imaginons que nous voulions protéger un répertoire &lt;a href=&quot;http://www.nikrou.net/private-data&quot;&gt;de données confidentielles&lt;/a&gt;. En supposant que la configuration d'apache nous y autorise - c'est-à-dire qu'il n'y ait aucun &lt;em&gt;AllowOverride None&lt;/em&gt;, il suffit de placer dans le répertoire un fichier &lt;b&gt;.htaccess&lt;/b&gt; contenant:&lt;/p&gt;
&lt;pre&gt;
AuthType Basic
AuthName &quot;Private Access By Invitation Only&quot;
AuthUserFile /absolute/path/to/pass.db
Require valid-user
&lt;/pre&gt;
&lt;p&gt;Ce type de protection n'est pas conseillé. On ne met pas le fichier de mot de passe dans le répertoire à protéger; c'ets juste pour la démonstration!&lt;/p&gt;
&lt;p&gt;Il faut ensuite créer un fichier de mot de passe avec l'utilitaire &lt;b&gt;htpasswd&lt;/b&gt;. J'y ai placé l'identifiant nico avec comme mot de passe nico. On va placer dans ce répertoire un fichier &lt;b&gt;test.php&lt;/b&gt; nous donnant le couple identifiant/mot de passe que l'on a entré. Ce couple est accessible à travers le tableau &lt;b&gt;$_SERVER&lt;/b&gt; au moyen des clés &lt;em&gt;PHP_AUTH_USER&lt;/em&gt; et &lt;em&gt;PHP_AUTH_PW&lt;/em&gt;. Je vais aussi créer un script &lt;b&gt;logout.php&lt;/b&gt; qui va permettre de mettre fin à cette authentification http. Cette déconnexion se fait en envoyant au navigateur un code http &lt;b&gt;401&lt;/b&gt; (authentificaiton requise), le même code qu'apache envoie au navigateur à la première tentative d'accès au répertoire. Le code ressemble à ceci:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&amp;nbsp;&lt;br /&gt;header&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'WWW-Authenticate:&amp;nbsp;Basic&amp;nbsp;realm=&quot;Private&amp;nbsp;Access&amp;nbsp;By&amp;nbsp;Invitation&amp;nbsp;Only&quot;'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;header&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'HTTP/1.0&amp;nbsp;401&amp;nbsp;Unauthorized'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&amp;nbsp;&lt;br /&gt;echo&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Texte&amp;nbsp;affiche&amp;nbsp;en&amp;nbsp;cas&amp;nbsp;d\'annulation'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&amp;nbsp;&lt;br /&gt;exit();&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Vous pouvez maintenant aller &lt;a href=&quot;http://www.nikrou.net/private-data/test.php&quot;&gt;voir mes données confidentielles&lt;/a&gt; (login: nico mot de passe: nico). &lt;a href=&quot;http://www.nikrou.net/provate-data/logout.php&quot;&gt;Déconnectez-vous&lt;/a&gt;, désormais vous ne pouvez plus voir les &lt;a href=&quot;http://www.nikrou.net/private-data/test.php&quot;&gt;données confidentielles&lt;/a&gt;. Vous pouvez cliquer sur annuler si ça vous chante mais vous serez tout de même déconnecter! N'essayer pas directement d'accéder au répertoire car vous auriez un accès non autorisé car par défaut ma configuration n'autorise pas de lister les répertoires (Options -Indexes)&lt;/p&gt;
&lt;p&gt;Notez bien que le &lt;b&gt;realm&lt;/b&gt; doit être le même que celui déclaré dans le .htaccess!&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Qu'est-ce qu'un singleton ?</title>
    <link>http://www.nikrou.net/post/2006/05/28/99-qu-est-ce-qu-un-singleton</link>
    <guid isPermaLink="false">urn:md5:1bb9d61b116869742754dd5074cdbfc0</guid>
    <pubDate>Sun, 28 May 2006 14:28:39 +0000</pubDate>
    <dc:creator>Nicolas</dc:creator>
        <category>PHP</category>
        <category>php</category>    
    <description>&lt;p&gt;Le singleton est un modèle de conception (design pattern pour les grands bretons). En clair c'est une façon éprouvée de résoudre un problème. Avec le sinleton on cherche à n'avoir qu'une seule instance d'un même objet.&lt;/p&gt;    &lt;p&gt;L'implémentation de l'objet singleton consiste à créer une instance de l'objet uniquement si elle n'existe pas encore. On stocke l'instance unique dans une propriété statique de l'objet. Cela peut donner quelque chose comme cela:&lt;/p&gt;
&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;class&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;Singleton&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;private&amp;nbsp;static&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$instance&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;private&amp;nbsp;function&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;__construct&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public&amp;nbsp;static&amp;nbsp;function&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;getInstance&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$instance&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$instance&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;new&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;Singleton&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$instance&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;
&lt;p&gt;La théorie c'est bien joli mais j'entends déjà les questions fuser: à quoi ça sert et comment on s'en sert ? Pour répondre à la première question, je dirais qu'à chaque fois que l'on a besoin d'un objet qui doit rester unique, on utilise un singleton. Je pense par exemple à une classe de log ou une classe de debbugage.&lt;/p&gt;
&lt;p&gt;Pour la deuxième question, voici la façon de récupérer l'instance unique:&lt;/p&gt;
&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;$instance1&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;Singleton&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;getInstance&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;echo&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'&amp;lt;pre&amp;gt;Instance&amp;nbsp;n°1:'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;var_dump&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$instance1&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;),&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'&amp;lt;/pre&amp;gt;'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$instance2&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;Singleton&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;getInstance&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;echo&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'&amp;lt;pre&amp;gt;Instance&amp;nbsp;n°2:'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;var_dump&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$instance2&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;),&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'&amp;lt;/pre&amp;gt;'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;
&lt;p&gt;En exécutant ce code, on obtient:&lt;/p&gt;
&lt;pre&gt;Instance n°1:object(Singleton)#1 (0) {
}

Instance n°2:object(Singleton)#1 (0) {
}
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;#1&lt;/b&gt; est une référence vers l'instance. Dans les deux cas on a la même, ce qui est le but recherché. Au prochain épisode je vous donne un exemple concret!&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Faut-il utiliser $_REQUEST ?</title>
    <link>http://www.nikrou.net/post/2006/05/26/96-faut-il-utiliser-request</link>
    <guid isPermaLink="false">urn:md5:a9b673aa4733f7fa1894b0a090bebacc</guid>
    <pubDate>Fri, 26 May 2006 11:14:49 +0000</pubDate>
    <dc:creator>Nicolas</dc:creator>
        <category>PHP</category>
        <category>php</category>    
    <description>&lt;p&gt;Depuis que je suis tout petit, j'utilise &lt;b&gt;$_GET&lt;/b&gt; pour les données provenant de l'url et &lt;b&gt;$_POST&lt;/b&gt; pour celles provenant de mes formulaires (utilisant la méthode &quot;post&quot;!).&lt;/p&gt;

&lt;p&gt;En lisant divers articles, je me demande si je ne prends pas un peu la tête et si je ne devrais pas utiliser &lt;b&gt;$_REQUEST&lt;/b&gt; quelle que soit la provenance des données. Peu importe la provenance, de toute façon il faut filtrer, vérifier, contrôler la cohérence de ces données.&lt;/p&gt;    &lt;p&gt;Pour commencer par le commencement, &lt;b&gt;$_REQUEST&lt;/b&gt; est un  tableau associatif constitué du contenu des variables &lt;b&gt;$_GET&lt;/b&gt;, &lt;b&gt;$_POST&lt;/b&gt;, &lt;b&gt;$_COOKIE&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;Nombreux sont ceux qui se disent au premier abord que cela est vraiment important de pouvoir distinguer la provenance des informations. Si l'utlisateur envoie les données par l'url (méthode &quot;get&quot;) ou via un formulaire utilisant la méthode &quot;post&quot; qu'est-ce qui est le plus important ? La façon de recevoir les données ou les données elles-même ? Pour ma part je pense que la façon de recevoir les données n'a aucune importance. L'important est de bien contrôler ce que l'on reçoit et de ne faire confiance à aucune donnée même celles qui pourraient sembler anodines et non modifiables telle que &lt;b&gt;$_SERVER['PHP_SELF']&lt;/b&gt; &lt;sup&gt;[&lt;a href=&quot;http://www.nikrou.net/post/2006/05/26/#pnote-96-1&quot; id=&quot;rev-pnote-96-1&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;. Du coup l'utilisation de &lt;b&gt;$_REQUEST&lt;/b&gt; serait plutôt déconseillée aux débutants qui ont déjà du mal à bien faire la différence entre &lt;b&gt;$_GET&lt;/b&gt; et &lt;b&gt;$_POST&lt;/b&gt;. Ceux-ci se contentent généralement de peu de vérifications sur les données transmises via la méthode &quot;post&quot;; ces données leur semblent sûres. Je ne parle même pas des cookies!&lt;/p&gt;
&lt;p&gt;On pourrait se dire que l'utilisation de &lt;b&gt;$_REQUEST&lt;/b&gt; pourrait être intéressante pour les cas où on laisse le choix aux utilisateurs de transmettre les données en utilisant la méthode &quot;get&quot; ou la méthode &quot;post&quot;. La gestion de la provenance des données serait ainsi transparente.&lt;/p&gt;
&lt;p&gt;Je vois un réel intéret d'utiliser &lt;b&gt;$_REQUEST&lt;/b&gt; pour le cas où je veux continuer une session valide sans dépendre de la configuration du serveur, c'est-à-dire sans se demander de quelle manière transite l'identifiant de session (soit par cookie, soit par l'url soit par un champ caché d'un formulaire) alors au lieu d'utiliser une cascade de &lt;b&gt;if&lt;/b&gt; pour savoir d'où vient l'identifiant je peux utiliser un code tel que:&lt;/p&gt;
&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;if&amp;nbsp;(isset(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_REQUEST&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;session_name&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()]))&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;session_start&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;
&lt;p&gt;Pour conclure je ne suis pas complétement convaincu d'utiliser ce tableau magique qu'est &lt;b&gt;$_REQUEST&lt;/b&gt; surtout si on se réfère à l'utilisation des méthodes &quot;get&quot; et &quot;post&quot; et sur une architecture &lt;a href=&quot;http://fr.wikipedia.org/wiki/REST&quot;&gt;REST&lt;/a&gt; d'une application web. Les méthodes &quot;get&quot; et &quot;post&quot; sont bien distinctes et donc récupérer les données sans en connaitre la provenance leurs fait perdre un peu de leur sens.&lt;/p&gt;

 &lt;p&gt;[&lt;a href=&quot;http://www.nikrou.net/post/2006/05/26/#rev-pnote-96-1&quot; id=&quot;pnote-96-1&quot;&gt;1&lt;/a&gt;] Je m'égare; ce sera l'objet d'un prochain billet. Oui j'ai honte de faire du teasing!&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Ne pas réinventer la roue.</title>
    <link>http://www.nikrou.net/post/2006/05/06/94-ne-pas-reinventer-la-roue</link>
    <guid isPermaLink="false">urn:md5:77100c5e996bd99b8d9af2e0e75265b2</guid>
    <pubDate>Sat, 06 May 2006 22:48:00 +0000</pubDate>
    <dc:creator>Nicolas</dc:creator>
        <category>PHP</category>
        <category>php</category>    
    <description>&lt;p&gt;On répète souvent que lorsqu'on fait un script il ne faut pas réinventer la roue et utiliser au maximum les fonctions natives du langage. Cela a de multiples avantages: c'est optimisé, sans bug,... Mais on n'imagine pas toujours lorsqu'on est débutant à quel point cet adage doit être pris au sérieux!&lt;/p&gt;    &lt;p&gt;Prenons un exemple concret pour éclairer le débat. Imaginons deux tables sql liées entre elles par un identifiant numérique:&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;table1: id, champ1, champ2&lt;/li&gt;
 &lt;li&gt;table2: cid, champ3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si on n'utilise mysql comme base de données on va utiliser en général un entier auto-incrémenté comme clé primaire de la première table et on va se servir de cet indentifiant comme clé étrangère dans l'autre table. On fait l'insertion d'un enregistrement dans la première table:&lt;/p&gt;
&lt;pre&gt;insert into table1 (champ1, champ2) values('valeur1', 'valeur2');&lt;/pre&gt;
&lt;p&gt;Jusque là tout va bien. Comment récupérer cet identifiant nouvellement créé ? La première solution qui vient à l'esprit est de récupérer le plus grand identifiant de la table1:&lt;/p&gt;
&lt;pre&gt;select max(id)as max_id from table1;&lt;/pre&gt;
&lt;p&gt;Le résultat obtenu risque de ne pas être le résultat escompté: il se peut qu'une nouvelle insertion intervienne avant que l'on récupère l'identifiant. Si le site n'a que 3 visiteurs par mois le risque que cela arrive est faible mais non négligeable pour un site à fort traffic. Ce n'est pas la bonne méthode: il faut utiliser la fonction &lt;a href=&quot;http://www.php.net/mysql_insert_id&quot; hreflang=&quot;en&quot;&gt;mysql_insert_id()&lt;/a&gt;. Cette fonction récupère l'identifiant auto-incrémenté lié à la dernière insertion, pour la connexion courante.&lt;/p&gt;
&lt;p&gt;Essayons de prouver cela avec les deux scripts suivants en simulant une insertion parasite:&lt;/p&gt;

&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;
// script n°1 basé sur mysql_insert_id():&lt;br&gt;$mysql_link&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mysql_connect&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$host&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$user&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$password&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mysql_select_db&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'db'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$mysql_link&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$query_max&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;select&amp;nbsp;max(id)&amp;nbsp;as&amp;nbsp;max_id&amp;nbsp;from&amp;nbsp;table1&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;printf&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Plus&amp;nbsp;grand&amp;nbsp;id&amp;nbsp;de&amp;nbsp;la&amp;nbsp;table:&amp;nbsp;%d&amp;lt;br&amp;gt;'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;current&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mysql_fetch_assoc&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mysql_query&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$query_max&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$mysql_link&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$query&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;insert&amp;nbsp;into&amp;nbsp;table1&amp;nbsp;(champ1,&amp;nbsp;champ2)&amp;nbsp;values('value1',&amp;nbsp;'value2')&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$result&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mysql_query&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$query&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$mysql_link&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;printf&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'id&amp;nbsp;inséré:&amp;nbsp;%d&amp;lt;br&amp;gt;'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mysql_insert_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$mysql_link&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;));&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;
&lt;br&gt;
&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br&gt;
// script n°2 basé sur le max:&lt;br&gt;$mysql_link&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mysql_connect&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$host&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$user&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$password&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mysql_select_db&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'db'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$mysql_link&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$query_max&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;select&amp;nbsp;max(id)&amp;nbsp;as&amp;nbsp;max_id&amp;nbsp;from&amp;nbsp;table1&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;printf&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Plus&amp;nbsp;grand&amp;nbsp;id&amp;nbsp;de&amp;nbsp;la&amp;nbsp;table:&amp;nbsp;%d&amp;lt;br&amp;gt;'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;current&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mysql_fetch_assoc&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mysql_query&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$query_max&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$mysql_link&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$query&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;insert&amp;nbsp;into&amp;nbsp;table1&amp;nbsp;(champ1,&amp;nbsp;champ2)&amp;nbsp;values('value1',&amp;nbsp;'value2')&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$result&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mysql_query&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$query1&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$mysql_link&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;sleep&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;printf&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'id&amp;nbsp;inséré:&amp;nbsp;%d&amp;lt;br&amp;gt;'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;current&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mysql_fetch_assoc&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mysql_query&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$query_max&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$mysql_link&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;

&lt;p&gt;Imaginons que le plus grand identifiant de la table1 soit 10. On exécute d'abord le script n°2 puis tout de suite après le script n°1. Le scritp n°2 fait une pause de 10 secondes après l'insertion pour simuler une requête qui s'exécuterait avant la récupération du maximum. L'identifiant inséré par le script n°2 sera donc 11 et celui inséré par le script n°1 sera 12. Mais le résultat obtenu n'est pas bon: le scritp n°2 renvoie 12 et le script n°1 renvoie 12.&lt;/p&gt;

&lt;p&gt;On pourrait faire l'opération inverse pour mettre en défaut la fonction mysql_insert_id() en faisant une pause de 10 seconde avant l'appel de la fonction. On verrait que la fonction renvoie bien le résultat voulu.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Quel est mon mot de passe ?</title>
    <link>http://www.nikrou.net/post/2006/03/14/84-quel-est-mon-mot-de-passe</link>
    <guid isPermaLink="false">urn:md5:bf0ae13a9531fbbee24f1f6e151a0c18</guid>
    <pubDate>Tue, 14 Mar 2006 15:27:10 +0000</pubDate>
    <dc:creator>Nicolas</dc:creator>
        <category>PHP</category>
        <category>php</category>    
    <description>    &lt;p&gt;Dans une interface d'administration qui se respecte, on doit pouvoir à un moment créer des comptes. Il est souvent agréable de se voir proposer un mot de passe aléatoire. En général, je n'utilise pas un mot de passe complétement alétaoire: je supprime les caractères ambigus tels que 0, 1, i, j, l, m, n, o, u, v,I,O. Le code peut ressembler à ça. La fonction attend en paramètre la longueur du mot de passe à générer. Cette fonction n'a rien d'extraordinaire mais elle ne fait que ce qu'on lui demande mais elle le fait bien!&lt;/p&gt;
&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;generate_password&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$size&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$listeChar&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'23456789abcdefghkpqrstwxyzABCDEFGHKJLMNPQRSTUVWXYZ'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$max&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;strlen&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$listeChar&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)-&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$key&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;''&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$i&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$i&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$size&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$i&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;++)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$key&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$listeChar&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;mt_rand&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$max&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)];&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;return&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$key&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;

&lt;p&gt;Petite mise à jour. J'avais oublié de préciser une chose: pourquoi je supprime certains caractères ? Je supprime les caractères 0, 1, i, j, l, m, n, o, u, v,I,O car ils sont potentiellement ambigus. Le &quot;i&quot; peut être confondu avec le &quot;l&quot;, le &quot;0&quot; avec le &quot;O&quot;. Même dans la phrase précédente on ne sait pas au premier coup d'oeil si j'ai écris &quot;le zéro et la lettre O&quot; ou &quot;la lettre O et  le zéro. L'intérêt est de générer des mots de manière automatique en enlevant les ambiguïtés visuelles.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Développement piloté par les tests.</title>
    <link>http://www.nikrou.net/post/2006/02/21/80-developpement-pilote-par-les-tests</link>
    <guid isPermaLink="false">urn:md5:85f284d7fe71c40135027b8eb1fc01cb</guid>
    <pubDate>Tue, 21 Feb 2006 17:16:58 +0000</pubDate>
    <dc:creator>Nicolas</dc:creator>
        <category>PHP</category>
        <category>php</category>    
    <description>&lt;p&gt;Il ne semble pas évident au premier abord de faire des tests du code que l'on écrit. En général, on se borne à vérifier qu'il n'y a pas d'erreurs de syntaxe. On vérifie que les 3 ou 4 pages que l'on vient de modifier fonctionnent toujours de la même façon. Cette manière de fonctionner atteint rapidement ses limites au fur et à mesure que l'application grossie. Comment se rappeler que le code écrit aujourd'hui n'aura pas d'impact sur le code écrit il y a 6 mois ? Sans tests exhaustifs, c'est tout simplement impossible.&lt;/p&gt;    &lt;p&gt;Il est hors de question de dérouler les tests &quot;à la main&quot;. On va écrire des tests automatiques ou plus particulièrement des tests de non-régression, c'est-à-dire des tests qui permettent de vérifier que les modifications apportées à l'application n'ont pas apportées de  bugs ou de modifications fonctionnelles. En fait ils permettent de s'assurer que l'application fonctionnera de la même façon.&lt;/p&gt;
&lt;p&gt;En PHP, il y a de nombreuses bibliothèques pour se faciliter la tâche, notament &lt;a href=&quot;http://www.phpunit.de/wiki/Main_Page&quot; hreflang=&quot;en&quot;&gt;PHPUnit&lt;/a&gt; ou &lt;a href=&quot;http://www.lastcraft.com/simple_test.php&quot; hreflang=&quot;en&quot;&gt;Simple Test&lt;/a&gt;. En ayant un peu regardé les deux je me suis décidé à utiliser Simple Test.&lt;/p&gt;
&lt;p&gt;Après avoir lu &lt;a href=&quot;http://www.nikrou.net/2006/01/28/75-l-extreme-programming-bientot-chez-vous&quot;&gt;un livre sur l'Extrême Programming&lt;/a&gt;, il me parait plus judicieux d'écrire les tests avant de commencer à coder quoi que ce soit. Ca peut sembler étrange au premier abord mais en utilisant cette pratique de plus en plus souvent cela semble bien plus naturel et surtout plus facile que d'écrire le code et de s'assurer que les tests que l'on va mettre en place couvrent bien tout l'aspect fonctionnel du code.&lt;/p&gt;
&lt;p&gt;Un p'tit exemple valant mieux qu'un long discours, imaginons que l'on veuille écrire une &quot;interface&quot; de connexion à &lt;a href=&quot;http://www.nikrou.net/xp/login1.php&quot;&gt;une zone membre&lt;/a&gt;. On veut que l'utilisateur ayant un couple identifiant/mot de passe correct soit connecté à la zone et que les autres utilisateurs soient rejettés.&lt;/p&gt;
&lt;p&gt;Code préliminaire: // login_test.php&lt;/p&gt;
&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;require_once(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'../simpletest/web_tester.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;require_once(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'../simpletest/reporter.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;class&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;TestOfLogging&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;extends&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;WebTestCase&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;function&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;testAuth&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;WebTestCase&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br&gt;&amp;nbsp;&amp;nbsp;}&lt;br&gt;}&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$test&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&amp;nbsp;new&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;TestOfLogging&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$test&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(new&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;HtmlReporter&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;());&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;
&lt;p&gt;Et on obtient le joli panneau suivant:&lt;/p&gt;
&lt;h1&gt;TestOfLogging&lt;/h1&gt;
&lt;div style=&quot;padding: 8px; margin-top: 1em; background-color: green; color: white;&quot;&gt;1/1 test cases complete:
&lt;strong&gt;0&lt;/strong&gt; passes, &lt;strong&gt;0&lt;/strong&gt; fails and &lt;strong&gt;0&lt;/strong&gt; exceptions.&lt;/div&gt;
&lt;p&gt;C'est un peu normal puisque l'on a rien testé! Premier test:&lt;/p&gt;
&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;require_once(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'../simpletest/web_tester.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;require_once(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'../simpletest/reporter.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;&lt;br&gt;class&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;TestOfLogging&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;extends&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;WebTestCase&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;function&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;testAuth&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;WebTestCase&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br&gt;&amp;nbsp;&amp;nbsp;}&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;function&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;testUnknownUser&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;get&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'http://localhost/xp/login1.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;setField&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'login'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;inconnu&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;setField&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'password'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'mot-de-passe'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;clickSubmit&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Ok'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;assertWantedPattern&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'/utilisateur&amp;nbsp;inconnu/i'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;&amp;nbsp;&amp;nbsp;}&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$test&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&amp;nbsp;new&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;TestOfLogging&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$test&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(new&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;HtmlReporter&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;());&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;
&lt;p&gt;On obtient ceci:&lt;/p&gt;
&lt;h1&gt;TestOfLogging&lt;/h1&gt;
&lt;span class=&quot;fail&quot;&gt;Fail&lt;/span&gt;: testUnknownUser -&amp;gt; Pattern [/utilisateur inconnu/i] not detected in [String: &amp;lt;br /&amp;gt;
&amp;lt;b&amp;gt;Warning&amp;lt;/b&amp;gt;:  require_once(./classes/Auth.php) [&amp;lt;a href='function.require-once'&amp;gt;function.require-once&amp;lt;/a&amp;gt;]: failed to open stream: No such file or directory in &amp;lt;b&amp;gt;/home/nicolas/webspace/simp...] at [/home/nicolas/webspace/simpletests/tests/login_test.php line 15]&lt;br /&gt;
&lt;div style=&quot;padding: 8px; margin-top: 1em; background-color: red; color: white;&quot;&gt;1/1 test cases complete:
&lt;strong&gt;0&lt;/strong&gt; passes, &lt;strong&gt;1&lt;/strong&gt; fails and &lt;strong&gt;0&lt;/strong&gt; exceptions.&lt;/div&gt;
&lt;p&gt;C'est normal puisque l'on n'a pas encore écrit de code! Une fois le formulaire soumis on affiche le message &quot;utilisateur inconnu&quot;. C'est ce message que l'on cherche dans le test&lt;/p&gt;
&lt;p&gt;L'idée principal du développement piloté par les tests (écrire les tests puis coder) est d'écrire les tests fonctionnels dans un premier temps puis d'écrire le code minimal qui permette de valider le test. On ne cherche pas à faire le code le plus beau et le plus performant à cette étape. Au test d'après on peut factoriser des bouts de code pour améliorer la qualité générale. On n'aura l'assurance que l'on a rien cassé grâce aux tests. Donc pour passer le test, il suffit d'ajouter dans le script login1.php (qui devient &lt;a href=&quot;http://www.nikrou.net/xp/login2&quot;&gt;login2.php&lt;/a&gt;), une ligne avec &quot;Utilisateur inconnu&quot;. C'est loin d'être optimal et c'est même un peu moche comme code. On est confronté à un nouveau problème. La première fois que l'on arrive sur la page, on a le message &quot;Utilisateur inconnu&quot;.&lt;/p&gt;
&lt;p&gt;Lorsqu'on se trouve avec un &quot;bug&quot; ou un comportement non voulu, on commence par écrire le test correspondant et qui échoue nécessairement. Le voici (en tête de la fonction testUnknownUser):&lt;/p&gt;
&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;assertNoUnWantedPattern&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'/utilisateur&amp;nbsp;inconnu/i'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;
&lt;p&gt;Il nous faut maintenant écrire le code minimal qui permette de passer ce test. Il suffit d'ajouter le code suivant: (&lt;a href=&quot;http://www.nikrou.net/xp/login3.php&quot;&gt;login3.php&lt;/a&gt;)&lt;/p&gt;
&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;if&amp;nbsp;(isset(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_POST&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'sub'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]))&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'&amp;lt;p&amp;gt;Utilisateur&amp;nbsp;inconnu&amp;lt;/p&amp;gt;'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;
&lt;p&gt;Et on arrive au résultat attendu:&lt;/p&gt;
&lt;h1&gt;TestOfLogging&lt;/h1&gt;
&lt;div style=&quot;padding: 8px; margin-top: 1em; background-color: green; color: white;&quot;&gt;1/1 test cases complete:
&lt;strong&gt;2&lt;/strong&gt; passes, &lt;strong&gt;0&lt;/strong&gt; fails and &lt;strong&gt;0&lt;/strong&gt; exceptions.&lt;/div&gt;
&lt;p&gt;Attaquons-nous à la partie &quot;utilisateur reconnu&quot;!  On va créer un objet User qui regroupera toutes les propriétés d'un utilisateur et en particulier le fait que son identification est correcte. Les tests dans login.php se résumeront à appeler une méthode vérifiant la validité du couple login/mot de passe pour pouvoir accéder à la zone membre. On va supposer dans un premier temps que l'objet existe et que l'on peut l'utiliser de la manière suivante:&lt;/p&gt;
&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;require_once(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'./classes/User.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$is_valid&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&lt;br /&gt;if&amp;nbsp;(isset(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_POST&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'sub'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]))&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$user&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;new&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;User&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$is_valid&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$user&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;isValid&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_POST&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'login'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;],&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_POST&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'password'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]);&lt;br /&gt;}&lt;br /&gt;if&amp;nbsp;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$is_valid&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Vous&amp;nbsp;êtes&amp;nbsp;connecté&amp;lt;br&amp;gt;'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;}&amp;nbsp;else&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #FF8000&quot;&gt;//&amp;nbsp;affichage&amp;nbsp;du&amp;nbsp;formulaire&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;
&lt;p&gt;Ecrivons maintenant les tests vérifiant qu'un utilisateur reconnu (login: Lebon et mot de passe: Secret) peut se connecter:&lt;/p&gt;
&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;require_once(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'../simpletest/web_tester.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;require_once(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'../simpletest/reporter.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;require_once(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'../classes/User.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;br /&gt;class&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;TestOfLogging&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;extends&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;WebTestCase&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;function&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;testAuth&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;WebTestCase&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;function&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;testUnknownUser&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;get&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'http://localhost/xp/login.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;assertNoUnWantedPattern&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'/utilisateur&amp;nbsp;inconnu/i'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;setField&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'login'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;inconnu&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;setField&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'password'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'mot-de-passe'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;clickSubmit&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Ok'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;assertWantedPattern&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'/utilisateur&amp;nbsp;inconnu/i'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;function&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;testKnownUserCanLogIn&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;get&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'http://localhost/xp/login.php'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;setField&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'login'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Lebon'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;setField&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'password'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Secret'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;clickSubmit&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Ok'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;assertWantedPattern&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'/connecté/i'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$test&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;nbsp;&amp;nbsp;new&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;TestOfLogging&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$test&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(new&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;HtmlReporter&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;());&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;
&lt;p&gt;En testant, on obtient ça:&lt;/p&gt;
&lt;code&gt;
Warning: require_once(../classes/User.php) [function.require-once]: failed to open stream: No such file or directory in /var/www/xp/test/login_test.php on line 4&lt;br&gt;
Fatal error: require_once() [function.require]: Failed opening required '../classes/User.php' (include_path='.:/usr/share/php') in /var/www/xp/test/login_test.php on line 4
&lt;/code&gt;
&lt;p&gt;Après avoir créer la classe User, on obtient:&lt;/p&gt;
&lt;h1&gt;TestOfLogging&lt;/h1&gt;
&lt;span class=&quot;fail&quot;&gt;Fail&lt;/span&gt;: testUnknownUser -&amp;gt; Pattern [/utilisateur inconnu/i] not detected in [String: &amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;

&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Zone membre&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;h1&amp;gt;Zone membre&amp;lt;/h1&amp;gt;

   &amp;lt;br /&amp;gt;
&amp;lt;b&amp;gt;Fatal...] at [/var/www/xp/test/login_test.php line 17]&lt;br /&gt;
&lt;span class=&quot;fail&quot;&gt;Fail&lt;/span&gt;: testKnownUserCanLogIn -&amp;gt; Pattern [/connect&amp;eacute;/i] not detected in [String: &amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;
&amp;lt;html lang=&amp;quot;fr&amp;quot;&amp;gt;

&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Zone membre&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;h1&amp;gt;Zone membre&amp;lt;/h1&amp;gt;
   &amp;lt;br /&amp;gt;

&amp;lt;b&amp;gt;Fatal...] at [/var/www/xp/test/login_test.php line 25]&lt;br /&gt;
&lt;div style=&quot;padding: 8px; margin-top: 1em; background-color: red; color: white;&quot;&gt;1/1 test cases complete:
&lt;strong&gt;1&lt;/strong&gt; passes, &lt;strong&gt;2&lt;/strong&gt; fails and &lt;strong&gt;0&lt;/strong&gt; exceptions.&lt;/div&gt;
&lt;p&gt;On va donc écrire une classe User minimale permettant de passer le nouveau test. Elle pourrait ressembler à ça:&lt;/p&gt;
&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;class&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;User&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;public&amp;nbsp;function&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;__construct&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public&amp;nbsp;function&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;isValid&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$login&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$password&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;((&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$login&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)==&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Lebon'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$password&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)==&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;'Secret'&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;))&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;
&lt;p&gt;Et on obtient alors le beau panneau vert suivant:&lt;/p&gt;
&lt;h1&gt;TestOfLogging&lt;/h1&gt;
&lt;div style=&quot;padding: 8px; margin-top: 1em; background-color: green; color: white;&quot;&gt;1/1 test cases complete:
&lt;strong&gt;3&lt;/strong&gt; passes, &lt;strong&gt;0&lt;/strong&gt; fails and &lt;strong&gt;0&lt;/strong&gt; exceptions.&lt;/div&gt;
&lt;p&gt;Tout le code écrit n'est pas forcément optimal mais on l'idée générale du développement dirigé par les tests. On va pouvoir modifier le code sans risquer d'avoir des régressions fonctionnelles ce qui est un des buts principaux de la méthode.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Version finale de la page d'accès à la zone membre: &lt;a href=&quot;http://www.nikrou.net/xp/login.php&quot;&gt;login.php&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Version finale du script de tests: &lt;a href=&quot;http://www.nikrou.net/xp/tests/login_test.php&quot;&gt;login_test.php&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Version finale de la classe User: &lt;a href=&quot;http://www.nikrou.net/xp/classes/User.php&quot;&gt;User.php&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>A la découverte de php5</title>
    <link>http://www.nikrou.net/post/2006/01/15/73-a-la-decouverte-de-php5</link>
    <guid isPermaLink="false">urn:md5:37843b6fcc6e4e1a5c97f9586768eee4</guid>
    <pubDate>Sun, 15 Jan 2006 20:22:24 +0000</pubDate>
    <dc:creator>Nicolas</dc:creator>
        <category>PHP</category>
        <category>php</category>    
    <description>    &lt;p&gt;La version 5 de &lt;acronym title=&quot;PHP: Hypertext Preprocessor&quot; lang=&quot;en&quot;&gt;PHP&lt;/acronym&gt; est sortie depuis plus d'un an, le 13 juillet 2004 exactement. Je ne parlerais pas des nombreux changements tellement c'est énorme. Mais de quoi je vais parler, alors ? De ma déouverte de php5.&lt;/p&gt;
&lt;p&gt;Je me suis mis à  php5 voici quelques mois. L'installation sur HP-UX n'a pas été une mince affaire mais ça fonctionne!&lt;/p&gt;
&lt;p&gt;J'avais pris comme habitude avec php4 de développer sur le serveur de test avec le niveau d'erreur E_ALL (2047). Avec php5, je suis passé à  E_ALL &amp;amp; E_STRICT, soit 4095. La plupart des scripts qui se disent compatibles php5 ne passent pas avec ce niveau d'erreurs. Un exemple flagrant: on ne peut plus déclarer un attribut de classe (une variable) de la manière suivante:&lt;/p&gt;
&lt;pre&gt;
&lt;?php
class Essai {
   var $ma_variable;
// etc
}
?&gt;
&lt;/pre&gt;
&lt;p&gt;Il faut utiliser un des mots-clés de portée, à savoir &lt;em&gt;public&lt;/em&gt;, &lt;em&gt;protected&lt;/em&gt; ou &lt;em&gt;private&lt;/em&gt;.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Précédence des opérateurs</title>
    <link>http://www.nikrou.net/post/2005/12/21/71-precedence-des-operateurs</link>
    <guid isPermaLink="false">urn:md5:114b0dbbf9720cb854c86a2fb298843c</guid>
    <pubDate>Wed, 21 Dec 2005 11:01:01 +0000</pubDate>
    <dc:creator>Nicolas</dc:creator>
        <category>PHP</category>
        <category>php</category>    
    <description>    &lt;p&gt;Il existe en PHP deux types de &quot;ET&quot; (and et &amp;amp;&amp;amp;) et de &quot;OU&quot; (or et ||). La raison est qu'ils ont des priorités différentes. Le &lt;em&gt;and&lt;/em&gt; et le &lt;em&gt;or&lt;/em&gt; ont une priorité plus faible que l'opérateur &lt;em&gt;=&lt;/em&gt; alors que le &lt;em&gt;&amp;amp;&amp;amp;&lt;/em&gt; et le &lt;em&gt;||&lt;/em&gt; ont une priorité plus élevée que le &lt;em&gt;=&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Par exemple si on a le code suivant:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;?php
$choix1 = &quot;un&quot;;
$choix2 = &quot;deux&quot;;
$choix3 = &quot;trois&quot;;

$val1 = $choix1 || $choix2 || $choix3; 
$val2 = $choix1 or $choix2 or $choix3; 
?&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;$val1&lt;/em&gt; sera égal à &lt;em&gt;true&lt;/em&gt; et $val2 sera égal à &quot;un&quot;.&lt;/p&gt;
&lt;p&gt;Pour régler le problème, soit on met tout le temps des parenthèses, soit on n'utilise les opérateurs &lt;em&gt;&amp;amp;&amp;amp;&lt;/em&gt; et &lt;em&gt;||&lt;/em&gt;.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Afficher une arborescence avec menu et sous-menu.</title>
    <link>http://www.nikrou.net/post/2005/07/22/55-afficher-une-arborescence-avec-menu-et-sous-menu</link>
    <guid isPermaLink="false">urn:md5:70fa548e8ee2ccdaa934f829dea18a10</guid>
    <pubDate>Fri, 22 Jul 2005 22:25:36 +0000</pubDate>
    <dc:creator>Nicolas</dc:creator>
        <category>PHP</category>
        <category>php</category>    
    <description>    &lt;p&gt;On est souvent confronté à ce type de problème: afficher sous forme d'arbre (liste ul/li par exemple) un menu ou un forum. On récupère les informations d'une base de données où chaque enregistrement comprend les champs suivants (au minimum): id, label, parent. La requête de sélection est toute simple: &lt;em&gt;select id, nom, parent from table&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Imaginons que l'on est récupéré ces enregistrements là:&lt;/p&gt;
&lt;code class=&quot;php&quot;&gt;
    &lt;span class=&quot;vars&quot;&gt;&amp;lt;?php&lt;br&gt;
	$tab&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;] = array(&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'menu1'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'parent'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;);&lt;br&gt;
    &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$tab&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;] = array(&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'menu1.1'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'parent'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;);&lt;br&gt;
    &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$tab&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;] = array(&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'menu1.1.1'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'parent'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;);&lt;br&gt;
    &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$tab&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;] = array(&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'menu1.1.2'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'parent'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;);&lt;br&gt;
    &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$tab&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;] = array(&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'menu1.2'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'parent'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;);&lt;br&gt;
    &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$tab&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;] = array(&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'menu2'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'parent'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;);&lt;br&gt;
    &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$tab&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;] = array(&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'menu3'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'parent'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;);&lt;br&gt;
    &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$tab&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;] = array(&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'menu3.1'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'parent'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;);&lt;br&gt;
    &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$tab&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;] = array(&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'menu3.2'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'parent'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;);&lt;br&gt;
    &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$tab&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;] = array(&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'menu3.3'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'parent'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;);&lt;/span&gt;&lt;br&gt;
&lt;span class=&quot;vars&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;
&lt;p&gt;On veut obtenir ça:&lt;/p&gt;
&lt;ul&gt;
   &lt;li&gt;menu1
      &lt;ul&gt;
         &lt;li&gt;menu1.1
            &lt;ul&gt;
               &lt;li&gt;menu1.1.1&lt;/li&gt;
               &lt;li&gt;menu1.1.2&lt;/li&gt;
            &lt;/ul&gt;
         &lt;/li&gt;
         &lt;li&gt;menu1.2&lt;/li&gt;
      &lt;/ul&gt;
   &lt;li&gt;menu2&lt;/li&gt;
   &lt;li&gt;menu3
      &lt;ul&gt;
         &lt;li&gt;menu3.1&lt;/li&gt;
         &lt;li&gt;menu3.2&lt;/li&gt;
         &lt;li&gt;menu3.3&lt;/li&gt;
      &lt;/ul&gt;
   &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Et le code &lt;acronym lang=&quot;en&quot; title=&quot;PHP Hypertext Processor&quot;&gt;PHP&lt;/acronym&gt; correspondant peut ressembler à çà:&lt;/p&gt;
&lt;code class=&quot;php&quot;&gt;
&lt;span class=&quot;vars&quot;&gt;&amp;lt;?php&lt;/span&gt;&lt;br&gt;
&lt;span class=&quot;keywords&quot;&gt;function &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;addTree&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;(&amp;amp;&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$Tree&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$feuille&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;) {&lt;br&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;global &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$tab&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;;&lt;/span&gt;&lt;br&gt;
	&lt;br&gt;
&lt;span class=&quot;vars&quot;&gt;   $Tree&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$feuille&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;]][&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'__LABEL'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;] = &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$feuille&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;];&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach (&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$tab &lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;as &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$cle &lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$element&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;) {&lt;br&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$element&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'parent'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;]==&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;) {&lt;br&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;addTree&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$Tree&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$feuille&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;]],&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$element&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$cle&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;);&lt;br&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
	  &amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
	    }&lt;br&gt;
	      &lt;br&gt;
    &lt;/span&gt;
    &lt;span class=&quot;vars&quot;&gt;$Tree &lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;= array();&lt;br&gt;
	foreach (&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$tab &lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;as &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$cle &lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;=&amp;gt; &lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$feuille&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;) {&lt;br&gt;
	&amp;nbsp;&amp;nbsp;if (&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$feuille&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;strings&quot;&gt;'parent'&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;]==&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;) {&lt;br&gt;
	&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;addTree&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$Tree&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$feuille&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;vars&quot;&gt;$cle&lt;/span&gt;&lt;span class=&quot;keywords&quot;&gt;);&lt;br&gt;
	&amp;nbsp;&amp;nbsp;}&lt;br&gt;
	  }&lt;br&gt;
	  &lt;span class=&quot;vars&quot;&gt;
	      ?&amp;gt;
	  &lt;/span&gt;
       &lt;/span&gt;
  &lt;/code&gt;
&lt;p&gt;Cette petite fonction récurssive peut sembler anodine mais elle fait tout le boulot et elle le fait bien.&lt;/p&gt;</description>
    
    
    
      </item>
    
</channel>
</rss>