<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://methylbro.titaxium.org/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/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Méthylbro Développeur Web PHP - Tutoriels</title>
  <link>http://methylbro.titaxium.org/</link>
  <atom:link href="http://methylbro.titaxium.org/feed/category/Tutoriels/rss2" rel="self" type="application/rss+xml"/>
  <description>Développeur Web PHP</description>
  <language>fr</language>
  <pubDate>Wed, 08 Sep 2010 20:21:12 +0200</pubDate>
  <copyright></copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>PHP/MySQL : Enregistrer et lire des fichiers dans une base de données</title>
    <link>http://methylbro.titaxium.org/post/2009/11/24/php-mysql-enregistrer-et-lire-des-fichiers-dans-une-base-de-donnees</link>
    <guid isPermaLink="false">urn:md5:989586e9886922637ae45206c12893e5</guid>
    <pubDate>Tue, 24 Nov 2009 08:00:00 +0100</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>blob</category><category>fichier</category><category>mysql</category><category>pdo</category><category>php</category><category>sql</category><category>upload</category>    
    <description>    &lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/php-mysql.jpg&quot; alt=&quot;PHP/MySQL : Enregistrer et lire des fichiers dans une base de données&quot; style=&quot;float: left; margin-right: 5px;&quot; /&gt;Tout au long de la semaine dernière nous avons vu comment enregistrer et consulter des fichiers dans une base de données &lt;strong&gt;MySQL&lt;/strong&gt; avec &lt;strong&gt;PHP&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;Nous avons appris les principes de bases des &lt;strong&gt;Objets Larges Binaires&lt;/strong&gt; (BLOB) ainsi que les outils mis a notre disposition par &lt;strong&gt;PDO&lt;/strong&gt; pour les manipuler efficacement avec PHP. Nous avons vu également les limites de ce genre de pratiques et comment en résoudre certaines en implémentant un petit système de cache côté PHP. &lt;/p&gt;
&lt;p&gt;Au cours de mes exemples j’ai proposé une classe &lt;em&gt;FileFromDB&lt;/em&gt; et un ensemble de pages permettant de démontrer comment réaliser tout cela. Vous trouverez aujourd’hui, en annexe à ce billet, l’ensemble des scripts utilisées comme exemple.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;Télécharger des sources : &lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/fichier-dans-base-de-donnees/exemple.rar&quot;&gt;exemple.rar&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Je n’ai malheureusement pas eu le temps de les commenter proprement mais si vous vous reportez aux articles de la semaine, vous serais alors à même de les comprendre. &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://methylbro.titaxium.org/post/2009/11/15/mysql-stocker-un-fichier-dans-une-base-de-donnees&quot;&gt;MySQL : Stocker un fichier dans une base de données&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://methylbro.titaxium.org/post/2009/11/17/php-enregistrer-un-fichier-dans-une-base-de-donnees&quot;&gt;PHP : Enregistrer un fichier dans une base de données&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://methylbro.titaxium.org/post/2009/11/20/php-lire-un-fichier-stocke-dans-la-base-de-donnees&quot;&gt;PHP : Lire un fichier stocké dans la base de données&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://methylbro.titaxium.org/post/2009/11/22/php-un-cache-pour-nos-fichiers-stockes-dans-mysql&quot;&gt;PHP : Un cache pour nos fichiers stockés dans MySQL&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Si cela vous intéresse de venir discourir des avantages et des (nombreux) inconvénients que peuvent avoir cette pratique, je vous invites à venir le faire sur le &lt;a href=&quot;http://www.titaxium.com/forum/&quot;&gt;forum&lt;/a&gt; dans &lt;a href=&quot;http://www.titaxium.com/forum/index.php?showforum=82&quot;&gt;l’espace dédié au développement&lt;/a&gt;.&lt;/p&gt;</description>
    
          <enclosure url="http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/fichier-dans-base-de-donnees/exemple.rar"
      length="5845" type="application/rar" />
    
    
          <comments>http://methylbro.titaxium.org/post/2009/11/24/php-mysql-enregistrer-et-lire-des-fichiers-dans-une-base-de-donnees#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/11/24/php-mysql-enregistrer-et-lire-des-fichiers-dans-une-base-de-donnees#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/528</wfw:commentRss>
      </item>
    
  <item>
    <title>PHP : Un cache pour nos fichiers stockés dans MySQL</title>
    <link>http://methylbro.titaxium.org/post/2009/11/22/php-un-cache-pour-nos-fichiers-stockes-dans-mysql</link>
    <guid isPermaLink="false">urn:md5:7aa43f3143654136f4d8eb7b75eb0666</guid>
    <pubDate>Sun, 22 Nov 2009 13:00:00 +0100</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>cache</category><category>fichier</category><category>mysql</category><category>pdo</category><category>php</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/php.png&quot; alt=&quot;PHP : Un cache pour nos fichiers stockés dans MySQL&quot; style=&quot;float:left;margin-right:15px;&quot; /&gt;Tout au long de la semaine, nous avons vu ensemble comment &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/11/15/mysql-stocker-un-fichier-dans-une-base-de-donnees&quot;&gt;stoker des fichiers dans une base de données MySQL&lt;/a&gt; &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/11/17/php-enregistrer-un-fichier-dans-une-base-de-donnees&quot;&gt;avec PHP&lt;/a&gt; et comment &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/11/20/php-lire-un-fichier-stocke-dans-la-base-de-donnees&quot;&gt;les lire&lt;/a&gt; par la suite.&lt;/p&gt;
&lt;p&gt;Cependant même s'il peut s'avérer pratique de profiter des capacités relationnelles de MySQL pour gérer des fichiers ; le risque d'une consommation de ressources excessive soulevé par cette méthode est élevé.&lt;/p&gt;
&lt;p&gt;Nous allons voir aujourd'hui pourquoi cette pratique bien qu'intéressante en apparence n'est que trop rarement utilisée en réalité. Nous verrons également comment proposer certaines solutions qui nous permettrons de résoudre certains des problèmes soulevés. &lt;/p&gt;    &lt;h3&gt;Au niveau de MySQL&lt;/h3&gt;
&lt;p&gt;Bien évidemment un serveur de base de données n’a pas été conçu pour stocker massivement des fichiers. Il n’a pas pour vocation de manipuler exclusivement ce type d’informations. Votre système de fichier sera bien évidemment beaucoup plus performant pour effectuer cette tâche. &lt;/p&gt;
&lt;p&gt;Stocker des fichiers dans vos tables alourdira considérablement la taille de ces dernières. Le serveur de données aura donc besoin de plus de temps et de ressources pour les parcourir lors de vos requêtes, ce qui peut nuire grandement au temps d’exécution global de vos script. &lt;/p&gt;
&lt;p&gt;A contrario centraliser les données est toujours quelque chose de très intéressant pour la maintenance d’une application. Les backups sont plus faciles à gérer lorsque les données nécessaires pour un programme sont réunies au même endroit. Comme cela peut être le cas avec une base de données. &lt;/p&gt;
&lt;h3&gt;Le débit de données entre le serveur et votre script&lt;/h3&gt;
&lt;p&gt;Il y a un point primordial que nous devront prendre en compte si nous souhaitons tout de même utiliser MySQL pour stocker nos fichiers : c’est le débit d’information qui va circuler entre le serveur de base de données et notre script.&lt;/p&gt;
&lt;p&gt;En effet outre les problèmes directement liés à notre SGBDR a chaque fois que nous allons vouloir faire appel à l’un de nos fichiers stocké en base celui-ci va devoir parcourir un long chemin pour arriver jusqu'à nous. &lt;/p&gt;
&lt;p&gt;Pour illustrer mon propos ; jetez un coups d’œil sur le schéma suivant :&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/fichier-dans-base-de-donnees/2009-11-23-debit-donnees-entre-serveur-et-script.jpg&quot; alt=&quot;Le débit de données entre le serveur et votre script&quot; style=&quot;border: 1px solid rgb(0, 0, 0);&quot; /&gt;&lt;/p&gt;
&lt;p&gt;La solution que l’on peut facilement envisager c’est de créer un cache au sein de notre application qui stockera dans le système de fichiers nos fichiers tant qu’ils seront valables par rapport à leurs version dans la base de données. &lt;/p&gt;
&lt;h3&gt;La méthode FileFromDB::headers()&lt;/h3&gt;
&lt;p&gt;A partir de ce que nous avons fait jusqu'à présent, mettre en place ce petit cache va s’avérer très facile. Commençons par modifier notre classe FileFromDB qui, je vous le rappelle, nous permet de manipuler nos fichiers stockés dans la base de données. &lt;/p&gt;
&lt;p&gt;Même si nous ne souhaitons pas faire circuler nos fichiers inutilement entre notre script et la base de données nous auront besoin néanmoins d’un grand nombre d’informations les concernant. Principalement leur nom ainsi que la date de leur dernière modification. &lt;/p&gt;
&lt;code&gt;public function headers() {&lt;br /&gt;
global $PDO;&lt;br /&gt;
$stmt = $PDO-&amp;gt;prepare(&quot;SELECT name, type, UNIX_TIMESTAMP(updated_date) AS updated_date FROM FILE WHERE name = ?&quot;);&lt;br /&gt;
$stmt-&amp;gt;bindParam(1, $this-&amp;gt;filename);&lt;br /&gt;
$stmt-&amp;gt;execute();&lt;br /&gt;
return $stmt-&amp;gt;fetch(PDO::FETCH_OBJ);&lt;br /&gt;
}&lt;/code&gt;
&lt;p&gt;C’est le rôle de cette nouvelle méthode. Elle nous donnera uniquement ces informations sous la forme d’un objet de type &lt;em&gt;sdtClass&lt;/em&gt;. Ce qui évitera d’avoir à aller chercher notre fichier inutilement à chaque demandes.&lt;/p&gt;
&lt;h3&gt;Une nouvelle page de download&lt;/h3&gt;
&lt;p&gt;Maintenant que nous disposons des outils nécessaires, nous pouvons modifier notre page de téléchargement de fichiers en y ajoutant notre petit système de cache. Par défaut donc, notre script enverra donc au visiteur le fichier contenu dans le cache. &lt;/p&gt;
&lt;p&gt;Ce dernier sera néanmoins renouvelé par le fichier contenu dans la base de donnée si l’une de ces trois conditions n’est pas rempli : &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Le fichier n’existe pas encore dans le cache&lt;/li&gt;
&lt;li&gt;Le fichier stocké dans le cache à dépasser son temps de vie maximum&lt;/li&gt;
&lt;li&gt;Le fichier stocké dans le cache n’est plus à jour avec celui stocké dans la base de données&lt;/li&gt;
&lt;/ol&gt;
&lt;code&gt;$cache_path = 'cache/';&lt;br /&gt;
$cache_lifetime = 3600;&lt;br /&gt;
&lt;br /&gt;
if (isset($_GET['filename'])) {&lt;br /&gt;
$File = new FileFromDB($_GET['filename']);&lt;br /&gt;
$FileHeaders = $File-&amp;gt;headers();&lt;br /&gt;
$file_cache = $cache_path.$FileHeaders-&amp;gt;name;&lt;br /&gt;
if (!file_exists($file_cache)&lt;br /&gt;
|| filemtime($file_cache)+$cache_lifetime&lt;time()&gt;&lt;br /&gt;
|| filemtime($file_cache)&amp;lt;=$FileHeaders-&amp;gt;updated_date) {&lt;br /&gt;
$File-&amp;gt;output($file_cache);&lt;br /&gt;
}&lt;br /&gt;
header(&quot;Content-Type: {$FileHeaders-&amp;gt;type}&quot;);&lt;br /&gt;
header(&quot;Content-Disposition: inline; filename={$FileHeaders-&amp;gt;name}&quot;);&lt;br /&gt;
header(&quot;Last-Modified: &quot;.date('r', $FileHeaders-&amp;gt;updated_date));&lt;br /&gt;
readfile($file_cache);&lt;br /&gt;
}&lt;/time()&gt;&lt;/code&gt;
&lt;p&gt;Dans un prochain billet je reviendrais sur tout ce que nous avons vu sur le stockage de fichier au sein d’une base de données avant de conclure cet article. Je vous proposerais également les sources utilisées dans nos exemples commentés.&lt;/p&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/11/22/php-un-cache-pour-nos-fichiers-stockes-dans-mysql#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/11/22/php-un-cache-pour-nos-fichiers-stockes-dans-mysql#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/518</wfw:commentRss>
      </item>
    
  <item>
    <title>PHP : Lire un fichier stocké dans la base de données</title>
    <link>http://methylbro.titaxium.org/post/2009/11/20/php-lire-un-fichier-stocke-dans-la-base-de-donnees</link>
    <guid isPermaLink="false">urn:md5:33070ae7891ffe29e2bf600e6a1095d1</guid>
    <pubDate>Fri, 20 Nov 2009 08:00:00 +0100</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>blob</category><category>fichier</category><category>pdo</category><category>php</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/php.png&quot; alt=&quot;PHP : Lire un fichier stocké dans la base de données&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Nous avons vu précédemment comment &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/11/15/mysql-stocker-un-fichier-dans-une-base-de-donnees&quot;&gt;stocker un fichier dans une base de données MySQL&lt;/a&gt;. Puis nous avons explorer ensemble une méthode pour &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/11/17/php-enregistrer-un-fichier-dans-une-base-de-donnees&quot;&gt;insérer ce fichier dans la base&lt;/a&gt; directement à l’aide d’un petit script PHP. Aujourd’hui nous allons voir comment &lt;strong&gt;récupérer ce fichier avec PHP&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Notre exemple sera très simple, nous allons seulement récupérer le fichier là ou il est, c’est a dire dans la base de données MySQL, pour le retourner directement à un visiteur.&lt;/p&gt;
&lt;p&gt;Il n’y aura donc pas de traitement sur ce fichier. Cependant cela serait tout à fait possible. Récemment par exemple je me suis retrouver dans un cas ou je devais modifier des images après les avoir récupérer dans une base de données.&lt;/p&gt;    &lt;h3&gt;La méthode FileFromDB ::output()&lt;/h3&gt;
&lt;p&gt;Dans notre dernier chapitre sur ce sujet, nous avons commencé l’élaboration d’une classe &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/11/17/php-enregistrer-un-fichier-dans-une-base-de-donnees&quot;&gt;FileFromDB&lt;/a&gt; nous permettant de manipuler des &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/11/15/mysql-stocker-un-fichier-dans-une-base-de-donnees&quot;&gt;fichiers stockés dans une base de données&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Nous allons poursuivre la conception de cette dernière en lui rajoutant une méthode &lt;em&gt;output()&lt;/em&gt; qui nous permettra de lire un fichier vers le flux standard de sortie ou d’enregistrer celui-ci dans le système de fichiers.&lt;/p&gt;
&lt;p&gt;Cette méthode acceptera donc un paramètre facultatif &lt;em&gt;$filename&lt;/em&gt;. Si celui-ci est fournis nous enregistrerons une copie du fichier stocké dans la base de données vers la destination indiqué au sein du système de fichiers.&lt;/p&gt;
&lt;p&gt;Sinon nous afficherons le fichier directement vers le flux standard de sortie. Comme il s’agit d’Apache dans notre exemple, nous prendrons soin d’indiquer certains &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/07/23/ressources-http-champs-d-en-tete-et-codes-de-retour&quot;&gt;en-têtes HTTP&lt;/a&gt; nécessaire pour que le client comprenne de quel fichier il s’agit.&lt;/p&gt;
&lt;code&gt;public function output($filename=null) {&lt;br /&gt;
global $PDO;&lt;br /&gt;
$stmt = $PDO-&amp;gt;prepare(&quot;SELECT type, UNIX_TIMESTAMP(updated_date), data FROM FILE WHERE name = ?&quot;);&lt;br /&gt;
$stmt-&amp;gt;bindParam(1, $this-&amp;gt;filename);&lt;br /&gt;
$stmt-&amp;gt;execute();&lt;br /&gt;
$stmt-&amp;gt;bindColumn(1, $type, PDO::PARAM_STR, 256);&lt;br /&gt;
$stmt-&amp;gt;bindColumn(2, $updated_date, PDO::PARAM_INT);&lt;br /&gt;
$stmt-&amp;gt;bindColumn(3, $data, PDO::PARAM_LOB);&lt;br /&gt;
$stmt-&amp;gt;fetch(PDO::FETCH_BOUND);&lt;br /&gt;
if (is_null($filename)) {&lt;br /&gt;
header(&quot;Content-Type: $type&quot;);&lt;br /&gt;
header(&quot;Content-Disposition: inline; filename={$this-&amp;gt;filename}&quot;);&lt;br /&gt;
header(&quot;Last-Modified: &quot;.date('r', $updated_date));&lt;br /&gt;
//return fpassthru($data);&lt;br /&gt;
return print($data);&lt;br /&gt;
} else {&lt;br /&gt;
$hdle = fopen($filename, 'wb');&lt;br /&gt;
//return stream_copy_to_stream($data, $hdle);&lt;br /&gt;
return fwrite($hdle, $data);&lt;br /&gt;
}&lt;br /&gt;
}&lt;/code&gt;
&lt;h3&gt;Le bug #40913 de PHP&lt;/h3&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://bugs.php.net/bug.php?id=40913&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/fichier-dans-base-de-donnees/2009-11-20-bug-php-40913-pdo-param-lob.jpg&quot; alt=&quot;e bug #40913 de PHP&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Comme vous pourrez le voir j’ai laissé deux lignes en commentaires dans la méthode ci-dessus. En effet a ce stade nous ne pourrons malheureusement pas utiliser d’objet large binaire (&lt;a href=&quot;http://methylbro.titaxium.org/post/2009/11/15/mysql-stocker-un-fichier-dans-une-base-de-donnees&quot;&gt;Binary Large Object&lt;/a&gt;) car PHP et PDO sont encore victimes d’un &lt;a href=&quot;http://bugs.php.net/bug.php?id=40913&quot;&gt;bug non corrigé&lt;/a&gt; à ce sujet.&lt;/p&gt;
&lt;p&gt;Le problème vient du fait que, malgré que l’on indique à PDO que l’on souhaite recevoir un paramètre de type PDO::PARAM_LOB (Objet Binaire Large) celui-ci nous retourne une chaîne de caractère (PDO::PARAM_STR). Il deviens impossible alors de traiter notre valeur comme une ressource de flux (utilisable notamment avec les fonctions &lt;em&gt;fpassthru()&lt;/em&gt; et &lt;em&gt;stream_copy_to_stream()&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt;En attendant que ce problème soit corrigé j’utiliserais donc print() et fwrite() dans mon exemple. Mais attention, cette méthode de remplacement consomme énormément plus en ressource qu’un simple traitement par flux. Ne l’utilisez donc pas en production (surtout sur des sites avec une grosse charge). &lt;/p&gt;
&lt;h3&gt;La page de download&lt;/h3&gt;
&lt;p&gt;Maintenant que nous avons une solution nous permettant de récupérer des fichiers stockés dans notre base de données MySQL, nous pouvons facilement créer un petit script pour télécharger ces fichiers.&lt;/p&gt;
&lt;code&gt;if (isset($_GET['filename'])) {&lt;br /&gt;
$File = new FileFromDB($_GET['filename']);&lt;br /&gt;
$File-&amp;gt;output();&lt;br /&gt;
}&lt;/code&gt;
&lt;p&gt;Encore une fois ce script restera simple et l’on omettra toutes les vérifications d’usage en termes de sécurité. Ce n’est pas le sujet abordé.&lt;/p&gt;
&lt;p&gt;Dans un prochain article nous verrons que notre solution demande énormément de ressources inutiles. Nous réglerons donc ces problèmes en implémentant un petit système de cache applicatif côté PHP.&lt;/p&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/11/20/php-lire-un-fichier-stocke-dans-la-base-de-donnees#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/11/20/php-lire-un-fichier-stocke-dans-la-base-de-donnees#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/505</wfw:commentRss>
      </item>
    
  <item>
    <title>PHP : Enregistrer un fichier dans une base de données</title>
    <link>http://methylbro.titaxium.org/post/2009/11/17/php-enregistrer-un-fichier-dans-une-base-de-donnees</link>
    <guid isPermaLink="false">urn:md5:00b83022d9cedf00942fb38a312bd839</guid>
    <pubDate>Tue, 17 Nov 2009 08:00:00 +0100</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>blob</category><category>fichier</category><category>pdo</category><category>php</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/php.png&quot; alt=&quot;PHP : Enregistrer un fichier dans une base de données&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Maintenant que nous disposons d’une base de données prête à &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/11/15/mysql-stocker-un-fichier-dans-une-base-de-donnees&quot;&gt;stocker nos fichiers directement au sein d’une table&lt;/a&gt; nous allons pouvoir commencer à regarder comment faire fonctionner cela proprement avec PHP.&lt;/p&gt;
&lt;p&gt;Nous verrons donc aujourd’hui comment enregistrer un fichier au sein d’un champ de type LONGBLOB avec PHP. Ici le fichier proviendra d’un formulaire mais on pourrais très bien étendre le champ d’application de cette méthode à tout type de sources. &lt;/p&gt;
&lt;p&gt;L’exemple utilisera PDO (PHP Data Object) ; si vous n’êtes pas à l’aise avec cette extension de PHP je vous conseille vivement de vous mettre à jour. Car comme vous pourrez le voir les fonctionnalités que proposent cette extension sont fort agréables.&lt;/p&gt;    &lt;h3&gt;La classe FileFromDB&lt;/h3&gt;
&lt;p&gt;Afin de manipuler les fichiers stockées dans la base de données, je vous propose d’utiliser une classe que nous feront évoluer tout au long de ce tutoriel. Appelons la FileFromDB car chaque instance de cette classe nous permettra de manipuler un de nos fichiers. &lt;/p&gt;
&lt;code&gt;class FileFromDB {&lt;br /&gt;
private $filename;&lt;br /&gt;
public function __construct($filename) {&lt;br /&gt;
$this-&amp;gt;filename = $filename;&lt;br /&gt;
}&lt;br /&gt;
}&lt;/code&gt;
&lt;h3&gt;Le formulaire d’upload&lt;/h3&gt;
&lt;p&gt;Comme je le disait lors de l’introduction, dans notre exemple les fichiers seront envoyés par les utilisateurs. Cela nécessitera donc un petit formulaire permettant d’envoyer des fichiers. &lt;/p&gt;
&lt;code&gt;&amp;lt;?php&lt;br /&gt;
$message = null;&lt;br /&gt;
if (isset($_FILES['myFile'])) {&lt;br /&gt;
$File = new FileFromDB($_FILES['myFile']['name']);&lt;br /&gt;
$File-&amp;gt;upload($_FILES['myFile']);&lt;br /&gt;
$message = 'Votre fichier à bien été ajouté';&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Upload&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;form method=&quot;post&quot; enctype=&quot;multipart/form-data&quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php echo $message; ?&amp;gt;&lt;br /&gt;
&amp;lt;fieldset&amp;gt;&lt;br /&gt;
&amp;lt;legend&amp;gt;Charger un fichier&amp;lt;/legend&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;label for=&quot;myFile&quot;&amp;gt;Fichier&amp;lt;/label&amp;gt;&lt;br /&gt;
&amp;lt;input type=&quot;file&quot; id=&quot;myFile&quot; name=&quot;myFile&quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;input type=&quot;reset&quot; value=&quot;Annuler&quot; /&amp;gt;&lt;br /&gt;
&amp;lt;input type=&quot;submit&quot; value=&quot;Envoyer&quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/fieldset&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/fichier-dans-base-de-donnees/2009-11-17-formulaire-upload.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Ce formulaire restera simple et l’on omettra toutes les vérifications d’usage en termes de sécurité. Ce n’est pas le sujet abordé.&lt;/p&gt;
&lt;h3&gt;La méthode FileFromDB::upload()&lt;/h3&gt;
&lt;p&gt;Enfin nous ajouterons à notre classe FileFromDB une méthode permettant d’enregistrer notre fichier comme un objet large binaire au sein de notre table. L’extension PDO et son système de requêtes préparées nous propose un type de paramètre parfait pour résoudre les problèmes liés : PARAM_LOB. &lt;/p&gt;
&lt;p&gt;Ainsi nous passerons comme paramètre un flux vers le fichier que l’on souhaite envoyé à la base de données au lieu de l’intégralité du contenu lui même. En travaillant avec des flux de données nous ne consommerons pas inutilement les ressources disponibles.&lt;/p&gt;
&lt;code&gt;public function upload($file) {&lt;br /&gt;
global $PDO;&lt;br /&gt;
$stmt = $PDO-&amp;gt;prepare(&quot;REPLACE INTO FILE (name, type, data) VALUES (?, ?, ?)&quot;);&lt;br /&gt;
$stmt-&amp;gt;bindParam(1, $this-&amp;gt;filename);&lt;br /&gt;
$stmt-&amp;gt;bindParam(2, $file['type']);&lt;br /&gt;
$stmt-&amp;gt;bindParam(3, fopen($file['tmp_name'], 'rb'), PDO::PARAM_LOB);&lt;br /&gt;
return $stmt-&amp;gt;execute();&lt;br /&gt;
}&lt;/code&gt;
&lt;p&gt;Dans un prochain article nous verrons comment lire des fichiers enregistrés dans notre base de données. &lt;/p&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/11/17/php-enregistrer-un-fichier-dans-une-base-de-donnees#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/11/17/php-enregistrer-un-fichier-dans-une-base-de-donnees#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/504</wfw:commentRss>
      </item>
    
  <item>
    <title>MySQL : Stocker un fichier dans une base de données</title>
    <link>http://methylbro.titaxium.org/post/2009/11/15/mysql-stocker-un-fichier-dans-une-base-de-donnees</link>
    <guid isPermaLink="false">urn:md5:b4a388150442cc375206b9d4bee1586d</guid>
    <pubDate>Sun, 15 Nov 2009 08:00:00 +0100</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>blob</category><category>fichier</category><category>MySQL</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/bdd.png&quot; alt=&quot;MySQL : Stocker un fichier dans une base de données&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Techniquement il est tout à fait possible de stocker des fichiers directement au sein d'une base de données. &lt;/p&gt;
&lt;p&gt;Cependant peut de développeurs se risquent à ce genre de pratique. Il est vrai que si l'on maîtrise mal certains aspects, ou s'il on en demande trop à cette technique cela peut vite se révéler être un véritable calvaire. &lt;/p&gt;
&lt;p&gt;Néanmoins je reste intimement convaincu que dans certains cas et pour des besoins raisonnables il peut être fort agréable de pouvoir stocker des fichiers directement au sein d'une base de données.&lt;/p&gt;
&lt;p&gt;Cette semaine je vous propose une série de billets qui va vous permettre de comprendre comment réaliser une telle chose. Mais je vais également essayer de vous amener à bien appréhender les risques et les limites d'une telle pratique ce qui vous permettra de mieux envisager sur quel projet cela peut ou ne peut pas se faire.&lt;/p&gt;    &lt;h3&gt;Les Objets Larges Binaires (BLOB)&lt;/h3&gt;
&lt;p&gt;Pour stocker nos fichiers au sein de notre base de données nous allons utiliser un type de données que les néophytes découvriront sans doutes pour la première fois : les &lt;strong&gt;Objets Larges Binaires&lt;/strong&gt; ou &lt;acronym title=&quot;Binary Large Object&quot;&gt;BLOB&lt;/acronym&gt; pour &lt;strong&gt;Binary Large Object&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Le BLOB est un type de donnée permettant le stockage d’informations sous forme binaire. On l’utilise le plus souvent pour stocker des fichiers en tout genre (images, sons ou videos …) directement dans le champ d'une table d'une base de données.&lt;/p&gt;
&lt;p&gt;Pour notre exemple nous utiliserons &lt;strong&gt;MySQL&lt;/strong&gt; comme système de gestion de base de données. Sachez que celui-ci propose plusieurs types différents d’objets larges qui ne diffèrent que par la taille maximale des données qu’ils peuvent stocker. &lt;/p&gt;
&lt;p&gt;Parmi eux nous utiliserons le type &lt;strong&gt;LONGBLOB&lt;/strong&gt; car ce dernier propose la capacité maximale de stockage ; mais le choix du type à utiliser variera selon les cas que vous pourrez rencontrer lors d’une application pratique. &lt;/p&gt;
&lt;h3&gt;Création de la table&lt;/h3&gt;
&lt;p&gt;La première étape consiste donc à créer la table qui viendra stocker nos différents fichiers. Outre le nom du fichier et le contenu même du fichier, nous conserverons également le type de fichier (« image/jpeg » pour une image par exemple) et la date de la dernière modification du fichier. &lt;/p&gt;
&lt;p&gt;Ces informations supplémentaires nous seront utiles par la suite pour envoyer des en-têtes HTTP corrects au visiteurs ainsi que pour gérer un petit cache côté serveur. &lt;/p&gt;
&lt;code&gt;CREATE TABLE `FILE` (&lt;br /&gt;
&lt;br /&gt;
`name` varchar(255) NOT NULL,&lt;br /&gt;
`type` varchar(255) NULL,&lt;br /&gt;
`updated_date` timestamp NOT NULL&lt;br /&gt;
DEFAULT CURRENT_TIMESTAMP&lt;br /&gt;
ON UPDATE CURRENT_TIMESTAMP,&lt;br /&gt;
`data` longblob NULL,&lt;br /&gt;
&lt;br /&gt;
PRIMARY KEY (`name`)&lt;br /&gt;
&lt;br /&gt;
)TYPE=MyISAM;&lt;/code&gt;
&lt;h3&gt;Un champ de fichier dans PHPMyAdmin&lt;/h3&gt;
&lt;p&gt;Une fois que vous aurez créer votre table avec la requête SQL &lt;em&gt;CREATE TABLE&lt;/em&gt; ci-dessus, vous vous apercevrais sans doutes que PHPMyAdmin vous proposera un formulaire d’insertion un peut particulier. &lt;/p&gt;
&lt;p&gt;En effet, vous verrez apparaître un champ d’envoi de fichier pour la valeur data. Comme vous pouvez le voir donc, notre champ data est bien destiné à recevoir un fichier. &lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/fichier-dans-base-de-donnees/2009-11-14-blob-phpmyadmin.jpg&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/fichier-dans-base-de-donnees/.2009-11-14-blob-phpmyadmin_m.jpg&quot; alt=&quot;Formulaire d'insertion de PHPMyAdmin pour la table FILE&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Dans un prochain article ; nous verrons comment enregistrer des fichiers au sein de cette table directement depuis un script PHP.&lt;/p&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/11/15/mysql-stocker-un-fichier-dans-une-base-de-donnees#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/11/15/mysql-stocker-un-fichier-dans-une-base-de-donnees#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/503</wfw:commentRss>
      </item>
    
  <item>
    <title>Étude de cas : Une perle dans l'utilisation de la fonction date de PHP</title>
    <link>http://methylbro.titaxium.org/post/2009/10/23/etude-de-cas-une-perle-dans-utilisation-de-la-fonction-date-de-php</link>
    <guid isPermaLink="false">urn:md5:2addc5b73a11b73b1a1e7a507e6a5df1</guid>
    <pubDate>Fri, 23 Oct 2009 08:00:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>date</category><category>getdate</category><category>php</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/php.png&quot; alt=&quot;Étude de cas : Une perle dans l'utilisation de la fonction date de PHP&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Toujours plonger dans mes retouches sur un code source magnifiquement drôle depuis ces derniers jours. Je voudrais vous proposer aujourd’hui une nouvelle perle de &lt;strong&gt;développement PHP&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Aujourd'hui nous allons voir une implémentation hilarante de la fonction &lt;strong&gt;date()&lt;/strong&gt;.&lt;/p&gt;    &lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://fr.php.net/manual/fr/function.getdate.php&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/2009-10-23-etude-de-cas-une-perle-dans-utilisation-de-la-fonction-date-de-php.jpg&quot; alt=&quot;Étude de cas : Une perle dans l'utilisation de la fonction date de PHP&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La problématique est la suivante : afin de construire une chaîne de caractères vous avez besoin de connaître trois informations temporelles ; l'année, le mois et le jour courant.&lt;/p&gt;
&lt;p&gt;Pour ce faire, voici ce qu'a proposé, écrit et mis en production un développeur :&lt;/p&gt;
&lt;code&gt;$today = mktime(0, 0, 0, date(&quot;m&quot;), date(&quot;d&quot;), date(&quot;Y&quot;));&lt;br /&gt;
$ladate = date(&quot;d / m / Y&quot;, $today);&lt;br /&gt;
$lemois = date(&quot;m&quot;, $today);&lt;br /&gt;
$lannee = date(&quot;Y&quot;, $today);&lt;br /&gt;
$lejour = date(&quot;d&quot;, $today);&lt;/code&gt;
&lt;p&gt;Vous comprenez le problème ? &lt;/p&gt;
&lt;p&gt;Ici l'interpréteur va calculer 8 fois la date. Sans compter bien évidement qu'utiliser la variable $today est inutile vu que la fonction date() retourne déjà la date du jour par défaut (ce que savais apparemment le développeur, puisqu'il utilise la fonction date() pour trouver la valeur de son $today) .&lt;/p&gt;
&lt;p&gt;Bien évidement, il aurait été plus pertinent d'écrire quelque chose comme cela :&lt;/p&gt;
&lt;code&gt;define('DATE_SEPARATOR', ' / ');&lt;br /&gt;
$today = getdate();&lt;br /&gt;
$lemois = $today['mon'];&lt;br /&gt;
$lannee = $today['year'];&lt;br /&gt;
$lejour = $today['mday'];&lt;br /&gt;
$ladate = $lejour.DATE_SEPARATOR.$lemois.DATE_SEPARATOR.$lannee;&lt;/code&gt;
&lt;p&gt;Un seul calcul de date, on stocke les informations dans un tableau associatif et ensuite c'est juste un jeu d'affection de valeurs.&lt;/p&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/10/23/etude-de-cas-une-perle-dans-utilisation-de-la-fonction-date-de-php#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/10/23/etude-de-cas-une-perle-dans-utilisation-de-la-fonction-date-de-php#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/444</wfw:commentRss>
      </item>
    
  <item>
    <title>Étude de cas PHP &amp; MySQL : Connaître le nombre d’occurrences dans une table</title>
    <link>http://methylbro.titaxium.org/post/2009/10/21/etude-de-cas-php-mysql-connaitre-le-nombre-occurrences-dans-une-table</link>
    <guid isPermaLink="false">urn:md5:1aebdb6742ec484883762e737d9344e2</guid>
    <pubDate>Wed, 21 Oct 2009 13:00:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
            
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/php.png&quot; alt=&quot;Étude de cas PHP &amp;amp; MySQL : Connaître le nombre d’occurrences dans une table&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Toujours plongé dans de l'analyse de code depuis quelques jours, je vous propose à nouveau de partager et d'analyser quelques perles avec vous. &lt;/p&gt;
&lt;p&gt;Dans ce billet, je vais m'entretenir avec vous d'un cas récurrent en développement web : compter un nombre d'occurrences spécifique dans une base de données ou plus simplement, connaître le nombre d'occurrences enregistré dans une table. C'est ce dernier exemple que nous utiliserons pour illustrer mes propos. &lt;/p&gt;
&lt;p&gt;Parmi mes pérégrinations dans les méandres de ce script infâme ; je suis tombé sur diverses méthodes pour compter un nombre d'occurrences dans une base de données qui m'ont fait hurler. &lt;/p&gt;    &lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/2009-10-21-etude-de-cas-php-mysql-connaitre-le-nombre-occurrences-dans-une-table.jpg&quot; alt=&quot;Étude de cas PHP &amp;amp; MySQL : Connaître le nombre d’occurrences dans une table&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Premier exemple, le développeur qui n'a jamais appris autre chose que les requêtes de base et se limite aux outils les plus simples de PHP :&lt;/p&gt;
&lt;code&gt;$sql = &quot;SELECT * FROM maTable&quot;;&lt;br /&gt;
$res = mysql_query($sql);&lt;br /&gt;
while($row[] = mysql_fetch_array($res));&lt;br /&gt;
$nb  = count($row);&lt;/code&gt;
&lt;p&gt;Remarquez comme c'est magnifique ; lancer une boucle à l'exécution alors que c'est complètement inutile. &lt;/p&gt;
&lt;p&gt;Comme deuxième exemple, je vais vous proposer une variante ; le développeur qui n'y connais toujours rien au SQL de base, mais qui c'est quand même penché un minimum sur la documentation de PHP :&lt;/p&gt;
&lt;code&gt;$sql = &quot;SELECT * FROM maTable&quot;;&lt;br /&gt;
$res = mysql_query($sql);&lt;br /&gt;
$nb  = mysql_num_rows($res);&lt;/code&gt;
&lt;p&gt;C'est presque acceptable. Cependant imaginez le nombre d'informations inutiles que vous allez faire circuler entre le serveur de données  (ici MySQL) et votre script ? Si le nombre d'enregistrements dans votre table est conséquent, imaginez le temps que cela va prendre !&lt;/p&gt;
&lt;p&gt;Bien évidement, vous avez la réponse en vous. Il faut utiliser la fonction SQL COUNT(). C'est logique. Comme cela on ne récupère que le nombre d'occurrences ; après tout pourquoi pas, c'est la seule chose que l'on veut non ?&lt;/p&gt;
&lt;p&gt;En bon développeur consciencieux ; vous écrirez sans doutes quelque chose comme cela : &lt;/p&gt;
&lt;code&gt;$sql = &quot;SELECT COUNT(*) FROM maTable&quot;;&lt;br /&gt;
$res = mysql_query($sql);&lt;br /&gt;
$row = mysql_fetch_row($res);&lt;br /&gt;
$nb  = $row[0];&lt;/code&gt;
&lt;p&gt;Cependant même si vous êtes presque dans le vrai, une dernière chose me chipote sur cette solution. Pourquoi faire une affectation par ligne avec un &lt;q&gt;fetch&lt;/q&gt; ? Il n'y a qu'une seule information dans le résultat votre requête, vous savez ou elle se trouve alors pourquoi ne pas aller la chercher directement ?&lt;/p&gt;
&lt;p&gt;C'est pourquoi, et pour conclure, je proposerais tout simplement cette solution : &lt;/p&gt;
&lt;code&gt;$sql = &quot;SELECT COUNT(*) AS `nb` FROM `maTable`;&quot;;&lt;br /&gt;
$res = mysql_query($sql);&lt;br /&gt;
$nb  = mysql_result($res, 0, 'nb');&lt;/code&gt;
&lt;p&gt;Et vous, vous feriez comment ?&lt;/p&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/10/21/etude-de-cas-php-mysql-connaitre-le-nombre-occurrences-dans-une-table#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/10/21/etude-de-cas-php-mysql-connaitre-le-nombre-occurrences-dans-une-table#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/442</wfw:commentRss>
      </item>
    
  <item>
    <title>Étude de cas : Tester si une variable est vide en PHP</title>
    <link>http://methylbro.titaxium.org/post/2009/10/21/etude-de-cas-tester-si-une-variable-est-vide-en-php</link>
    <guid isPermaLink="false">urn:md5:d01c261c9515babefef53f8a08852779</guid>
    <pubDate>Wed, 21 Oct 2009 08:00:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>empty</category><category>php</category><category>variable</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/php.png&quot; alt=&quot;Étude de cas : Tester si une variable est vide en PHPune &quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Comme je vous l'ai déjà dit &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/10/20/etude-de-cas-stocker-une-date-dans-le-systeme-de-fichiers-en-php&quot; title=&quot;Étude de cas : Stocker une date dans le système de fichiers en PHP&quot;&gt;hier&lt;/a&gt;, je suis en train de devoir modifier toute une série de script écrit en PHP par d'autres développeurs. &lt;/p&gt;
&lt;p&gt;Si hier l'inutilité d'ouvrir des flux à tout bout de champ vers des fichiers m'a pour le moins amusé, aujourd'hui je commence à être agacé par tout ce que je peu voir. &lt;/p&gt;    &lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/2009-10-21-etude-de-cas-tester-si-une-variable-est-vide-en-php.jpg&quot; alt=&quot;Étude de cas : Tester si une variable est vide en PHP&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Pour tester si une variable est vide, beaucoup trop souvent les jeunes développeurs s'arrêtent à la solution suivante : &lt;/p&gt;
&lt;code&gt;if ($myVar==&quot;&quot;) &lt;br /&gt;
echo 'ma variable est vide';&lt;/code&gt;
&lt;p&gt;Alors qu'en réalité l'assertion &lt;em&gt;$myVar==&quot;&quot;&lt;/em&gt; ne signifie pas du tout &lt;q&gt;la variable $myVar est vide&lt;/q&gt; mais &lt;q&gt;la variable $myVar est une chaîne de caractères vide&lt;/q&gt;.&lt;/p&gt;
&lt;p&gt;On trouve ce genre d'assertion partout dans beaucoup de script. Pourtant qu'adviendrait il de notre script si &lt;em&gt;$myVar&lt;/em&gt; avait une valeur à &lt;em&gt;entier:0&lt;/em&gt; dès le départ ?&lt;/p&gt;
&lt;code&gt;$myVar = 0;&lt;br /&gt;
if ($myVar==&quot;&quot;)&lt;br /&gt;
echo 'ma variable est vide';&lt;/code&gt;
&lt;p&gt;Ou mieux, si &lt;em&gt;$myVar&lt;/em&gt; était &lt;em&gt;null&lt;/em&gt; ? &lt;/p&gt;
&lt;code&gt;$myVar = null;&lt;br /&gt;
if ($myVar==&quot;&quot;)&lt;br /&gt;
echo 'ma variable est vide';&lt;/code&gt;
&lt;p&gt;Pourtant dans ce dernier cas, &lt;em&gt;$myVar&lt;/em&gt; est réellement vide, puisqu'elle n'a aucune valeur. Mais l'assertion &lt;em&gt;$myVar==&quot;&quot;&lt;/em&gt; ne se vérifie pas. Donc peut on considérer que &lt;em&gt;$myVar==&quot;&quot;&lt;/em&gt; signifie que &lt;q&gt;$myVar est une variable vide&lt;/q&gt; ?&lt;/p&gt;
&lt;p&gt;Si vous souhaitez tester si une variable &lt;q&gt;est vide&lt;/q&gt;, utilisez plutôt la fonction &lt;a href=&quot;http://fr.php.net/manual/fr/function.empty.php&quot;&gt;empty()&lt;/a&gt; :&lt;/p&gt;
&lt;code&gt;if (empty($myVar))&lt;br /&gt;
echo 'ma variable est vide';&lt;/code&gt;
&lt;p&gt;Si vous considérez une chaîne de caractères composée seulement d'espace comme vide, vous pouvez alors utiliser la fonction &lt;a href=&quot;http://fr.php.net/manual/fr/function.trim.php&quot;&gt;trim()&lt;/a&gt; au préalable. Prenons un exemple concret trouvé dans le script qui m'a inspiré ce billet : &lt;/p&gt;
&lt;code&gt;if ($nick != &quot;&quot; &amp;amp;&amp;amp; $text != &quot;&quot; &amp;amp;&amp;amp; $nick != &quot; &quot; &amp;amp;&amp;amp; $text != &quot; &quot;) {}&lt;/code&gt;
&lt;p&gt;Nous effacerons les espaces en début et fin de chaîne avec la fonction &lt;strong&gt;trim()&lt;/strong&gt; avant de tester le résultat avec &lt;strong&gt;empty()&lt;/strong&gt; dans une condition :&lt;/p&gt;
&lt;code&gt;$nick = trim($nick, ' ');&lt;br /&gt;
$text = trim($text, ' ');&lt;br /&gt;
if (!empty($nick) &amp;amp;&amp;amp; !empty($text)) {}&lt;/code&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/10/21/etude-de-cas-tester-si-une-variable-est-vide-en-php#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/10/21/etude-de-cas-tester-si-une-variable-est-vide-en-php#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/441</wfw:commentRss>
      </item>
    
  <item>
    <title>Étude de cas : Stocker une date dans le système de fichiers en PHP</title>
    <link>http://methylbro.titaxium.org/post/2009/10/20/etude-de-cas-stocker-une-date-dans-le-systeme-de-fichiers-en-php</link>
    <guid isPermaLink="false">urn:md5:d1bc1a35019faf8ba87c245f9ef306c8</guid>
    <pubDate>Tue, 20 Oct 2009 08:00:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>date</category><category>fichier</category><category>php</category><category>stat</category><category>touch</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/php.png&quot; alt=&quot;Étude de cas : Stocker une date dans le système de fichiers en PHP&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;En travaillant sur un script écrit par quelqu'un d'autre, j'ai eu l'idée de ce petit tutoriel. En effet au sein d'un script que j'ai du modifier j'ai découvert une portion de code qui m'a quelque peut alerté.&lt;/p&gt;
&lt;p&gt;Nous allons voir comment le développeur aurait pu résoudre son problème avec une solution alternative. &lt;/p&gt;
&lt;p&gt;Dans notre exemple nous devrons stocker une date dans le système de fichiers côté serveur puis pouvoir venir la récupérer et la mettre à jour lors d'une autre exécution du script. &lt;/p&gt;    &lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.php.net/manual/fr/ref.filesystem.php&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/2009-10-20-etude-de-cas-stocker-une-date-dans-le-systeme-de-fichiers-en-php.jpg&quot; alt=&quot;Étude de cas : Stocker une date dans le système de fichiers en PHP&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Voici mot pour mot la solution qui a été retenue par le développeur dont j'ai du modifier le script : &lt;/p&gt;
&lt;code&gt;// Ecriture de l'heure courante dans fichier, pour comparaison ulterieure&lt;br /&gt;
$fichier_memoire = &quot;memoire.db&quot;;&lt;br /&gt;
&lt;br /&gt;
// Lecture de la derniere heure sauvegardee&lt;br /&gt;
// Ajouter protections&lt;br /&gt;
$fp_l = fopen($fichier_memoire, 'r');&lt;br /&gt;
$last_date = fread($fp_l, 6);&lt;br /&gt;
$suc=fclose ($fp_l);&lt;br /&gt;
&lt;br /&gt;
// L'heure courante brute //&lt;br /&gt;
$date_propre = date('H:i');&lt;br /&gt;
&lt;br /&gt;
$fp_m=fopen($fichier_memoire, w);&lt;br /&gt;
$suc=fputs($fp_m, &quot;$date_propre&quot;);&lt;br /&gt;
$suc=fclose ($fp_m);&lt;/code&gt;
&lt;p&gt;Comme vous pourrez le voir, l'opération se déroule en deux temps :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;d'abord on ouvre un flux en lecture vers le fichier pour récupérer la date stockée comme une chaîne de caractère en son sein&lt;/li&gt;
&lt;li&gt;ensuite on ouvre un flux en écriture seule vers le fichier pour venir enregistrer la date à l'intérieur comme une chaîne de caractères&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ce que je reproche à cette méthode, c'est d'ouvrir inutilement et à deux reprises un flux vers le fichier (d'abord en lecture puis en écriture). &lt;/p&gt;
&lt;p&gt;En effet le système de fichier nous propose déjà d'obtenir toute une foule d'information avant même d'ouvrir celui-ci. Son nom, le nom de son propriétaire, sa taille, sa date de création, sa date de dernière modification etc. &lt;/p&gt;
&lt;p&gt;Pourquoi alors ne pas utiliser directement ces informations ? Cela nous éviterais d'avoir ouvrir notre fichier. &lt;/p&gt;
&lt;p&gt;Pour cela je vais vous proposer d'utiliser la date de dernière modification pour stocker l'information qui nous intéresse. &lt;/p&gt;
&lt;code&gt;// format de date que l'on utilisera à l'affichage&lt;br /&gt;
define('DATE_FORMAT', 'Y/d/m H:i:s');&lt;br /&gt;
// nom du fichier &lt;br /&gt;
$filename  = 'filetest';  &lt;br /&gt;
// ensemble des informations sur le fichier&lt;br /&gt;
$fileinfos = stat($filename);&lt;br /&gt;
// date de dernière modification que l'on donnera au fichier &lt;br /&gt;
$time = time(); &lt;br /&gt;
&lt;br /&gt;
// Si le fichier existe déjà, on montre ca date de dernière modification&lt;br /&gt;
if (file_exists($filename))&lt;br /&gt;
echo 'last update : '.date(DATE_FORMAT, $fileinfos['mtime']).'&lt;br /&gt;';&lt;br /&gt;
&lt;br /&gt;
// On modifie la date de dernière modification du fichier&lt;br /&gt;
// Si ce dernier n'existe pas, on le crée&lt;br /&gt;
if (touch($filename, $time))&lt;br /&gt;
echo 'update on : '.date(DATE_FORMAT, $time);&lt;/code&gt;
&lt;p&gt;Pour stocker une date dans le système de fichier afin de revenir la chercher plus tard, quelle solution préférait vous ? Ouvrir toute une série de flux vers le fichier ou manipuler directement les informations relatives à ce dernier ?&lt;/p&gt;
&lt;h3&gt;A lire également sur le sujet&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.php.net/manual/fr/ref.filesystem.php&quot;&gt;Fonctions sur les systèmes de fichiers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.php.net/manual/fr/function.stat.php&quot;&gt;Manuel de la fonction stat()&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.php.net/manual/fr/function.touch.php&quot;&gt;Manuel de la fonction touch()&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/10/20/etude-de-cas-stocker-une-date-dans-le-systeme-de-fichiers-en-php#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/10/20/etude-de-cas-stocker-une-date-dans-le-systeme-de-fichiers-en-php#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/440</wfw:commentRss>
      </item>
    
  <item>
    <title>Chargement de fichiers (3/3) - par la méthode PUT</title>
    <link>http://methylbro.titaxium.org/post/2009/10/10/chargement-de-fichiers-3-3-par-la-methode-put</link>
    <guid isPermaLink="false">urn:md5:674153e5a362388da1ecf8547fd79a17</guid>
    <pubDate>Sat, 10 Oct 2009 08:00:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>apache</category><category>fichier</category><category>php</category><category>upload</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/files-upload.png&quot; alt=&quot;Chargement de fichiers (3/3) - par la méthode PUT&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Nous avons vu comment faire du charment de fichier avec la méthode POST dans le dernier billet. Pourtant, comme nous l'avons vus dans le tutoriel sur le protocole HTTP ; faire de la création de ressources (et donc de l'envoi de fichier) avec la méthode POST fonctionne, mais ce c'est pas le top. &lt;/p&gt;
&lt;p&gt;La marche a suivre passe alors par l'utilisation de la méthode HTTP PUT. C'est sur cette dernière que nous allons nous pencher aujourd'hui. Nous verrons alors que, encore trop peu de navigateurs supportent la méthode PUT et pour des raisons de sécurité, JavaScript ne vous facilitera pas forcément la vie pour pouvoir proposer une alternative aux browsers ne prenant pas en charge cette méthode. &lt;/p&gt;    &lt;h3&gt;Chargement de fichiers par la méthode PUT&lt;/h3&gt;
&lt;p&gt;Comme nous l'avons vu dans notre étude du protocole HTTP, chaque action à réaliser sur le serveur possède idéalement une méthode propre. GET pour la lecture, POST pour la modification, DELETE pour la suppression, HEAD pour avoir les en-têtes d'un document ainsi que PUT pour la création de nouvelles ressources. &lt;/p&gt;
&lt;h4&gt;Côté client&lt;/h4&gt;
&lt;p&gt;Idéalement donc, nous ne devrions donc pas utiliser la méthode POST pour envoyer des fichiers (du moins, lors de la création de ressources) mais la méthode PUT. Le formulaire idéal que nous devrions posséder pour la création d'une nouvelle ressource devrait donc avoir la forme suivante : &lt;/p&gt;
&lt;code&gt;&amp;lt;form method=&quot;put&quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;label for=&quot;titre&quot;&amp;gt;Titre&amp;lt;/label&amp;gt;&lt;br /&gt;
&amp;lt;input type=&quot;text&quot; id=&quot;titre&quot; name=&quot;titre&quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;label for=&quot;image&quot;&amp;gt;Image&amp;lt;/label&amp;gt;&lt;br /&gt;
&amp;lt;input type=&quot;file&quot; id=&quot;image&quot; name=&quot;image&quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;input type=&quot;submit&quot; value=&quot;ajouter&quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;/code&gt;
&lt;p&gt;Malheureusement, nous ne pourrons commencer à voir apparaître ce genre de formulaires qu'avec HTML5.
&lt;/p&gt;
&lt;h5&gt;Une surcouche simple avec JavaScript ?&lt;/h5&gt;
&lt;p&gt;En attendant la sortie de HTML5 et donc le support de la méthode PUT, nous pourrions créer des surcouches simple en JavaScript pour envoyer nos fichiers. En effet la fameuse interface XMLHTTPRequest de JavaScript (à l'origine de ce que l'on appelle AJAX) implémente elle toutes les méthodes du protocole HTTP.&lt;/p&gt;
&lt;p&gt;Il suffirait donc de créer un formulaire de ce type :&lt;/p&gt;
&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&amp;gt;&lt;br /&gt;
&amp;lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;fr&quot; lang=&quot;fr&quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Upload&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset= utf-8&quot; /&amp;gt;&lt;br /&gt;
&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;&lt;br /&gt;
window.onload = function() {&lt;br /&gt;
document.getElementById(&quot;test&quot;).onsubmit = function() {&lt;br /&gt;
var xhr = null;&lt;br /&gt;
if(window.XMLHttpRequest)&lt;br /&gt;
xhr = new XMLHttpRequest();&lt;br /&gt;
else if(window.ActiveXObject){&lt;br /&gt;
try {&lt;br /&gt;
xhr = new ActiveXObject(&quot;Msxml2.XMLHTTP&quot;);&lt;br /&gt;
} catch (e) {&lt;br /&gt;
xhr = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);&lt;br /&gt;
}&lt;br /&gt;
} else {&lt;br /&gt;
alert(&quot;Votre navigateur ne supporte pas les objets XMLHTTPRequest...&quot;);&lt;br /&gt;
xhr = false;&lt;br /&gt;
}&lt;br /&gt;
xhr.onreadystatechange = function() {&lt;br /&gt;
if(xhr.readyState == 4) {&lt;br /&gt;
if (xhr.status == 200) {&lt;br /&gt;
this.innerHTML = &quot;Le fichier &quot;+this.fichier.value+&quot; a bien ete charge&quot;;&lt;br /&gt;
} else {&lt;br /&gt;
this.innerHTML = &quot;Impossible de charger le fichier &quot;+this.fichier.value;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
xhr.open(&quot;PUT&quot;, &quot;script.php&quot;, false);&lt;br /&gt;
xhr.send(this.fichier);&lt;br /&gt;
return false;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;form method=&quot;put&quot; id=&quot;test&quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;label for=&quot;fichier&quot;&amp;gt;Fichier&amp;lt;/label&amp;gt;&lt;br /&gt;
&amp;lt;input type=&quot;file&quot; id=&quot;fichier&quot; name=&quot;fichier&quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;input type=&quot;submit&quot; value=&quot;envoyer&quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;
&lt;p&gt;Cependant cette solution se borne à un problème de sécurité de taille. Il est impossible en JavaScript de pouvoir lire le contenu du fichier appartenant encore au client. Il existe cependant des astuces pour palier à ce problème. Mais les mettre en place relève du calvaire. &lt;/p&gt;
&lt;h5&gt;Ressources utiles sur le sujet&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.xorax.info/blog/programmation/114-input-file-iframe.html&quot; target=&quot;_blank&quot;&gt;http://www.xorax.info/blog/programmation/114-input-file-iframe.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.xorax.info/blog/programmation/127-ajax-upload-input-file.html&quot; target=&quot;_blank&quot;&gt;http://www.xorax.info/blog/programmation/127-ajax-upload-input-file.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Côté serveur&lt;/h3&gt;
&lt;p&gt;Côté serveur néanmoins, les choses sont plus simples. Car le duo Apache/PHP permet d'implémenter facilement le traitement des requêtes de type PUT voire DELETE aussi d'ailleurs. &lt;/p&gt;
&lt;h4&gt;La directive Script d'Apache&lt;/h4&gt;
&lt;p&gt;La première chose à faire si vous souhaitez que votre script réponde à des requêtes HTTP avec la méthode PUT sera de signaler à Apache ce qu'il doit faire lorsqu'on lui demandera de traiter une telle requête. Nous utiliserons pour cela la directive « Script » d'Apache.&lt;/p&gt;
&lt;p&gt;Vous pouvez placer cette directive n'importe où dans votre fichier de configuration d'Apache. Généralement on l'insère dans un bloc &amp;lt;Directory&amp;gt; ou parfois même directement dans un &amp;lt;VirtualHost&amp;gt;.&lt;/p&gt;
&lt;p&gt;Nous allons voir un exemple simple, permettant de charger un fichier. A chaque utilisation de la méthode PUT, nous demanderons donc à Apache d'exécuter le fichier « put.php » : &lt;/p&gt;
&lt;code&gt;Script PUT /put.php&lt;/code&gt;
&lt;h4&gt;Traitement de la méthode PUT en PHP&lt;/h4&gt;
&lt;p&gt;Une fois Apache configuré pour exécuter notre script lors d'une requête avec la méthode PUT il n'y a rien de plus simple à traiter en PHP.&lt;/p&gt;
&lt;p&gt;Il suffit de lire le flux entrant qui contiendra les données du fichier, puis d'aller les écrire dans un fichier de destination sur le serveur. &lt;/p&gt;
&lt;code&gt;$putdata = fopen(&quot;php://input&quot;, &quot;r&quot;);&lt;br /&gt;
$fp = fopen(&quot;myputfile.ext&quot;, &quot;w&quot;);&lt;br /&gt;
and write to the file */&lt;br /&gt;
while ($data = fread($putdata, 1024))&lt;br /&gt;
fwrite($fp, $data);&lt;br /&gt;
fclose($fp);&lt;br /&gt;
fclose($putdata);&lt;br /&gt;
&lt;/code&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/10/10/chargement-de-fichiers-3-3-par-la-methode-put#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/10/10/chargement-de-fichiers-3-3-par-la-methode-put#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/394</wfw:commentRss>
      </item>
    
  <item>
    <title>Chargement de fichiers (2/3) - par la méthode POST</title>
    <link>http://methylbro.titaxium.org/post/2009/10/03/chargement-de-fichiers-2-3-par-la-methode-post</link>
    <guid isPermaLink="false">urn:md5:378ca1ce646eac1a106711dcae6a50b3</guid>
    <pubDate>Sat, 03 Oct 2009 08:00:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
            
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/files-upload.png&quot; alt=&quot;Chargement de fichiers (2/3) - par la méthode POST&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Voyons aujourd’hui la deuxième partie du tutoriel sur le chargement de fichiers avec PHP. &lt;/p&gt;

&lt;p&gt;Aujourd’hui nous allons voir comment mettre en place un formulaire permettant de charger un fichier vers un serveur en utilisant la méthode POST. C’est la méthode la plus classique cependant comme je l’ai dit lors de l’introduction ; nous verrons également comment implémenter la méthode PUT.&lt;/p&gt;    &lt;h3&gt;Chargement de fichier par la méthode POST&lt;/h3&gt;
&lt;p&gt;Le chargement de fichier tel que nous le connaissons le plus couramment à été introduit en novembre 1995 par la RFC-1867. Si vous souhaitez plus de détails sur le fonctionnement de cette méthode je vois renvois directement vers la &lt;acronym title=&quot;Request For Comment&quot;&gt;RFC&lt;/acronym&gt;. Dans notre article nous ne verrons que comment mettre tout cela en œuvre au sein d'un l'environnement &lt;acronym title=&quot;Apache MySQL PHP&quot;&gt;AMP&lt;/acronym&gt;.&lt;/p&gt;
&lt;p&gt;Nous réaliserons l'étude de cas suivante à titre d'exemple : &lt;/p&gt;
&lt;p&gt;A souhaite pouvoir charger des fichiers dans le répertoire &lt;em&gt;/upload/&lt;/em&gt; de son site internet via un simple formulaire disponible depuis son navigateur. &lt;/p&gt;
&lt;p&gt;Nous utiliserons l'arborescence de la figure 1-1. Le répertoire &lt;em&gt;/upload/&lt;/em&gt; contiendra les fichiers chargés par le visiteur, le fichier &lt;em&gt;/upload.php&lt;/em&gt; contiendra le formulaire ainsi que le script &lt;acronym title=&quot;PHP HyperText Preprocessor&quot;&gt;PHP&lt;/acronym&gt; permettant le chargement des images. Quand au fichier &lt;em&gt;/.htaccess&lt;/em&gt; il pourra nous permettre de modifier certaines valeurs par défaut de PHP un peu gênante que nous verrons plus bas.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/upload/arborescence.jpg&quot; alt=&quot;Figure 1-1 : Arborescence &quot; /&gt;&lt;br /&gt;Figure 1-1 : Arborescence &lt;/p&gt;
&lt;h4&gt;Le formulaire HTML&lt;/h4&gt;
&lt;p&gt;Comme nous l'avons abordé plus haut,  l'envoi de fichier via la méthode POST est décrit par la RFC-1867. Comme exposé au sein de la RFC, côté &lt;acronym title=&quot;Hyper Text Markup Language&quot;&gt;HTML&lt;/acronym&gt; nous devons résoudre 3 impératifs :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;que notre formulaire utilise la méthode POST &lt;/li&gt;
&lt;li&gt;que l'attribut « enctype » de notre balise « form » prenne la valeur « multipart/form-data »&lt;/li&gt;
&lt;li&gt;que le champ accueillant le fichier à envoyer soit de type « file »&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pour résoudre proprement notre étude de cas, nous ajouterons aussi un petit message de retour, pour indiquer si le chargement c'est bien passé, s'il a échoué … Ce message sera géré en PHP et stocké dans la variable $information. &lt;/p&gt;
&lt;p&gt;Voici donc une première partie de notre fichier &lt;em&gt;upload.php&lt;/em&gt; :&lt;/p&gt;
&lt;code&gt;&amp;lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot;&lt;br /&gt;
&quot;http://www.w3.org/TR/html4/strict.dtd&quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf8&quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Chargement de Fichiers&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;form method=&quot;post&quot; enctype=&quot;multipart/form-data&quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;?php echo $information; ?&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;label for=&quot;fichier&quot;&amp;gt;Fichier à envoyer :&amp;lt;/label&amp;gt;&lt;br /&gt;
&amp;lt;input type=&quot;file&quot; id=&quot;fichier&quot; name=&quot;fichier&quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
&amp;lt;input type=&quot;submit&quot; value=&quot;Envoyer&quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;
&lt;p&gt;Notre formulaire sera donc très simple et ressemblera à quelque chose comme le montre la figure 1-2. Remarquez que le navigateur s'occupe lui-même de proposer un champ parcourable au visiteur pour que celui-ci puisse sélectionner le fichier de son choix. &lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/upload/formulaire.jpg&quot; alt=&quot;Figure 1-2 : Le formulaire&quot; /&gt;&lt;br /&gt;Figure 1-2 : Le formulaire&lt;/p&gt;
&lt;h4&gt;Traiter le formulaire en PHP&lt;/h4&gt;
&lt;p&gt;Maintenant que nous avons rédigé notre formulaire ; nous allons voir comment en lire les données une fois celui-ci envoyé. Si les données traditionnelles envoyées depuis des formulaires avec la méthode POST sont lues la superglobale $_POST ; les choses sont un peu différentes concernant les champs de type file &lt;/p&gt;
&lt;h5&gt;lors de la validation du formulaire&lt;/h5&gt;
&lt;p&gt;Lors de la validation du formulaire, le client va envoyer le fichier à l'aide de son navigateur. PHP et apache viendrons alors placer ce fichier dans un répertoire temporaire. C'est l'étape 1 que vous pouvez retrouver sur la figure 2-1. &lt;/p&gt;
&lt;p&gt;Ce fichier sera conservé à cet endroit durant toute l'exécution du script uniquement. Une fois le script achevé et pour des raisons de sécurités évidentes le fichier sera supprimé de cet emplacement. &lt;/p&gt;
&lt;p&gt;Vous pouvez connaître le nom du répertoire utilisé comme répertoire temporaire via la directive upload_tmp_dir du php.ini. Généralement il s'agit par défaut de &lt;em&gt;/tmp/&lt;/em&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/upload/fonctionnement-upload.jpg&quot; alt=&quot;Figure 2-1 : Déplacements du fichier&quot; /&gt;&lt;br /&gt;Figure 2-1 : Déplacements du fichier&lt;/p&gt;
&lt;p&gt;Comprenez bien que vous devez donc, déplacer le fichier et l'enregistrer ailleurs si vous souhaitez conserver celui-ci après la fin de l'exécution du script. C'est ce que nous allons écrire en PHP. &lt;/p&gt;
&lt;p&gt;Dans notre étude de cas, nous voulons stocker nos fichiers dans le répertoire &lt;em&gt;/upload/&lt;/em&gt; ; nous devrons donc déplacer notre fichier du répertoire temporaire pour le placer dans le répertoire &lt;em&gt;/upload/&lt;/em&gt;. C'est la deuxième étape représentée sur la figure 2-1.&lt;/p&gt;
&lt;h5&gt;la super globale $_FILES&lt;/h5&gt;
&lt;p&gt;Pour lire un les données associés aux champs de type file depuis un script PHP, vous devrez utiliser la superglobale $_FILES. Il s'agit d'un tableau multidimensionnel contenant à son premier niveau, un indice par fichier envoyé via un champ de formulaire de type file. Le nom de l'indice correspond a la valeur de l'attribut « name » de votre formulaire. &lt;/p&gt;
&lt;p&gt;Si nous reprenons notre étude de cas, la superglobale $_FILES contiendra donc un indice nommé « fichier ». $_FILES['fichier'] sera donc égal à un tableau contenant un ensemble de valeurs qui nous informera sur le fichier concerné.&lt;/p&gt;
&lt;p&gt;Le tableau que vous trouverez dans $_FILES['fichier'], ou dans $_FILES[{n'importe quel fichier}] contiendra les valeurs suivantes :&lt;/p&gt;
&lt;table align=&quot;center&quot; width=&quot;90%&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope=&quot;col&quot;&gt;Indice&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;name&lt;/td&gt;
&lt;td&gt;Le nom original du fichier, tel que sur la machine du client web.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;type&lt;/td&gt;
&lt;td&gt;Le type MIME du fichier, si le navigateur a fourni cette information. Par exemple, cela pourra être &quot;image/gif&quot;. Ce type mime n'est cependant pas vérifié du côté de PHP et, donc, ne prend pas sa valeur pour se synchroniser.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;size&lt;/td&gt;
&lt;td&gt;La taille, en octets, du fichier téléchargé.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tmp_name&lt;/td&gt;
&lt;td&gt;Le nom temporaire du fichier qui sera chargé sur la machine serveur&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;error&lt;/td&gt;
&lt;td&gt;Le code d'erreur  associé au téléchargement de fichier. Cet élément a été introduit en PHP 4.2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Pour information, sachez que $_FILES n'est utilisé que depuis PHP4.1, avant il fallait utiliser $HTTP_POST_FILES mais considérez ce dernier comme obsolète. &lt;/p&gt;
&lt;h5&gt;les différentes erreurs&lt;/h5&gt;
&lt;p&gt;Comme vous venez de le voir, le tableau $_FILES['fichier'] contient un indice « error » qui permet de connaître le statut du téléchargement du fichier associé. &lt;/p&gt;
&lt;p&gt;Voici un tableau récapitulatif des valeurs possible que vous pourrez rencontrer :&lt;/p&gt;
&lt;table align=&quot;center&quot; width=&quot;90%&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope=&quot;col&quot;&gt;Constante&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Valeur&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UPLOAD_ERR_OK&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Aucune erreur, le téléchargement est correct&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UPLOAD_ERR_INI_SIZE&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Le fichier téléchargé excède la taille de upload_max_filesize, configurée dans le php.ini&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UPLOAD_ERR_FORM_SIZE&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Le fichier téléchargé excède la taille de MAX_FILE_SIZE, qui a été spécifiée dans le formulaire HTML.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UPLOAD_ERR_PARTIAL&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Le fichier n'a été que partiellement téléchargé&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UPLOAD_ERR_NO_FILE&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Aucun fichier n'a été téléchargé&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UPLOAD_ERR_NO_TMP_DIR&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Un dossier temporaire est manquant. Introduit en PHP 4.3.10 et PHP 5.0.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UPLOAD_ERR_CANT_WRITE&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Échec de l'écriture du fichier sur le disque. Introduit en PHP 5.1.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UPLOAD_ERR_EXTENSION&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;L'envoi de fichier est arrêté par l'extension. Introduit en PHP 5.2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5&gt;le code PHP&lt;/h5&gt;
&lt;p&gt;Maintenant que nous avons vu ensemble l'essentiel sur ce que vous devait savoir, je vais vous proposer la suite et fin de notre petit exemple : la partie concernant les traitements en PHP. Vous pourrez également trouver l'ensemble des sources concernant notre étude de cas en annexe à ce tutoriel.&lt;/p&gt;
&lt;p&gt;Notre traitement en PHP va se diviser en 3 actions simples à réaliser :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;vérifier que le formulaire a bien été envoyé&lt;/li&gt;
&lt;li&gt;vérifier que le fichier à bien été chargé dans le répertoire temporaire&lt;/li&gt;
&lt;li&gt;déplacer le fichier vers le répertoire &lt;em&gt;/upload/&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Bien évidement, comme nous l'avons vu lors de la création du formulaire plus haut, tout au long de ces traitements nous prendrons soin en cas d'erreur d'en avertir l'utilisateur final à l'aide de la variable &lt;em&gt;$information&lt;/em&gt;. &lt;/p&gt;
&lt;code&gt;$upload_path = 'upload/';&lt;br /&gt;
if (isset($_FILES['fichier'])) {&lt;br /&gt;
if ($_FILES['fichier']['error']===UPLOAD_ERR_OK) {&lt;br /&gt;
$filename = $upload_path.$_FILES['fichier']['name'];&lt;br /&gt;
if (move_uploaded_file($_FILES['fichier']['tmp_name'], $filename)) {&lt;br /&gt;
$information = 'Le fichier à bien été enregistré';&lt;br /&gt;
} else {&lt;br /&gt;
$information = 'Impossible d\'enregistrer le fichier';&lt;br /&gt;
}&lt;br /&gt;
} else {&lt;br /&gt;
$information = 'Impossible de charger le fichier. Code d\'erreur #'.$_FILES['fichier']['error'];&lt;br /&gt;
}&lt;br /&gt;
} else {&lt;br /&gt;
$information = 'Selectionner le fichier a envoyer';&lt;br /&gt;
}&lt;/code&gt;
&lt;h4&gt;Annexe&lt;/h4&gt;
&lt;h5&gt;informations à connaître&lt;/h5&gt;
&lt;p&gt;Allez donc faire un tour sur la documentation PHP, et regardez les choses suivantes concernant le chargement de fichier par la méthode POST :&lt;/p&gt;
&lt;p&gt;Directives dans le php.ini :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://fr.php.net/manual/fr/ini.core.php#ini.file-uploads&quot;&gt;file_uploads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://fr.php.net/manual/fr/ini.core.php#ini.upload-max-filesize&quot;&gt;upload_max_filesize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://fr.php.net/manual/fr/ini.core.php#ini.upload-tmp-dir&quot;&gt;upload_tmp_dir&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://fr.php.net/manual/fr/ini.core.php#ini.post-max-size&quot;&gt;post_max_size&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://fr.php.net/manual/fr/info.configuration.php#ini.max-input-time&quot;&gt;max_input_time&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Fonctions à connaître :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://fr.php.net/manual/fr/function.is-uploaded-file.php&quot;&gt;is_uploaded_file()&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://fr.php.net/manual/fr/function.move-uploaded-file.php&quot;&gt;move_uploaded_file()&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Une piste si vous souhaitez implémenter une barre de progression : &lt;a href=&quot;http://fr.php.net/manual/fr/apc.configuration.php#ini.apc.rfc1867&quot;&gt;apc.rfc1867&lt;/a&gt;&lt;/p&gt;
&lt;h5&gt;upload_max_filesize&lt;/h5&gt;
&lt;p&gt;PHP a besoin d'une limite de taille pour les fichiers envoyés via cette méthode. Généralement dans la plupart des configuration par défaut cette limite peut parfois être trop basse, empêchant ainsi vos utilisateurs de charger des fichiers un minimum conséquents (comme un gros fichier word, ou une image haute définition par exemple).&lt;/p&gt;
&lt;p&gt;En théorie ce genre de problème est forcé de vous arriver au moins une fois pendant votre vie. Sachez que vous pouvez vous-même modifier la taille maximum des fichiers via la directive PHP upload_max_filesize.&lt;/p&gt;
&lt;p&gt;Pour modifier cette valeur, vous pouvez par exemple la changer depuis un fichier .htaccess placé dans le répertoire contenant votre script PHP. Ajouter simplement les lignes suivantes dans le fichier (xxxxx étant la nouvelle valeur que vous souhaitez attribuer. Il s'agit du nombre d'octet maximum que peut représenter un fichier chargé) :&lt;/p&gt;
&lt;code&gt;php_value upload_max_filesize xxxxx&lt;/code&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Comme nous avons pu le voir, PHP implémente de façon plus que satisfaisante la RFC-1867 ce qui nous permet, couplé avec du HTML, de proposer aux utilisateurs de nos applications un moyen de pouvoir saisir des fichiers.&lt;/p&gt;
&lt;p&gt;Le tout malgré la faiblesse de HTML 4 qui n'implémente aucun support de la méthode HTTP PUT dont le rôle est dédié à la création de nouvelles ressources.&lt;/p&gt;
&lt;p&gt;Cependant le support de la méthode PUT est à l'ordre du jour si l'on en crois le brouillon de HTML 5 publié par le W3C. Dans un futur proche, nous pourrions donc implémenté des formulaire avec la méthode PUT au sein de nos pages web sans avoir à ajouter de sur-couche en JavaScript comme c'est le cas actuellement.&lt;/p&gt;</description>
    
          <enclosure url="http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/upload/exemple-complet.rar"
      length="801" type="application/rar" />
    
    
          <comments>http://methylbro.titaxium.org/post/2009/10/03/chargement-de-fichiers-2-3-par-la-methode-post#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/10/03/chargement-de-fichiers-2-3-par-la-methode-post#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/393</wfw:commentRss>
      </item>
    
  <item>
    <title>Chargement de fichiers (1/3) - Introduction</title>
    <link>http://methylbro.titaxium.org/post/2009/10/02/chargement-de-fichiers-1-3-introduction</link>
    <guid isPermaLink="false">urn:md5:e9ed555db4da9d98c237aee24b1f517b</guid>
    <pubDate>Fri, 02 Oct 2009 08:00:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
            
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/files-upload.png&quot; alt=&quot;Chargement de fichiers (1/3) - Introduction&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Je vais publier à partir d'aujourd'hui et dans les jours qui viennent une série de 3 billets qui ensemble formeront un tutoriel sur le chargement de fichier avec PHP. &lt;/p&gt;
&lt;p&gt;L'objectif sera double. Essayer de mieux expliquer aux plus novices le fonctionnement du chargement de fichiers par la méthode POST ; la méthode la plus classique que l'on connaît tous. Mais également faire ouvrir les yeux sur la possibilité de charger des fichiers proprement selon le protocole HTTP : avec la méthode PUT. &lt;/p&gt;
&lt;p&gt;En espérant que cette petite série de billets vous plaise et surtout qu'elle vous apprennent des choses intéressante.&lt;/p&gt;    &lt;h3&gt;Introduction au chargement de fichiers&lt;/h3&gt;
&lt;p&gt;La plupart des applications que nous avons à produire supposent une certaine interactivité avec les utilisateurs finaux. Ces derniers doivent en effet la plupart du temps saisir toute sortes d'information à un moment donné. &lt;/p&gt;
&lt;p&gt;S'il est facile de maîtriser rapidement l'environnement LAMP pour proposer des formulaires simples permettant aux utilisateurs de saisir des chaînes de caractères ; de faire des choix parmi des listes et etc. Il est néanmoins plus complexe de créer des formulaire capables d'offrir à l'utilisateur d'envoyer par exemple des fichiers entiers.&lt;/p&gt;
&lt;p&gt;Il faut dire que la méthode généralement proposée par la plupart des tutoriaux traitant du sujet n'arrange pas les choses. Si vous vous êtes penchés sur le protocole HTTP comme je vous l'ai invité à le faire, vous comprendrez certainement qu'utiliser la méthode POST pour de l'envoi de fichiers à quelque chose de quelque peut perturbant. &lt;/p&gt;
&lt;p&gt;C'est pourquoi, après avoir revu en profondeur la méthode traditionnelle de chargement de fichiers en PHP nous observerons ensemble comment profiter pleinement des capacités que nous apporte le JavaScript côté client pour palier le non support de la méthode PUT par HTML 4. &lt;/p&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/10/02/chargement-de-fichiers-1-3-introduction#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/10/02/chargement-de-fichiers-1-3-introduction#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/392</wfw:commentRss>
      </item>
    
  <item>
    <title>Ressources HTTP : Champs d'en-tête et codes de retour</title>
    <link>http://methylbro.titaxium.org/post/2009/07/23/ressources-http-champs-d-en-tete-et-codes-de-retour</link>
    <guid isPermaLink="false">urn:md5:c0a9ac9f1705274bf02a445dda600eb1</guid>
    <pubDate>Thu, 23 Jul 2009 08:00:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>code erreur</category><category>http</category><category>protocole</category><category>protocole http</category><category>ressrouces</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/http.jpg&quot; alt=&quot;Le protocole HTTP&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Après avoir vu ensemble comment fonctionne le protocole HTTP au niveau de ses requêtes et de ses résultats ; et avant de concevoir pas à pas un petit client HTTP entièrement écrit en PHP nous allons faire un petit billet de ressources sur le protocole HTTP.&lt;/p&gt;
&lt;p&gt;Dans ce billet j'ai tout simplement listé et classé l'ensemble des champs d'en-tête (de requête et de réponse) que vous pourrez trouvé le plus communément. Bien évidement il ne s'agit pas d'une liste exhaustive car de toute façon il est tout à fait possible pour n'importe qui d'utiliser des champs d'en-tête personnalisés. Pour ma part je laisse régulièrement une signature à mon travail en glissant un petit mot dans les champs de réponse.&lt;/p&gt;
&lt;p&gt;J'y ai glissé également à nouveau un tableau très classique. Il s'agit de la liste des codes de retour HTTP (excluant les codes hérités de WebDav). &lt;/p&gt;    &lt;h3&gt;Les champs d'en-tête HTTP&lt;/h3&gt;
&lt;table&gt;
&lt;caption&gt;Les champs de requête&lt;/caption&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th scope=&quot;col&quot;&gt;Nom du champ&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Accept&lt;/th&gt;
&lt;td&gt;Type de contenu accepté par le navigateur (par exemple text/html, ce sont les codes MIME).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Content-Length&lt;/th&gt;
&lt;td&gt;Longueur du corps de la requête&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Content-Type&lt;/th&gt;
&lt;td&gt;Type de contenu du corps de la requête (par exemple text/html).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Date&lt;/th&gt;
&lt;td&gt;Date de début de transfert des données&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Forwarded&lt;/th&gt;
&lt;td&gt;Utilisé par les proxys entre le navigateur et le serveur&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;From&lt;/th&gt;
&lt;td&gt;Permet de spécifier l'adresse e-mail du client&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Referer&lt;/th&gt;
&lt;td&gt;URL du lien à partir duquel la requête a été effectuée&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;If-Modified-Since&lt;/th&gt;
&lt;td&gt;Dernière date de réception du contenu de la ressource&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Host&lt;/th&gt;
&lt;td&gt;Nom du serveur/domaine de destination&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;User-Agent&lt;/th&gt;
&lt;td&gt;Chaîne donnant des informations sur le client, comme le nom et la version du navigateur, du système d'exploitation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;caption&gt;Les champs de réponses&lt;/caption&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th scope=&quot;col&quot;&gt;Nom de l'en-tête&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Content-Encoding&lt;/th&gt;
&lt;td&gt;Type de codage du corps de la réponse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Content-Language&lt;/th&gt;
&lt;td&gt;Type de langage du corps de la réponse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Content-Length&lt;/th&gt;
&lt;td&gt;Longueur du corps de la réponse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Content-Type&lt;/th&gt;
&lt;td&gt;Type de contenu du corps de la réponse (par exemple text/html).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Date&lt;/th&gt;
&lt;td&gt;Date de début de transfert des données&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Expires&lt;/th&gt;
&lt;td&gt;Date limite de consommation des données&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Forwarded&lt;/th&gt;
&lt;td&gt;Utilisé par les machines intermédiaires entre le browser et le serveur&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Location&lt;/th&gt;
&lt;td&gt;Redirection vers une nouvelle URL associée au document&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;Server&lt;/th&gt;
&lt;td&gt;Caractéristiques du serveur ayant envoyé la réponse&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Les codes de retour HTTP&lt;/h3&gt;
&lt;table&gt;
&lt;caption&gt;Les codes de retour&lt;/caption&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th scope=&quot;col&quot; colspan=&quot;3&quot;&gt;Information&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;100&lt;/th&gt;
&lt;td&gt;Continue&lt;/td&gt;
&lt;td&gt;Attente de la suite de la requête&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;101&lt;/th&gt;
&lt;td&gt;Switching Protocols&lt;/td&gt;
&lt;td&gt;Acceptation du changement de protocole&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;col&quot; colspan=&quot;3&quot;&gt;Succès&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;200&lt;/th&gt;
&lt;td&gt;OK&lt;/td&gt;
&lt;td&gt;Requête traitée avec succès&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;201&lt;/th&gt;
&lt;td&gt;Created&lt;/td&gt;
&lt;td&gt;Requête traitée avec succès avec création d'un document&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;202&lt;/th&gt;
&lt;td&gt;Accepted&lt;/td&gt;
&lt;td&gt;Requête traitée mais sans garantie de résultat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;203
&lt;/th&gt;&lt;td&gt;Non-Authoritative Information&lt;/td&gt;
&lt;td&gt;Information retournée mais générée par une source non certifiée&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;204&lt;/th&gt;
&lt;td&gt;No Content&lt;/td&gt;
&lt;td&gt;Requête traitée avec succès mais pas d'information à renvoyer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;205&lt;/th&gt;
&lt;td&gt;Reset Content&lt;/td&gt;
&lt;td&gt;Requête traitée avec succès, la page courante peut être effacée&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;206&lt;/th&gt;
&lt;td&gt;Partial Content&lt;/td&gt;
&lt;td&gt;Une partie seulement de la requête a été transmise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;col&quot; colspan=&quot;3&quot;&gt;Redirection&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;300&lt;/th&gt;
&lt;td&gt;Multiple Choices&lt;/td&gt;
&lt;td&gt;L'URI demandée se rapporte à plusieurs ressources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;301&lt;/th&gt;
&lt;td&gt;Moved Permanently&lt;/td&gt;
&lt;td&gt;Document déplacé de façon permanente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;302&lt;/th&gt;
&lt;td&gt;Moved Temporarily&lt;/td&gt;
&lt;td&gt;Document déplacé de façon temporaire&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;303&lt;/th&gt;
&lt;td&gt;See Other&lt;/td&gt;
&lt;td&gt;La réponse à cette requête est ailleurs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;304&lt;/th&gt;
&lt;td&gt;Not Modified&lt;/td&gt;
&lt;td&gt;Document non-modifié depuis la dernière requête&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;305&lt;/th&gt;
&lt;td&gt;Use Proxy&lt;/td&gt;
&lt;td&gt;La requête doit être ré-adressée au proxy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;307&lt;/th&gt;
&lt;td&gt;Temporary Redirect&lt;/td&gt;
&lt;td&gt;La requête doit être redirigée temporairement vers l'URI spécifiée&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;col&quot; colspan=&quot;3&quot;&gt;Erreur du client&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;400&lt;/th&gt;
&lt;td&gt;Bad Request&lt;/td&gt;
&lt;td&gt;La syntaxe de la requête est erronée&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;401&lt;/th&gt;
&lt;td&gt;Unauthorized&lt;/td&gt;
&lt;td&gt;Accès à la ressource refusé&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;402&lt;/th&gt;
&lt;td&gt;Payment Required&lt;/td&gt;
&lt;td&gt;Paiement requis pour accéder à la ressource (non utilisé)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;403&lt;/th&gt;
&lt;td&gt;Forbidden&lt;/td&gt;
&lt;td&gt;Refus de traitement de la requête&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;404&lt;/th&gt;
&lt;td&gt;Not Found&lt;/td&gt;
&lt;td&gt;Document non trouvé&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;405&lt;/th&gt;
&lt;td&gt;Method Not Allowed&lt;/td&gt;
&lt;td&gt;Méthode de requête non autorisée&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;406&lt;/th&gt;
&lt;td&gt;Not Acceptable&lt;/td&gt;
&lt;td&gt;Toutes les réponses possibles seront refusées.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;407&lt;/th&gt;
&lt;td&gt;Proxy Authentication Required&lt;/td&gt;
&lt;td&gt;Accès à la ressource autorisé par identification avec le proxy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;408&lt;/th&gt;
&lt;td&gt;Request Time-out&lt;/td&gt;
&lt;td&gt;Temps d'attente d'une réponse du serveur écoulé&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;409&lt;/th&gt;
&lt;td&gt;Conflict&lt;/td&gt;
&lt;td&gt;La requête ne peut être traitée à l'état actuel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;410&lt;/th&gt;
&lt;td&gt;Gone&lt;/td&gt;
&lt;td&gt;La ressource est indisponible et aucune adresse de redirection n'est connue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;411&lt;/th&gt;
&lt;td&gt;Length Required&lt;/td&gt;
&lt;td&gt;La longueur de la requête n'a pas été précisée&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;412&lt;/th&gt;
&lt;td&gt;Precondition Failed&lt;/td&gt;
&lt;td&gt;Préconditions envoyées par la requête non-vérifiées&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;413&lt;/th&gt;
&lt;td&gt;Request Entity Too Large&lt;/td&gt;
&lt;td&gt;Traitement abandonné dû à une requête trop importante&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;414&lt;/th&gt;
&lt;td&gt;Request-URI Too Long&lt;/td&gt;
&lt;td&gt;URI trop longue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;415&lt;/th&gt;
&lt;td&gt;Unsupported Media Type&lt;/td&gt;
&lt;td&gt;Format de requête non-supportée pour une méthode et une ressource données&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;416&lt;/th&gt;
&lt;td&gt;Requested range unsatisfiable&lt;/td&gt;
&lt;td&gt;Champs d'en-tête de requête 'range' incorrect.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;417&lt;/th&gt;
&lt;td&gt;Expectation failed&lt;/td&gt;
&lt;td&gt;Comportement attendu et défini dans l'en-tête de la requête insatisfaisable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;col&quot; colspan=&quot;3&quot;&gt;Erreur du serveur&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;500&lt;/th&gt;
&lt;td&gt;Internal Server Error&lt;/td&gt;
&lt;td&gt;Erreur interne du serveur&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;501&lt;/th&gt;
&lt;td&gt;Not Implemented&lt;/td&gt;
&lt;td&gt;Fonctionnalité réclamée non supportée par le serveur&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;502&lt;/th&gt;
&lt;td&gt;Bad Gateway ou Proxy Error&lt;/td&gt;
&lt;td&gt;Mauvaise réponse envoyée à un serveur intermédiaire par un autre serveur.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;503&lt;/th&gt;
&lt;td&gt;Service Unavailable&lt;/td&gt;
&lt;td&gt;Service indisponible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;504&lt;/th&gt;
&lt;td&gt;Gateway Time-out&lt;/td&gt;
&lt;td&gt;Temps d'attente d'une réponse d'un serveur à un serveur intermédiaire écoulé&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;505&lt;/th&gt;
&lt;td&gt;HTTP Version not supported&lt;/td&gt;
&lt;td&gt;Version HTTP non gérée par le serveur&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/07/23/ressources-http-champs-d-en-tete-et-codes-de-retour#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/07/23/ressources-http-champs-d-en-tete-et-codes-de-retour#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/350</wfw:commentRss>
      </item>
    
  <item>
    <title>Le protocole HTTP : Les Réponses</title>
    <link>http://methylbro.titaxium.org/post/2009/07/21/le-protocole-http-les-reponses</link>
    <guid isPermaLink="false">urn:md5:1aa1d038834eb18c81304950f1d93b36</guid>
    <pubDate>Tue, 21 Jul 2009 08:00:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>code erreur</category><category>http</category><category>protocole</category><category>protocole http</category><category>reponse</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/http.jpg&quot; alt=&quot;Le protocole HTTP : Les Réponses&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Vendredi dernier, je me suis lancé dans la rédaction d'une nouvelle série d'articles dédiés au &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/07/17/a-venir/introduction-au-protocole-http&quot;&gt;protocole HTTP&lt;/a&gt;. Après avoir commencé dimanche à parler des &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/07/19/le-protocole-http-les-requetes&quot;&gt;requêtes&lt;/a&gt; et de tous les éléments qui les composent ; nous allons avoir aujourd'hui comment sont construites les &lt;strong&gt;réponses HTTP&lt;/strong&gt;. &lt;/p&gt;    &lt;h3&gt;Composition d'un résultat HTTP&lt;/h3&gt;
&lt;p&gt;Dans le protocole HTTP on peut considérer que les réponses sont construites à peut de choses prés de la même manière que les requête. On pourra ainsi la découper à nouveau en trois parties bien distinctes. &lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/HTTP/http-reponse.jpg&quot; alt=&quot;Le protocole HTTP : Les Réponses&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Le code de retour&lt;/h4&gt;
&lt;p&gt;La première chose que doit indiquer le serveur au client HTTP c'est si sa commande a bien été effectuée. Il s'agit du code de retour donné en première ligne de la réponse. Cette ligne prendra la forme suivante : &lt;/p&gt;
&lt;code&gt;HTTP/1.1 200 OK&lt;/code&gt;
&lt;p&gt;Reprenant donc la version du protocole utilisé, le code de l'erreur ainsi que sa traduction littérale, ici une réponse favorable indiquant que tout c'est bien passé sans encombres. &lt;/p&gt;
&lt;p&gt;Ce chapitre n'est pas destiné à faire la liste de tous les codes d'erreurs qu'il existe. Je réserve ça pour plus tard. Cependant je suis sur que vous connaissez déjà bon nombre de codes d'erreurs. Qui n'a jamais vu dans son navigateur des pages &quot;404&quot; indiquant que le document n'existe pas ? C'est en réalité ici que sont utilisées ces fameux codes ; en voilà l'explication. &lt;/p&gt;
&lt;h4&gt;En-tête&lt;/h4&gt;
&lt;p&gt;Les réponse HTTP contiennent elles aussi divers champs d'en-tête. Ces derniers permettent de fournir toute sorte d'informations au client. &lt;/p&gt;
&lt;p&gt;Il peut s'agir par exemple du type de serveur HTTP qui a été utilisé pour répondre à la requête (Soit Apache dans mon petit exemple), de la date à laquelle à été générer le document que vous êtes en train de consulter (dans le cas de sites dynamiques) mais on peut y trouver également des informations très intéressante que le serveur fourni au cache de votre navigateur. &lt;/p&gt;
&lt;p&gt;Nous verrons la liste de tous les champs possibles dans un chapitre à venir. Mais bien évidement cette liste n'est pas figée. Vous pouvez tout à fait venir rajouter des champs d'en-tête comme vous le souhaitez.&lt;/p&gt;
&lt;h4&gt;Corps&lt;/h4&gt;
&lt;p&gt;Bien évidement, le résultat d'une requête doit pouvoir contenir également le document que vous avez demandé. Je dit bien &quot;doit pouvoir&quot;, car dans le cas d'une requête avec la méthode HEAD cela ne sera pas le cas. &lt;/p&gt;
&lt;p&gt;Le document est donc fourni à la fin du résultat. Il peut s'agir de n'importe quel type de fichier : document html, image, fichier pdf ou que sais-je encore.&lt;/p&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/07/21/le-protocole-http-les-reponses#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/07/21/le-protocole-http-les-reponses#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/346</wfw:commentRss>
      </item>
    
  <item>
    <title>Le protocole HTTP : Les Requêtes</title>
    <link>http://methylbro.titaxium.org/post/2009/07/19/le-protocole-http-les-requetes</link>
    <guid isPermaLink="false">urn:md5:c91a2ac170f9f454f4eed059b7669240</guid>
    <pubDate>Sun, 19 Jul 2009 08:00:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>http</category><category>méthode</category><category>protocole</category><category>protocole http</category><category>requête</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/http.jpg&quot; alt=&quot;Le Protocole HTTP&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;J'ai abordé dans mon &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/07/17/a-venir/introduction-au-protocole-http&quot;&gt;billet précédent&lt;/a&gt; l'importance et le soin qu'un développeur web doit mettre en oeuvre pour comprendre et maîtriser les différents protocoles qu'il est amené a utilisé. &lt;/p&gt;
&lt;p&gt;J'avais, sans doutes à tord, commencé à parler du &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/07/01/le-protocole-smtp&quot;&gt;protocole SMTP&lt;/a&gt; dans une première série de billets. Mais je vais essayer de corriger un peu cette erreur en publiant maintenant un chapelet de billets sur &lt;strong&gt;le protocole HTTP&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;En effet, la maîtrise de ce &lt;strong&gt;protocole&lt;/strong&gt; est essentielle pour appréhender par la suite bon nombre de problématiques. Qu'il s'agisse de sécurité, de sessions, d'AJAX ou d'architectures relativement complexe de type MVC et etc si dès le départ vous n'êtes pas à l'aise à l'emploi de &lt;strong&gt;HTTP&lt;/strong&gt; ; vous ne parviendrez jamais a maîtriser d'autres concepts plus avancés. &lt;/p&gt;    &lt;h3&gt;HTTP : Un protocole synchrone&lt;/h3&gt;
&lt;p&gt;A l'instar de beaucoup de protocoles de communication (comme l'IMAP par exemple), HTTP est un protocole synchrone. C'est-à-dire que les deux processus d'envoi de requête et de réception de la réponse s'effectuent de manière synchronisée. Chacune étant en lien avec l'autre.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/HTTP/http-client-serveur.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Jusque là rien de bien nouveau a ce que vous avez sans doutes déjà compris auparavant. Seulement la requête n'est pas seulement constituée de l'adresse de la page que vous souhaitez récupérer. De la même façon la réponse elle contient d'autres informations que le simple fichier (généralement un document html) que le client souhaite téléchargée.&lt;/p&gt;
&lt;p&gt;Nous allons donc commencer par voir de quoi son composer les requêtes HTTP. J'expliquerais également le concept de &quot;méthode&quot; au sein du protocole HTTP, et nous verrons rapidement ensemble chacune d'entre elles.&lt;/p&gt;
&lt;h3&gt;Composition d'une requête HTTP&lt;/h3&gt;
&lt;p&gt;Comme je l'ai dit précédemment, en HTTP une requête ce n'est pas composé de la simple url que vous souhaitez joindre. En effet il faut fournir au serveur HTTP d'autres paramètres afin que ce dernier puisse répondre à votre sollicitation.&lt;/p&gt;
&lt;h4&gt;Commande&lt;/h4&gt;
&lt;p&gt;Avec le protocole HTTP, trois paramètres au minimum sont à fournir afin de pouvoir constituer une requête :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;la méthode utilisée&lt;/li&gt;
&lt;li&gt;le nom du fichier souhaité&lt;/li&gt;
&lt;li&gt;la version du protocole employée&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ces informations doivent être disposées sur la première ligne de votre requête, séparées par un espace comme le montre le petit schéma ci-dessous :&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/HTTP/http-requete.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;En-tête&lt;/h4&gt;
&lt;p&gt;Vous venez de le voir sur la petite figure, une requête est aussi constituée d'autres informations. Il s'agit de ce que l'on appelle les champs de requête. C'est un ensemble d'informations facultatives que vous pouvez passer au serveur web.&lt;/p&gt;
&lt;p&gt;C'est par exemple grâce aux informations fournies ici que le serveur web peut connaître le navigateur que vous utilisez. Nous verrons dans un autre chapitre quelles sont les informations qui sont acceptées ici. &lt;/p&gt;
&lt;h4&gt;Corps&lt;/h4&gt;
&lt;p&gt;Enfin, dernier point, il s'agit du corps de votre requête. Si vous avez déjà manipulé des données de formulaire avec du PHP et du html simple, vous vous êtes sans doutes déjà demandés comment étaient transmises les variables entre le navigateur et le serveur avec la méthode POST. Contrairement aux données circulant avec la méthode GET, ces dernières sont « invisibles » et n'apparaissent pas dans l'url.&lt;/p&gt;
&lt;p&gt;C'est ici qu'elles sont transmises. Directement dans le corps de votre requête. Elles prennent la même forme que les variables passées dans le GET ;&lt;/p&gt;
&lt;code&gt;variable=valeur&amp;amp;variable2=valeur2&lt;/code&gt;
&lt;h3&gt;Les méthodes HTTP&lt;/h3&gt;
&lt;p&gt;En HTTP, les méthodes sont en fait des sortes de commandes. Elles vous permettront de spécifier au serveur le type d'action que vous souhaitez que réalise votre requête.&lt;/p&gt;
&lt;p&gt;Il existe cinq méthodes :&lt;/p&gt;
&lt;table align=&quot;center&quot; width=&quot;100%&quot;&gt;
&lt;caption&gt;Les méthodes HTTP&lt;/caption&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th scope=&quot;col&quot;&gt;Méthode&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;Requête de la ressource située à l'URL spécifiée&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HEAD&lt;/td&gt;
&lt;td&gt;Requête de la ressource située à l'URL spécifiée (la réponse ne contient que l'entête, et pas le contenu de la ressource)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;Envoi de données au programme situé à l'URL spécifiée (le corps de la requête peut être utilisé)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PUT&lt;/td&gt;
&lt;td&gt;Envoi de données à l'URL spécifiée (idem POST)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;Suppression de la ressource située à l'URL spécifiée&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Malheureusement en html les formulaires ne supportent pour le moment que les méthodes GET et POST. Il s'agit d'une restriction bien souvent regrettée que l'on pallie généralement avec des surcouches en javascript (avec ce que l'on appelle vulgairement l'AJAX).&lt;/p&gt;
&lt;p&gt;Néanmoins l'arrivée du support des méthodes PUT et DELETE par html et un des points abordés dans le document de travail de HTML5.&lt;/p&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/07/19/le-protocole-http-les-requetes#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/07/19/le-protocole-http-les-requetes#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/344</wfw:commentRss>
      </item>
    
  <item>
    <title>A venir : Introduction au protocole HTTP</title>
    <link>http://methylbro.titaxium.org/post/2009/07/17/a-venir/introduction-au-protocole-http</link>
    <guid isPermaLink="false">urn:md5:deebd6c5985392c6ddcbee9a25123306</guid>
    <pubDate>Fri, 17 Jul 2009 08:00:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>http</category><category>protocole</category><category>protocole http</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/http.jpg&quot; alt=&quot;Le Protocole HTTP&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;La semaine dernière, au fil d'une discussion avec le responsable technique d'un site de vente en ligne basé à Toulouse je me suis aperçu que la méconnaissance (ou plutôt ici la mal-connaissance) du &lt;strong&gt;protocole HTTP&lt;/strong&gt; est une affliction bien plus large est généralisée que je ne le pensais jusqu'à présent. &lt;/p&gt;
&lt;p&gt;Je sait que l'excellent &lt;a href=&quot;http://julien-pauli.developpez.com&quot; target=&quot;_blank&quot;&gt;Julien Pauli&lt;/a&gt; est en train de rédiger un article dédié au &lt;strong&gt;protocole HTTP&lt;/strong&gt; qui sera sans doutes bien plus clair et complet que tout ce que je pourrais jamais écrire à ce sujet (cela fait un moment qu'il en fait allusion sur son &lt;a href=&quot;http://blog.developpez.com/julienpauli/&quot; target=&quot;_blank&quot;&gt;blog&lt;/a&gt;). &lt;/p&gt;
&lt;p&gt;Néanmoins en attendant la sortie de cet article je vais essayer de faire un rapide synthèse du minimum requis pour réellement comprendre le &lt;strong&gt;protocole HTTP&lt;/strong&gt;. Ou du moins, du minimum pour vous donner le goût et l'envie de vous y pencher dessus plus en détail.&lt;/p&gt;    &lt;p&gt;HTTP est sans doutes l'un des protocoles réseaux les plus simples à comprendre et pourtant il est parmi les protocoles les plus ignorés par les débutants et les amateurs (voire même par certains qui se disent professionnels). &lt;/p&gt;
&lt;p&gt;Il y a quand même un point que tout le monde à bien compris au sujet du protocole HTTP, c'est qu'il est question d'un protocole orienté client/serveur. Le plus simplement du monde, le client envoie une requête au serveur et celui-ci lui retourne la ressource correspondante.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/http-client-serveur.jpg&quot; alt=&quot;HTTP : Client/Serveur&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Oui mais voilà, la requête ne se limite pas à la simple url ; comme vous pouvez l'apercevoir dans un navigateur. La réponse elle, ne se limite pas au document html, ou à tout autre type de document. &lt;/p&gt;
&lt;p&gt;Nous verrons donc, donc une série d'articles à venir de quoi son composer les requêtes et les réponse HTTP lors de ce dialogue client/serveur. On s'attardera par exemple sur les champs d'en-tête à connaître, ou sur les codes d'erreurs les plus courants. Pour finir même, nous verrons comment créer un petit client HTTP directement avec PHP. &lt;/p&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/07/17/a-venir/introduction-au-protocole-http#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/07/17/a-venir/introduction-au-protocole-http#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/342</wfw:commentRss>
      </item>
    
  <item>
    <title>Le protocole SMTP</title>
    <link>http://methylbro.titaxium.org/post/2009/07/01/le-protocole-smtp</link>
    <guid isPermaLink="false">urn:md5:cb69e50dd64c5850d039dea2cd3c779f</guid>
    <pubDate>Wed, 01 Jul 2009 08:00:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>mail</category><category>protocole</category><category>smtp</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/mail.png&quot; alt=&quot;Emailing avec PHP : Pourquoi faut il éviter la fonction mail() ?&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Comme pour beaucoup de choses en PHP ; pour bien saisir les points faible d'une méthode par rapport à une autre ; il faut avant tout maîtriser le sujet que l'on traite. Ici il s'agit de l'envoi de courrier électronique et donc implicitement de l'utilisation du protocole SMTP (Simple Mail Transfert Protocol).&lt;/p&gt;
&lt;p&gt;Comme son nom l'indique ; le protocole SMTP est très simple. Il est même parmi les protocoles les plus simple à comprendre. Il suffit simplement de signaler au serveur SMTP qui est l'émetteur d'un message, quel est son destinataire et de rédiger enfin le dit message et il s'occupe du reste.&lt;/p&gt;
&lt;p&gt;C'est ce que fait la fonction mail() de PHP pour vous. Elle se connecte et donne au serveur SMTP défini dans votre &lt;em&gt;php.ini&lt;/em&gt; toutes ces informations. Pour mieux comprendre donc comment cette dernière fonctionne ; je vous invite à faire un petit test. Envoyer vous-même ; sans client mail, sans fonction mail, un courrier à l'aide du protocole SMTP. &lt;/p&gt;    &lt;p&gt;Comme mes statistiques me signalent que 76,26 % de mes visiteurs sont des utilisateurs de Windows (bouh les vilains) je vais donc réaliser cet exemple sous XP. Nous allons communiquer avec notre serveur SMTP directement en ligne de commande dans le terminal et avec l'aide de telnet. &lt;/p&gt;
&lt;p&gt;Sous Windows ; ouvrez donc un nouveau terminal : &lt;em&gt;Démarrer &amp;gt; Exécuter : cmd&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;La première chose à faire c'est se connecter à un serveur SMTP. Ici je vais utiliser celui d'orange (smtp.orange.fr) mais pour être sur que ce petit test fonctionne chez vous ; je vous conseille d'utiliser le serveur SMTP de votre fournisseur d'accès. &lt;/p&gt;
&lt;p&gt;Nous ouvrons donc une connexion avec le serveur SMTP :&lt;/p&gt;
&lt;code&gt;telnet smtp.orange.fr 25&lt;/code&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/smtp-pic-1.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/.smtp-pic-1_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Le serveur vous renvoie alors un code 220 ; ce qui signifie que tout c'est bien passé, et que vous avez désormais une connexion établie entre votre poste client et le serveur SMTP. &lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/smtp-pic-2.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/.smtp-pic-2_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Une fois correctement connecté à votre serveur SMTP ; il faut commencer par s'identifier. C'est le rôle de la commande EHLO (anciennement HELO). &lt;/p&gt;
&lt;p&gt;Dans notre exemple ; nous allons nous déclarer comme un utilisateur inconnu ; cela n'a que peut d'importance pour le moment (surtout sur un serveur SMTP public).&lt;/p&gt;
&lt;code&gt;EHLO unknown&lt;/code&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/smtp-pic-3.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/.smtp-pic-3_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Une fois cette commande exécutée, le serveur nous retourne un code 250 (OK) pour nous dire que tout c'est bien passé. &lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/smtp-pic-4.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/.smtp-pic-4_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nous disposons donc désormais d'une connexion prête à l'emploi pour envoyer un message à notre serveur SMTP.&lt;/p&gt;
&lt;p&gt;Afin de pouvoir envoyer un message ; nous allons devoir fournir à notre serveur SMTP trois informations : &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;l'adresse de l'émetteur du message&lt;/li&gt;
&lt;li&gt;l'adresse du ou des destinataires du message&lt;/li&gt;
&lt;li&gt;le contenu du message&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Commençons donc par les coordonnées de l'émetteur du message. Vous devez utiliser la commande MAIL FROM pour les indiquer au serveur ; par exemple :&lt;/p&gt;
&lt;code&gt;MAIL FROM:&amp;lt;methylbro@titaxium.org&amp;gt;&lt;/code&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/smtp-pic-5.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/.smtp-pic-5_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si tout se passe bien ; que vous avez saisie l'adresse correctement, le serveur SMTP devrait à nouveau vous retourner un code 250 (OK) pour vous dire que tout c'est bien passé. &lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/smtp-pic-6.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/.smtp-pic-6_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;De la même façon que pour l'émetteur du message ; nous devons maintenant spécifier le ou les destinataires. Pour cela nous devons utiliser la commande RCPT TO. Vous pouvez l'utiliser autant de fois que vous avez de destinataires.&lt;/p&gt;
&lt;code&gt;RCPT TO:&amp;lt;methylbro@forumfr.com&amp;gt;&lt;/code&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/smtp-pic-7.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/.smtp-pic-7_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si tout se passe bien ; que vous avez saisie l'adresse correctement, le serveur SMTP devrait à nouveau vous retourner un code 250 (OK) pour vous dire que tout c'est bien passé. &lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/smtp-pic-8.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/.smtp-pic-8_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Maintenant il ne nous reste plus qu'à indiquer le contenu du message que l'on souhaite envoyer. &lt;/p&gt;
&lt;p&gt;Pour ce faire nous devons utiliser la commande DATA. La commande DATA va nous laisser rédiger le contenu de notre message jusqu'à ce que le serveur reçoive la pseudo commande &amp;lt;CR&amp;gt;&amp;lt;LF&amp;gt;.&amp;lt;CR&amp;gt;&amp;lt;LF&amp;gt;&lt;/p&gt;
&lt;code&gt;DATA&lt;br /&gt;
Bonjour !&lt;br /&gt;
.&lt;/code&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/smtp-pic-9.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/.smtp-pic-9_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/smtp-pic-10.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/.smtp-pic-10_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/smtp-pic-11.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/.smtp-pic-11_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Une fois le contenu du message envoyé au serveur SMTP ; celui-ci va nous répondre que le message à bien été pris en compte et qu'il a été mis en file d'attente avant envoi. On peut donc considérer que le message à bien été envoyé.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/smtp-pic-12.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/.smtp-pic-12_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;On peut donc clore la connexion ouverte entre le client et le serveur SMTP. Pour cela ; on utilise la commande QUIT.&lt;/p&gt;
&lt;code&gt;QUIT&lt;/code&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/smtp-pic-13.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/tutoriels/SMTP/.smtp-pic-13_m.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Lors du développement de vos script PHP il est en effet plus agréable d'utiliser la fonction mail() ; qui propose une véritable interface simple d'utilisation plutôt que d'avoir à réaliser soit même toutes ces opérations (ouverture d'un socket, transaction avec le serveur SMTP …).&lt;/p&gt;
&lt;p&gt;Malheureusement cette fonction possède bon nombre d'inconvénient. En termes de sécurité tout d'abord ; car sur un script mal conçue, rien n'empêche les injections. Mais également en termes de consommation de ressources dans le cadre d'un envoi en masse de courriers ; pour de l'emailling par exemple.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Pour plus d'informations sur le protocole SMTP, je vous conseille de lire la RFC 2821. Vous pourrez en trouver une traduction francaise sur le site &lt;a href=&quot;http://abcdrfc.free.fr/&quot;&gt;abcdrfc.free.fr&lt;/a&gt;.&lt;/p&gt;</description>
    
    
    
          <comments>http://methylbro.titaxium.org/post/2009/07/01/le-protocole-smtp#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/07/01/le-protocole-smtp#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/323</wfw:commentRss>
      </item>
    
  <item>
    <title>PHP : Stocker sa configuration dans une session</title>
    <link>http://methylbro.titaxium.org/post/2009/06/25/PHP-%3A-Stocker-sa-configuration-dans-une-session</link>
    <guid isPermaLink="false">urn:md5:f34ba257ea9b57fda87c854fe90210e6</guid>
    <pubDate>Thu, 25 Jun 2009 08:30:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>config</category><category>configuration</category><category>php</category><category>session</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/arton2166-0a977-bc27b.png&quot; alt=&quot;Les variables de configuration avec PHP&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;De prime abord, cette idée peut paraitre saugrenue. Quelle peut être l'intérêt de stocker des &lt;strong&gt;variables de configuration&lt;/strong&gt; au sein d'une session ?&lt;/p&gt;
&lt;p&gt;J'avoue que je n'en ai absolument aucune idée. Ne me jetez pas la pierre, je cherchais juste un bon exemple pour montrer que l'on peut enregistrer des &lt;strong&gt;variables de configuration&lt;/strong&gt; n'importe ou avec un minimum d'abstraction.&lt;/p&gt;    &lt;p&gt;De prime abord, cette idée peut paraitre saugrenue. Quelle peut être l'intérêt de stocker des &lt;strong&gt;variables de configuration&lt;/strong&gt; au sein d'une session ?&lt;/p&gt;
&lt;p&gt;J'avoue que je n'en ai absolument aucune idée. Ne me jetez pas la pierre, je cherchais juste un bon exemple pour montrer que l'on peut enregistrer des &lt;strong&gt;variables de configuration&lt;/strong&gt; n'importe ou avec un minimum d'abstraction.&lt;/p&gt;
&lt;h3&gt;La classe Session_ConfigurationHandler&lt;/h3&gt;
&lt;code&gt;
class Session_ConfigurationHandler extends ConfigurationHandler implements iConfigurationHandler {&lt;br /&gt;
&lt;br /&gt;
private $array_access;&lt;br /&gt;
&lt;br /&gt;
public function __construct($array_access, $auto=null) {&lt;br /&gt;
parent::__construct($auto);&lt;br /&gt;
&lt;br /&gt;
if (strlen(session_id())&amp;lt;=0) throw new Exception('need a valid SID resource');&lt;br /&gt;
$r = (!session_is_registered($array_access))&lt;br /&gt;
? (session_register($array_access))&lt;br /&gt;
? true&lt;br /&gt;
: new Exception('failed to define \''.$array_access.'\'')&lt;br /&gt;
: new Exception('\''.$array_access.'\' is already defined');&lt;br /&gt;
if ($r instanceof Exception) throw $r;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public function load() {&lt;br /&gt;
$this-&amp;gt;setData($_SESSION[$this-&amp;gt;array_access]);&lt;br /&gt;
return $this;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public function save() {&lt;br /&gt;
$_SESSION[$this-&amp;gt;array_access] = $this-&amp;gt;getData();&lt;br /&gt;
return $this;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
}
&lt;/code&gt;</description>
    
          <enclosure url="http://methylbro.titaxium.org/portfolio/methylbro/public/sources/class.session_configurationhandler.rar"
      length="497" type="application/rar" />
    
    
          <comments>http://methylbro.titaxium.org/post/2009/06/25/PHP-%3A-Stocker-sa-configuration-dans-une-session#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/06/25/PHP-%3A-Stocker-sa-configuration-dans-une-session#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/295</wfw:commentRss>
      </item>
    
  <item>
    <title>PHP : Stocker sa configuration dans une base de données</title>
    <link>http://methylbro.titaxium.org/post/2009/06/23/php-stocker-sa-configuration-dans-une-base-de-donnees</link>
    <guid isPermaLink="false">urn:md5:a697e172da80e81bf881a5c7adf2d6e7</guid>
    <pubDate>Tue, 23 Jun 2009 08:30:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>base de données</category><category>config</category><category>configuration</category><category>php</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/bdd.png&quot; alt=&quot;Stocker ses variable de configuration PHP dans une Base de Données&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Nous venons de voir dans un billet précédant comment manipuler facilement des &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/06/15/les-variables-de-configuration-avec-PHP&quot;&gt;variables de configuration&lt;/a&gt; à l'aide d'un &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/06/21/php-stocker-sa-configuration-dans-un-fichier-ini&quot;&gt;fichier .ini&lt;/a&gt;. Mais comme je l'ai expliqué dans le &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/06/15/les-variables-de-configuration-avec-PHP&quot;&gt;billet d'introduction&lt;/a&gt; à ce sujet, dans certains cas nous pourrions très bien vouloir stocker autrement ces informations.&lt;/p&gt;
&lt;p&gt;Aujourd'hui nous allons voir comment, avec la même méthodologie, avec les mêmes &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/06/19/php-enregistrer-et-stocker-des-variables-de-configuration&quot;&gt;classes et interfaces&lt;/a&gt; de base nous pouvons étendre notre petite librairie à l'utilisation de &lt;strong&gt;base de données&lt;/strong&gt;.&lt;/p&gt;    &lt;h3&gt;La classe DataBase_ConfigurationHandler&lt;/h3&gt;
&lt;p&gt;Pour ce faire, il faudra indiquer à la classe &lt;em&gt;Configuration&lt;/em&gt; comment elle doit lire et enregistrer les informations qu'elle manipule. &lt;/p&gt;
&lt;p&gt;Il suffit donc de reprendre la classe abstraite &lt;em&gt;ConfigurationHandler&lt;/em&gt; au sein d'une nouvelle classe (que nous appellerons ici &lt;em&gt;DataBase_ConfigurationHandler&lt;/em&gt;) et de lui implémenter également les méthodes de l'interface &lt;em&gt;iConfigurationHandler&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;On se retrouve donc avec un nouvel objet de type &lt;em&gt;ConfigurationHandler&lt;/em&gt; capable de lire et d'écrire dans une base de données.&lt;/p&gt;
&lt;code&gt;
class DataBase_ConfigurationHandler extends ConfigurationHandler implements iConfigurationHandler {&lt;br /&gt;
&lt;br /&gt;
private $column_name;&lt;br /&gt;
private $column_value;&lt;br /&gt;
private $table;&lt;br /&gt;
private $_PDO;&lt;br /&gt;
&lt;br /&gt;
public function __construct($colname, $colvalue, $table, $PDO, $auto=false) {&lt;br /&gt;
parent::__construct($auto);&lt;br /&gt;
$this-&amp;gt;column_name = $colname;&lt;br /&gt;
$this-&amp;gt;column_value = $colvalue;&lt;br /&gt;
$this-&amp;gt;table = $table;&lt;br /&gt;
$this-&amp;gt;_PDO = $PDO;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public function load() {&lt;br /&gt;
$sql = &quot;SELECT `&quot;.$this-&amp;gt;column_name.&quot;`, `&quot;.$this-&amp;gt;column_value.&quot;` &quot;&lt;br /&gt;
. &quot;FROM `&quot;.$this-&amp;gt;table.&quot;`;&quot;;&lt;br /&gt;
$PDOStatement = $this-&amp;gt;_PDO-&amp;gt;query($sql);&lt;br /&gt;
while($row = $PDOStatement-&amp;gt;fetch(PDO::FETCH_ASSOC)) {&lt;br /&gt;
$this-&amp;gt;setData($row[$this-&amp;gt;column_name], $this-&amp;gt;column_value);&lt;br /&gt;
}&lt;br /&gt;
return $this;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public function save() {&lt;br /&gt;
$arr = array();&lt;br /&gt;
$sql = &quot;TRUNCATE TABLE `&quot;.$this-&amp;gt;table.&quot;`;&quot;;&lt;br /&gt;
$this-&amp;gt;_PDO-&amp;gt;exec($sql);&lt;br /&gt;
$sql = &quot;INSERT INTO `&quot;.$this-&amp;gt;table.&quot;` &quot;&lt;br /&gt;
. &quot;(`&quot;.$this-&amp;gt;column_name.&quot;`, `&quot;.$this-&amp;gt;column_value.&quot;`) VALUES &quot;;&lt;br /&gt;
foreach($this-&amp;gt;data as $name =&amp;gt; $value) $arr[] = &quot;('&quot;.$name.&quot;', '&quot;.$value.&quot;')&quot;;&lt;br /&gt;
$sql.= implode(', ', $arr);&lt;br /&gt;
$this-&amp;gt;_PDO-&amp;gt;exec($sql);&lt;br /&gt;
return $this;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
}
&lt;/code&gt;
&lt;h3&gt;La table CONFIGURATION&lt;/h3&gt;
&lt;p&gt;Dans un second temps nous allons créer une table simple au sein d'une base de données qui contiendra les valeurs de chaque variables de configuration que nous allons utiliser :&lt;/p&gt;
&lt;code&gt;
CREATE TABLE `CONFIGURATION` (&lt;br /&gt;
`name` varchar(255) NOT NULL,&lt;br /&gt;
`value` blob NULL,&lt;br /&gt;
PRIMARY KEY (`name`)&lt;br /&gt;
)TYPE=MyISAM;&lt;br /&gt;
&lt;br /&gt;
INSERT INTO `CONFIGURATION` (`name`, `value`) VALUES ('bonjour', 'hello world !'), ('foo', 'bar');
&lt;/code&gt;
&lt;h3&gt;Exemple d'utilisation&lt;/h3&gt;
&lt;p&gt;Pour finir il ne reste plus qu'a utiliser notre nouvelle classe. Rien de plus simple car grâce au l'interface &lt;em&gt;iConfigurationHandler&lt;/em&gt; c'est toujours les mêmes méthodes que l'on utilise. &lt;/p&gt;
&lt;code&gt;
$PDO = new PDO();&lt;br /&gt;
$maMethode = new DataBase_ConfigurationHandler('name', 'value', 'CONFIGURATION', $PDO);&lt;br /&gt;
$maConfiguration = new Configuration($maMethode);&lt;br /&gt;
&lt;br /&gt;
echo $maConfiguration-&amp;gt;bonjour;&lt;br /&gt;
/*&lt;br /&gt;
* Affichera :&lt;br /&gt;
* hello world !&lt;br /&gt;
*/&lt;br /&gt;
echo $maConfiguration-&amp;gt;foo;&lt;br /&gt;
/*&lt;br /&gt;
* Affichera :&lt;br /&gt;
* bar&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
$maConfiguration-&amp;gt;bonjour = 'coucou !';&lt;br /&gt;
$maMethode-&amp;gt;save();&lt;br /&gt;
&lt;/code&gt;
&lt;p&gt;&lt;a href=&quot;http://methylbro.titaxium.org/post/2009/06/25/PHP-%3A-Stocker-sa-configuration-dans-une-session&quot;&gt;Lire la suite&lt;/a&gt;&lt;/p&gt;</description>
    
          <enclosure url="http://methylbro.titaxium.org/portfolio/methylbro/public/sources/class.database_configurationhandler.rar"
      length="623" type="application/rar" />
    
    
          <comments>http://methylbro.titaxium.org/post/2009/06/23/php-stocker-sa-configuration-dans-une-base-de-donnees#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/06/23/php-stocker-sa-configuration-dans-une-base-de-donnees#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/294</wfw:commentRss>
      </item>
    
  <item>
    <title>PHP : Stocker sa configuration dans un fichier ini</title>
    <link>http://methylbro.titaxium.org/post/2009/06/21/php-stocker-sa-configuration-dans-un-fichier-ini</link>
    <guid isPermaLink="false">urn:md5:15e240d313fa1336a90ab095c1a9ef34</guid>
    <pubDate>Sun, 21 Jun 2009 08:30:00 +0200</pubDate>
    <dc:creator>Méthylbro</dc:creator>
        <category>Tutoriels</category>
        <category>config</category><category>configuration</category><category>ini</category><category>php</category>    
    <description>&lt;p&gt;&lt;img src=&quot;http://methylbro.titaxium.org/portfolio/methylbro/public/images/arton2166-0a977-bc27b.png&quot; alt=&quot;Les variables de configuration avec PHP&quot; style=&quot;float: left; margin-right: 15px;&quot; /&gt;Maintenant que vous savez comment gérer vos &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/06/15/les-variables-de-configuration-avec-PHP&quot;&gt;variables de configuration en PHP&lt;/a&gt; avec une classe et que vous êtes capable de &lt;a href=&quot;http://methylbro.titaxium.org/post/2009/06/19/PHP-Enregistrer-et-stocker-des-variables-de-configuration&quot;&gt;stocker&lt;/a&gt; ces dernières de différentes manière. Nous allons voir comment les enregistrer au sein d'un &lt;strong&gt;fichier ini&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Comme je l'ai déjà dit, ce format sera plus efficace, car l'on pourra lire et écrire plus facilement les données concernées.&lt;/p&gt;    &lt;p&gt;Nous allons voir aujourd'hui un exemple de classe héritant de la classe abstraite &lt;em&gt;ConfigurationHandler&lt;/em&gt; ainsi que l'interface &lt;em&gt;iConfigurationHandler&lt;/em&gt; que nous avons déjà vu dans un billet précédant. &lt;/p&gt;
&lt;p&gt;Il suffit juste d'indiquer comment doivent se lire et s'enregistrer les différentes variables de configuration dans le fichier &lt;em&gt;.ini&lt;/em&gt;.&lt;/p&gt;
&lt;code&gt;
class IniFile_ConfigurationHandler extends ConfigurationHandler implements iConfigurationHandler {&lt;br /&gt;
&lt;br /&gt;
private $file;&lt;br /&gt;
&lt;br /&gt;
public function __construct($file, $auto=false) {&lt;br /&gt;
parent::__construct($auto);&lt;br /&gt;
$r = (file_exists($file) &amp;amp;&amp;amp; is_file($file))&lt;br /&gt;
? (is_readable($file) &amp;amp;&amp;amp; is_writable($file))&lt;br /&gt;
? $this-&amp;gt;file = $file&lt;br /&gt;
: new Exception('failed to open stream: Permission denied')&lt;br /&gt;
: new Exception('failed opening \''.$file.'\': No such file');&lt;br /&gt;
if ($r instanceof Exception) throw $r;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public function load() {&lt;br /&gt;
$this-&amp;gt;setData(parse_ini_file($this-&amp;gt;file, false));&lt;br /&gt;
return $this;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public function save() {&lt;br /&gt;
$str = null;&lt;br /&gt;
foreach($this-&amp;gt;data as $name =&amp;gt; $value) {&lt;br /&gt;
$str.= $name.' = '. ((is_int($value))&lt;br /&gt;
? $value&lt;br /&gt;
: (is_bool($value))&lt;br /&gt;
? ($value) ? 'On' : 'Off'&lt;br /&gt;
: '&quot;'.$value.'&quot;').PHP_EOL;&lt;br /&gt;
}&lt;br /&gt;
file_put_contents($this-&amp;gt;file, $str);&lt;br /&gt;
return $this;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
}
&lt;/code&gt;&lt;p&gt;Ainsi, pour dire à notre classe &lt;em&gt;Configuration&lt;/em&gt; qu'elle doit lire et enregistrer ses valeurs dans le fichier &lt;em&gt;config.ini&lt;/em&gt;, nous l'utiliserons désormais de la façon suivante :&lt;/p&gt;
&lt;code&gt;
$maMethode = new IniFile_ConfigurationHandler('config.ini');&lt;br /&gt;
$maConfiguration = new Configuration($maMethode);&lt;br /&gt;
&lt;br /&gt;
$maConfiguration-&amp;gt;maVariable = 'Hello World !'; &lt;br /&gt;
$maConfiguration-&amp;gt;foo = 'bar';&lt;br /&gt;
&lt;br /&gt;
$maMethode-&amp;gt;save();
&lt;/code&gt;
&lt;p&gt;&lt;a href=&quot;http://methylbro.titaxium.org/post/2009/06/23/php-stocker-sa-configuration-dans-une-base-de-donnees&quot;&gt;Lire la suite&lt;/a&gt;&lt;/p&gt;</description>
    
          <enclosure url="http://methylbro.titaxium.org/portfolio/methylbro/public/sources/class.inifile_configurationhandler.rar"
      length="606" type="application/rar" />
    
    
          <comments>http://methylbro.titaxium.org/post/2009/06/21/php-stocker-sa-configuration-dans-un-fichier-ini#comment-form</comments>
      <wfw:comment>http://methylbro.titaxium.org/post/2009/06/21/php-stocker-sa-configuration-dans-un-fichier-ini#comment-form</wfw:comment>
      <wfw:commentRss>http://methylbro.titaxium.org/feed/atom/comments/293</wfw:commentRss>
      </item>
    
</channel>
</rss>