<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://phpsymfony.com/index.php?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>PHPSymfony - Blog par un programmeur pour les programmeurs</title>
  <link>http://phpsymfony.com/index.php?</link>
  <atom:link href="http://phpsymfony.com/index.php?feed/rss2" rel="self" type="application/rss+xml"/>
  <description></description>
  <language>en</language>
  <pubDate>Sun, 12 May 2013 11:19:30 +0200</pubDate>
  <copyright></copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Demarrer avec un Raspberry Pi Model B</title>
    <link>http://phpsymfony.com/index.php?post/2013/05/12/Demarrer-avec-un-raspberry-pi-Model-B</link>
    <guid isPermaLink="false">urn:md5:98ea64504fd9812f1d8c682afc020def</guid>
    <pubDate>Sun, 12 May 2013 12:23:00 +0200</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>Raspberry Pi</category>
            
    <description>    Dans cet article, je vais expliquer comment faire ses premiers pas avec un raspberry pi. L'idée est de le connecter simplement à un réseau filaire existant et de pouvoir ensuite se connecter via putty.
&lt;br /&gt;&lt;br /&gt;Si vous ne savez ne savez pas ce qu'est un raspberry pi, je vous encourage à aller lire la page suivante qui présente bien le produit : www.kubii.fr/content/19-raspberry-pi-model-b-512-mo-presentation
&lt;br /&gt;&lt;br /&gt;Concernant l'achat, je suis passé par le site de farnell : http://fr.farnell.com/
&lt;br /&gt;&lt;br /&gt;J'y ai acheté : &lt;br /&gt;&lt;ul&gt;&lt;li&gt;raspberry pi Model B&lt;/li&gt;
&lt;li&gt;un cable rj45 3M&lt;/li&gt;
&lt;li&gt;un cable USB vers micro USB&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour un cout de 52€ livraison comprise.&lt;/p&gt;
&lt;p&gt;J'ai commandé la carte mémoire séparément. D'après la liste des cartes compatibles dispo sur http://elinux.org/RPi_SD_cards j'ai choisi, une SANDISK 16Go Extreme SDSDX-016G-X46 (en promo chez grosbill&amp;nbsp; : http://www.grosbill.com/4-sandisk_16go_extreme_-144521-numerique-memoire_sd_card)&lt;/p&gt;
&lt;p&gt;Une fois, votre mini ordinateur et la carte mémoire recus, nous allons pouvoir commencer.&lt;/p&gt;
&lt;p&gt;Tout d'abord, munissez vous d'un lecteur de carte SD (la plupart des PC portables en ont un intégré). Télécharger sur la page http://www.raspberrypi.org/downloads la raspbian wheezy. Téléchargez également Win32 diskimager http://sourceforge.net/projects/win32diskimager/?source=dlp si vous êtes sous windows. Insérez la carte dans le lecteur de cartes. Copiez l'image sur la carte grace au logiciel. &lt;/p&gt;
&lt;p&gt;Insérez ensuite la carte dans le raspberry pi et connectez le à une source d'alimentation via le cable micro USB. Raccordez le RPi au réseau via le cable RJ45. La distribution installée est équipée d'un serveur ssh et les identifiants par défaut sont : &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;login : pi&lt;/li&gt;
&lt;li&gt;password : raspberry&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si vous réseau est équipée d'un serveur DHCP, vous pourrez connaitre l'IP du raspberry pi via l'outil http://www.softperfect.com/products/networkscanner/&lt;/p&gt;
&lt;p&gt;Les adresses MAC des raspberry pi débutent par B8:27:EB. Une fois l'adresse IP récupérée, vous pourrez vous connecter en ssh via un outil type putty.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[Linux] Changer l'adresse MAC sous Ubuntu 11.10</title>
    <link>http://phpsymfony.com/index.php?post/2012/10/02/%5BLinux%5D-Changer-l-adresse-MAC-sous-Ubuntu-11.10</link>
    <guid isPermaLink="false">urn:md5:4b48f24e19a195391e7add9c08e7ea7f</guid>
    <pubDate>Tue, 02 Oct 2012 08:18:00 +0100</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>Linux</category>
            
    <description>    &lt;p&gt;Pour changer l'adresse MAC de votre carte réseau sous Ubuntu 11.10 : &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Affichez les interfaces actives via la commande ifconfig : &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;[08:55]user@gm21:/home/guigui$ sudo ifconfig&lt;br /&gt;eth0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Link encap:Ethernet&amp;nbsp; HWaddr 08:00:27:ef:b8:71&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inet adr:172.25.10.60&amp;nbsp; Bcast:172.25.11.255&amp;nbsp; Masque:255.255.254.0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; adr inet6: fe80::a00:27ff:feef:b871/64 Scope:Lien&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UP BROADCAST RUNNING MULTICAST&amp;nbsp; MTU:1500&amp;nbsp; Metric:1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RX packets:755506 errors:0 dropped:0 overruns:0 frame:0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TX packets:2746 errors:0 dropped:0 overruns:0 carrier:0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; collisions:0 lg file transmission:1000&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RX bytes:81288103 (77.5 MiB)&amp;nbsp; TX bytes:354363 (346.0 KiB)&lt;br /&gt;&lt;br /&gt;eth1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Link encap:Ethernet&amp;nbsp; HWaddr 08:00:27:0a:92:d5&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inet adr:192.168.56.101&amp;nbsp; Bcast:192.168.56.255&amp;nbsp; Masque:255.255.255.0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; adr inet6: fe80::a00:27ff:fe0a:92d5/64 Scope:Lien&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UP BROADCAST RUNNING MULTICAST&amp;nbsp; MTU:1500&amp;nbsp; Metric:1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RX packets:12701342 errors:0 dropped:0 overruns:0 frame:0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TX packets:12732288 errors:0 dropped:0 overruns:0 carrier:0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; collisions:0 lg file transmission:1000&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RX bytes:2847332852 (2.6 GiB)&amp;nbsp; TX bytes:2772354787 (2.5 GiB)&lt;br /&gt;&lt;br /&gt;lo&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Link encap:Boucle locale&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inet adr:127.0.0.1&amp;nbsp; Masque:255.0.0.0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; adr inet6: ::1/128 Scope:Hôte&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UP LOOPBACK RUNNING&amp;nbsp; MTU:16436&amp;nbsp; Metric:1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RX packets:1667 errors:0 dropped:0 overruns:0 frame:0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TX packets:1667 errors:0 dropped:0 overruns:0 carrier:0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; collisions:0 lg file transmission:0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RX bytes:116698 (113.9 KiB)&amp;nbsp; TX bytes:116698 (113.9 KiB)$&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Arrétez&amp;nbsp; le network manager&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;sudo service network-manager stop&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Changez l'adresse MAC de l'interface concernée&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;sudo ifconfig ethX hw ether xx:xx:xx:xx:xx:xx &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;où vous remplacerez ethX par une interface existante et xx:xx:xx:xx:xx:xx&amp;nbsp; par une adresse MAC valide (08:00:27:42:01:11 par exemple). S'il s'agissait d'une carte réseau sans fil, remplacez ethX par wlanX.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Relancer le network manager&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;sudo service network-manager start&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Vérifier la prise en compte des informations par une nouvelle commande ifconfig&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;sudo ifconfig&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Attention, cette modification est temporaire, lorsque vous redémarrerez votre machine, l'ancienne valeur de l'adresse MAC sera rétablie.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[Javascript][Mootools] Requêtes périodiques avec Mootools</title>
    <link>http://phpsymfony.com/index.php?post/2012/08/17/%5BJavascript%5D%5BMootools%5D-Requ%C3%AAte-p%C3%A9riodique-avec-Mootools</link>
    <guid isPermaLink="false">urn:md5:25eccf6d83e853d6bcf336a6a2530ff4</guid>
    <pubDate>Fri, 17 Aug 2012 18:57:00 +0100</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>Mootools</category>
        <category>javascript</category><category>mootools</category>    
    <description>    &lt;p&gt;Dans le cadre d'un développement, j'ai du implémenter une fonctionnalité de requête périodique sur un de mes sites web pour vérifier par exemple : &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;la disponibilité d'un service,&lt;/li&gt;
&lt;li&gt;un nombre de personnes connectées,&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;J'ai donc créé la classe générique PeriodicRequest pour répondre à ce besoin. J'ai utilisé Mootools V1.4.5.&lt;/p&gt;
&lt;h2&gt;Classe PeriodicRequest&lt;/h2&gt;
&lt;code&gt;/**&lt;br /&gt;&amp;nbsp;* Periodic request class&lt;br /&gt;&amp;nbsp;* &lt;br /&gt;&amp;nbsp;* @author gbretou&lt;br /&gt;&amp;nbsp;*/&lt;br /&gt;var PeriodicRequest = new Class({&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Implements: Options,&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; url : '',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request: null,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; periodical: null,&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; options: {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;method: 'GET',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;delay: '3000',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;onComplete: function(){},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;onCancel: function(){},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;onSuccess: function(){},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;onFailure: function(){}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; },&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* Constructor&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* @param url&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* @param options&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; initialize: function(url, options)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;this.setOptions(options);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;this.url&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = url;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;this.method&amp;nbsp; = this.options.method;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;this.delay&amp;nbsp;&amp;nbsp; = this.options.delay;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;this.request = new Request({&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;method: this.method,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;url: this.url,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;onComplete: this.options.onComplete,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;onCancel: this.options.onCancel,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;onSuccess: this.options.onSuccess,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;onFailure: this.options.onFailure&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;});&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; },&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* Starts the timer&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; startTimer: function()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;this.periodical = (function(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;this.request.send();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;}.bind(this)).periodical(this.delay);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; },&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* Stops timer&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stopTimer: function()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;clearInterval(this.periodical);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;});&lt;/code&gt; &lt;br /&gt;&lt;h2&gt;Utilisation&lt;/h2&gt;
&lt;p&gt;Le constructeur prend en paramètres 2 arguments : &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;url : la page à appeler,&lt;/li&gt;
&lt;li&gt;data : un objet&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L'objet data accepte les clés suivantes : &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;method : la méthode à utiliser (GET par défaut),&lt;/li&gt;
&lt;li&gt;delay : le délai entre chaque requête (3000ms par défaut),&lt;/li&gt;
&lt;li&gt;onComplete : callback lorsque la requête est terminée. &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;&lt;p&gt;Dans le code suivant, nous allons créer une exécution périodique qui va requêter la page test.html toutes les 2 secondes. On affichera en console le contenu de la réponse. &lt;/p&gt;
&lt;code&gt;&lt;p&gt;data = {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; delay: 2000,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; onComplete: function(content) {console.log(content);}&lt;br /&gt;};&lt;br /&gt;var periodic = new PeriodicRequest('test.html', data);&lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;La construction de l'objet ne lance pas automatiquement les actions périodiques. Vous devrez utiliser la méthode startTimer() : &lt;/p&gt;
&lt;p&gt;&lt;code&gt;periodic.startTimer();&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Si vous souhaitez arrêtez l'exécution périodique, vous pourrez utiliser la méthode stopTimer() :&lt;/p&gt;
&lt;p&gt;&lt;code&gt;periodic.stopTimer();&lt;/code&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[PHP] PHP Cli Progress Bar</title>
    <link>http://phpsymfony.com/index.php?post/2012/07/24/PHP-Cli-Progress-Bar</link>
    <guid isPermaLink="false">urn:md5:fcb995a3aedf0d0d0657046a7fc4655d</guid>
    <pubDate>Tue, 24 Jul 2012 13:38:00 +0100</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>PHP</category>
        <category>cli</category><category>php</category><category>progress bar</category>    
    <description>    &lt;p&gt;Voici une des dernière librairie que je viens de développer. Il s'agit d'une progress bar en PHP pour une utilisation en CLI.&lt;/p&gt;
&lt;h2&gt;Récupérer les sources&lt;/h2&gt;
&lt;p&gt;Pour récupérer les sources, vous pouvez utiliser : &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;git &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;git clone https://github.com/guiguiboy/PHP-CLI-Progress-Bar.git&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Puis ajouter les lignes au début de votre script : &lt;/p&gt;
&lt;code&gt;&lt;p&gt;&amp;lt;?php&lt;/p&gt;
&lt;p&gt;require_once 'ProgressBar/Manager.php';&lt;/p&gt;
&lt;p&gt;require_once 'ProgressBar/Registry.php';&lt;/p&gt;
&lt;/code&gt;
&lt;br /&gt;&lt;ul&gt;&lt;li&gt;composer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ajouter les lignes dans votre composer.json&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;require&quot;: {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;php&quot;: &quot;&amp;gt;=5.3.0&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;guiguiboy/php-cli-progress-bar&quot;: &quot;*&quot;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; },&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;minimum-stability&quot;: &quot;dev&quot;,&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;puis &lt;/p&gt;
&lt;p&gt;&lt;code&gt;php composer.phar install&lt;/code&gt;&lt;/p&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;
&lt;h2&gt;Utilisation&lt;/h2&gt;
&lt;br /&gt;&lt;h3&gt;Quick start&lt;/h3&gt;
&lt;p&gt;Une fois les fichiers chargés, rien de plus simple : &lt;/p&gt;
&lt;p&gt;&lt;code&gt;$progressBar = new \ProgressBar\Manager(0, 10);&lt;br /&gt;&lt;br /&gt;for ($i = 0; $i &amp;lt;= 10; $i++)&lt;br /&gt;{&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $progressBar-&amp;gt;update($i);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sleep(1);&lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Le code ci dessus va créer une progress bar pour un traitement de 10 éléments. A chaque itération, il attend 1 seconde.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;1/10 [===&amp;gt;----------------------------------------------] 10.00% 00:00:09&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;br /&gt;&lt;p&gt;Le format d'affichage par défaut est : %current%/%max% [%bar%] %percent%% %eta% où&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;%current% correspond à l'élément actuel&lt;/li&gt;
&lt;li&gt;%max% correspond à l'élément max&lt;/li&gt;
&lt;li&gt;%bar% correspond à la progress bar&lt;/li&gt;
&lt;li&gt;%percent% correspond au pourcentage d'avancement&lt;/li&gt;
&lt;li&gt;%eta% correspond à une estimation du temps de traitement restant&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;&lt;h3&gt;Configuration&lt;/h3&gt;
&lt;br /&gt;&lt;h4&gt;Format&lt;/h4&gt;
&lt;p&gt;Vous pouvez changer le format de la progress bar avec la méthode setFormat : &lt;/p&gt;
&lt;code&gt;&lt;p&gt;$progressBar-&amp;gt;setFormat('%current% |%bar%| %max%');&lt;/p&gt;
&lt;/code&gt;
&lt;br /&gt;&lt;h4&gt;Longueur&lt;/h4&gt;
&lt;p&gt;La longueur se spécifie au niveau du constructeur. PAr défaut elle est de 80 caractères maximum. La taille de la progress bar se base sur cette information. PAr exemple : &lt;/p&gt;
&lt;p&gt;&lt;code&gt;$pb = new \ProgressBar\Manager(0, 20, 120);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Affichera : &lt;/p&gt;
&lt;p&gt;1/20 [====&amp;gt;----------------------------------------------------------------------------------------] 5.00% 00:00:00&lt;/p&gt;
&lt;br /&gt;&lt;h4&gt;Caractères de la progress bar&lt;/h4&gt;
&lt;p&gt;Par défaut la progress bar utilisera les caractères suivants : &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&amp;gt; : position courante&lt;/li&gt;
&lt;li&gt;= : partie traitée&lt;/li&gt;
&lt;li&gt;- : reste à faire&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ces caractères se configurent à l'initialisation. Par exemple : &lt;/p&gt;
&lt;code&gt;&lt;p&gt;$pb = new \ProgressBar\Manager(0, 20, 120, '-', ' ', ')');&lt;br /&gt;$pb-&amp;gt;update(5);&lt;/p&gt;
&lt;/code&gt;&lt;p&gt;Affichera : &lt;/p&gt;
&lt;p&gt;5/20 [-----------------------)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ] 25.00% 00:00:00&lt;/p&gt;
&lt;br /&gt;&lt;h2&gt;Extension&lt;/h2&gt;
&lt;br /&gt;&lt;h3&gt;Ajouter des règles de remplacement&lt;/h3&gt;
&lt;p&gt;&lt;br /&gt;Vous pouvez ajouter des règles de remplacement :&amp;nbsp;&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;&lt;span class=&quot;nv&quot;&gt;$pb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Manager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;213&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$pb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setFormat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Progress : %current%/%max% [%bar%] %foo%'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$pb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addReplacementRule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'%foo%'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$registry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'OK!'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;});&lt;br /&gt;$pb-&amp;gt;update(1);&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/code&gt;&lt;p&gt;Affichera : &lt;/p&gt;
&lt;p&gt;Progress : 1/213 [&amp;gt;---------------------------------------------------] OK!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NB : Cette documentation ne sera pas forcément tenue à jour. Pour la version la plus récente, veuillez consulter le README.md du projet.&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Forum PHP 2012 organisé par l'AFUP : les slides des talks des conférenciers</title>
    <link>http://phpsymfony.com/index.php?post/2012/06/05/Forum-PHP-2012-organis%C3%A9-par-l-AFUP-%3A-les-slides-des-talks-des-conf%C3%A9renciers</link>
    <guid isPermaLink="false">urn:md5:60d5ca106ea1de997781ef132e77fd6f</guid>
    <pubDate>Tue, 05 Jun 2012 17:16:00 +0100</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>PHP</category>
            
    <description>    &lt;p&gt;Vous n'avez pas pu assister au Forum PHP 2012 ? Séance de rattrapage avec les slides des conférenciers : &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PHP in 2012&lt;/strong&gt; : &lt;a hreflang=&quot;en&quot; href=&quot;http://talks.php.net/show/afup12&quot;&gt;http://talks.php.net/show/afup12&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Annotating with annotations&lt;/strong&gt; : &lt;a hreflang=&quot;en&quot; href=&quot;http://www.slideshare.net/rdohms/annotating-with-annotations-forumphp-2012&quot;&gt;http://www.slideshare.net/rdohms/annotating-with-annotations-forumphp-2012&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Coup de pied dans la LAMP :&lt;/strong&gt; &lt;a hreflang=&quot;fr&quot; href=&quot;http://ternel.net/forumphp/Slideshow/#/author-bros&quot;&gt;http://ternel.net/forumphp/Slideshow/#/author-bros&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anatomie du test : &lt;a style=&quot;font-weight: normal;&quot; hreflang=&quot;fr&quot; href=&quot;http://joind.in/talk/view/6440&quot;&gt;http://joind.in/talk/view/6440&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Monitoring applicatif : &lt;a style=&quot;font-weight: normal;&quot; hreflang=&quot;fr&quot; href=&quot;http://joind.in/talk/view/6442&quot;&gt;http://joind.in/talk/view/6442&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anatomie, fonctionnement et performances de PHP :&lt;/strong&gt; &lt;a hreflang=&quot;fr&quot; href=&quot;http://www.slideshare.net/jpauli/anatomie-et-performances-de-php&quot;&gt;http://www.slideshare.net/jpauli/anatomie-et-performances-de-php&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lightning talk : Hip Hop for PHP :&lt;/strong&gt; &lt;a hreflang=&quot;en&quot; href=&quot;http://www.slideshare.net/gplessis/lightning-talk-hiphop-for-php&quot;&gt;http://www.slideshare.net/gplessis/lightning-talk-hiphop-for-php&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gestion des dépendances dans un projet PHP : &lt;a style=&quot;font-weight: normal;&quot; hreflang=&quot;fr&quot; href=&quot;http://joind.in/talk/view/6458&quot;&gt;http://joind.in/talk/view/6458&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Varnish pour les développeurs PHP : &lt;a style=&quot;font-weight: normal;&quot; hreflang=&quot;en&quot; href=&quot;http://jrenard.info/blog/varnish-for-php-developers-the-slides.html&quot;&gt;http://jrenard.info/blog/varnish-for-php-developers-the-slides.html&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Drupal comme vous ne l'avez jamais vu : &lt;a style=&quot;font-weight: normal;&quot; hreflang=&quot;fr&quot; href=&quot;https://speakerdeck.com/u/gagarine/p/drupal-comme-vous-ne-lavez-jamais-vu&quot;&gt;https://speakerdeck.com/u/gagarine/p/drupal-comme-vous-ne-lavez-jamais-vu&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;La qualité au delà du code : &lt;a style=&quot;font-weight: normal;&quot; hreflang=&quot;fr&quot; href=&quot;http://joind.in/talk/view/6454&quot;&gt;http://joind.in/talk/view/6454&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maitriser structures de données PHP 102 : &lt;a style=&quot;font-weight: normal;&quot; hreflang=&quot;fr&quot; href=&quot;http://www.slideshare.net/patrick.allaert/maitriser-les-structures-de-donnes-php-102-forum-paris-2012&quot;&gt;http://www.slideshare.net/patrick.allaert/maitriser-les-structures-de-donnes-php-102-forum-paris-2012&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Démons en PHP de inetd à ZeroMQ : &lt;a style=&quot;font-weight: normal;&quot; hreflang=&quot;fr&quot; href=&quot;http://www.slideshare.net/geekcto/dmons-en-php-de-inetd-zeromq&quot;&gt;http://www.slideshare.net/geekcto/dmons-en-php-de-inetd-zeromq&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Accès concurrents et scalabilité : &lt;a style=&quot;font-weight: normal;&quot; hreflang=&quot;fr&quot; href=&quot;http://joind.in/6461&quot;&gt;http://joind.in/6461&lt;/a&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TDD avec ATOUM :&lt;/strong&gt; &lt;a hreflang=&quot;fr&quot; href=&quot;http://joind.in/talk/view/6463&quot;&gt;http://joind.in/talk/view/6463&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Vous trouverez en fichier joint mes notes prises lors de la conférence.&lt;/p&gt;
&lt;p&gt;[EDIT]&lt;/p&gt;
&lt;p&gt;Voici les slides du Symfony Live qui avait lieu peu de temps après : &lt;a hreflang=&quot;fr&quot; href=&quot;https://gist.github.com/2890651&quot;&gt;https://gist.github.com/2890651&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>restaurant.michelin.fr en ligne !</title>
    <link>http://phpsymfony.com/index.php?post/2012/03/10/restaurant.michelin.fr-en-ligne-%21</link>
    <guid isPermaLink="false">urn:md5:7ce3681ea40b462d09654c84ae6366e5</guid>
    <pubDate>Sat, 10 Mar 2012 15:01:00 +0000</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
            
    <description>    &lt;p&gt;Le site &lt;a hreflang=&quot;fr&quot; href=&quot;http://restaurant.michelin.fr/&quot;&gt;http://restaurant.michelin.fr/&lt;/a&gt; est désormais en ligne. Vous pouvez désormais rechercher des restaurants et laisser des avis.&lt;/p&gt;
&lt;p&gt;Le site B2B est disponible à l'adresse : &lt;a hreflang=&quot;fr&quot; href=&quot;http://pro.restaurant.michelin.fr/&quot;&gt;http://pro.restaurant.michelin.fr/&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[PHP] Spécifier une connexion en utf-8 avec Doctrine DBAL</title>
    <link>http://phpsymfony.com/index.php?post/2011/12/29/%5BPHP%5D-Sp%C3%A9cifier-une-connexion-en-utf-8-avec-Doctrine-DBAL</link>
    <guid isPermaLink="false">urn:md5:b6dc9300ed2f7d6a9efddb594772c566</guid>
    <pubDate>Fri, 06 Jan 2012 19:31:00 +0000</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>PHP</category>
            
    <description>    &lt;p&gt;Lorsque vous utilisez Doctrine DBAL (sur un projet Silex par exemple), voici comment spécifier l'encodage de la base de données.&lt;/p&gt;
&lt;p&gt;Ajoutez une classe étendue de DoctrineServiceProvider et surchargez la méthode register(). Vous devrez utiliser le système d'event. &lt;/p&gt;
&lt;p&gt;Exemple pour une base de données Mysql &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;p&gt;&lt;br /&gt;use Silex\Application;&lt;br /&gt;use Doctrine\DBAL\Event\Listeners\MysqlSessionInit;&lt;br /&gt;&lt;br /&gt;class DoctrineServiceProvider extends \Silex\Provider\DoctrineServiceProvider&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; public function register(Application $app)&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; parent::register($app);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; $app['db.event_manager']-&amp;gt;addEventSubscriber(new MysqlSessionInit('utf8','utf8_unicode_ci'));&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notez qu'avec le système d'event, vous pourrez réaliser d'autres actions telles que la mise en place de Behaviors.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[Java] Débuter avec le développement Android</title>
    <link>http://phpsymfony.com/index.php?post/2011/12/20/%5BJava%5D-D%C3%A9buter-avec-le-d%C3%A9veloppement-sous-Android-%21</link>
    <guid isPermaLink="false">urn:md5:fba9faf443d492aeaa76c3968fd893e0</guid>
    <pubDate>Tue, 20 Dec 2011 22:15:00 +0000</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>JAVA</category>
            
    <description>    &lt;p&gt;Ayant reçu un Samsung GALAXY S II (en remplacement de mon HTC Touch HD qui a rendu l’âme), j'ai tout de suite accroché au système des applications disponibles sur l'Android Market. Pour aller plus loin que la simple utilisation, J'ai voulu regarder comment créer une application sous Android. &lt;/p&gt;
&lt;p&gt;Comme le veux la coutume, impossible de passer à coté de l'éternel &quot;Hello World&quot; quand on débute avec une nouvelle technologie. Voici les différentes étapes que j'ai suivi pour faire fonctionner mon application sous Windows :&amp;nbsp; &lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;Tout d'abord, vous devez vous assurer d'avoir le JDK. Vous pourrez le télécharger ici : http://www.oracle.com/technetwork/java/javase/downloads/index.html&lt;/p&gt;
&lt;p&gt;Sélectionnez la version qui correspond à votre OS.&lt;/p&gt;
&lt;p&gt;Ensuite, vous devrez télécharger le SDK Android ici : http://developer.android.com/sdk/index.html&lt;/p&gt;
&lt;p&gt;Pour simplifier l'utilisation du SDK en ligne de commande, nous allons renseigner le chemin vers le répertoire tools du SDK dans le PATH. Sous Windows 7, démarrer &amp;gt; rechercher &quot;paramètres systèmes avancés&quot;. Cliquer sur le bouton &quot;Variables d'environnement&quot;. Puis, dans la variables système, changer la valeur de la variable PATH pour y ajouter le path vers le dossier tools du SDK.&lt;/p&gt;
&lt;h2&gt;Configuration&lt;/h2&gt;
&lt;p&gt;Dans notre cas, nous considérerons l'utilisation de l'IDE Eclipse. Pour installer les plugins nécessaire, il faut suivre la documentation ici : http://developer.android.com/sdk/eclipse-adt.html#downloading&lt;/p&gt;
&lt;p&gt;Notre environnement est désormais prêt et nous allons pouvoir créer l'application;&lt;/p&gt;
&lt;p&gt;Commencez par créer un nouveau projet Android dans eclipse. Un Clic droit dans le package explorer puis sélectionnez &quot;New&quot; puis &quot;Project ...&quot;.&lt;/p&gt;
&lt;p&gt;Sélectionnez &quot;Android Project&quot; puis Next.&lt;/p&gt;
&lt;p&gt;Choisissez un nom au projet, nous l'appellerons &quot;HelloAndroid&quot;. Pour le reste de cet écran, le paramétrage par défaut est suffisant. Cliquez sur &quot;Next&quot;.&lt;/p&gt;
&lt;p&gt;Choisissez ensuite le SDK Android dans la liste. On prendra pour cet example la version 2.3.3. Cliquez ensuite sur &quot;Next&quot;.&lt;/p&gt;
&lt;p&gt;Enfin, choisissez un nom pour le package &quot;HelloWorldAndroid&quot; puis &quot;Finish&quot;&lt;/p&gt;
&lt;p&gt;Dans le dernier écran, vous devrez remplir les champs : &lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Application name : nom de l'application. Dans notre exemple nous utiliserons &quot;Hello Android&quot;&lt;/li&gt;
&lt;li&gt;Pckage name : il s'agit du namespace du package. Dans notre exemple, nous utiliserons &quot;com.example.helloandroid&quot;. Veuillez à bien respecter les règles de nommage de package java. Sinon, vous pourrez rencontrer l'erreur &quot;Aplication package XXX must have a minimum of 2 segments&quot;&lt;/li&gt;
&lt;li&gt;Create Activity : laissez cette case cochée. Cela va permettre la génération d'une classe étendue de Activity sur laquelle nous allons travailler.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Cliquez sur &quot;Finish&quot;.&lt;/p&gt;
&lt;p&gt;Le système va ensuite générer le projet.&lt;/p&gt;
&lt;p&gt;Dans src/com.example.helloandroid/HelloAndroid.java remplacez le code par&amp;nbsp; : &lt;/p&gt;
&lt;p&gt;&lt;code&gt;package com.example.helloandroid;&lt;br /&gt;&lt;br /&gt;import android.app.Activity;&lt;br /&gt;import android.os.Bundle;&lt;br /&gt;import android.widget.TextView;&lt;br /&gt;&lt;br /&gt;public class HelloAndroid extends Activity {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /** Called when the activity is first created. */&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Override&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void onCreate(Bundle savedInstanceState) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; super.onCreate(savedInstanceState);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setContentView(R.layout.main);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TextView tv = new TextView(this);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tv.setText(&quot;Hello, Android&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setContentView(tv);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Astuce&lt;/strong&gt; : sous eclipse, vous pouvez faire Ctrl Shift O pour importer les packages manquants.&lt;/p&gt;
&lt;p&gt;Comme vous vous en doutez, l'idée est d'afficher &quot;Hello, Android&quot; sur l'écran.&lt;/p&gt;
&lt;p&gt;Nous allons maintenant tester notre développement. Pour cela, nous allons utiliser un AVD.&lt;/p&gt;
&lt;h2&gt;
Créer un AVD &lt;/h2&gt;
AVD (pour Android Virtual Device) est un émulateur qui vous permet de choisir un type d'appareil compatible et de le configurer afin de tester votre application.&lt;br /&gt;Nous allons donc créer un AVD pour vérifier que notre application fonctionne bien.&lt;br /&gt;&lt;br /&gt;Pour créer un AVD, il faut commencer par installer de nouveaux packages.&lt;br /&gt;Lancer l'utilitaire &quot;SDK Manager&quot; en tant qu'administrateur.&lt;br /&gt;Puis cocher les packages correspondant aux différentes versions que vous souhaitez installer. Veuillez à bien sélectionner le SDK Android 2.3.3 car c'est celui ci que nous utiliserons pour tester notre application Hello world.&lt;br /&gt;&lt;br /&gt;Cliquez ensuite sur &quot;Install&quot;&lt;br /&gt;Notez l'emplacement du téléchargement.&lt;br /&gt;&lt;br /&gt;Il faudra ensuite enregistrer le bon path pour les SDK dans eclipse. Pour cela, dans eclipse, allez dans Window &amp;gt; Preference &amp;gt; Android.&lt;br /&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.casimages.com/img.php?i=111226095222207847.png&quot; target=&quot;_blank&quot; title=&quot;upload image&quot;&gt;&lt;img src=&quot;http://nsa21.casimages.com/img/2011/12/26/mini_111226095222207847.png&quot; alt=&quot;Hebergement gratuit d'image et photo&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ensuite, cliquez sur Window &amp;gt; AVD Manager&lt;br /&gt;Cliquez sur &quot;New ...&quot;. Le système affiche une nouvelle fenêtre vous permettant de configurer votre AVD&lt;br /&gt;&lt;ol&gt;&lt;li&gt;name (obligatoire) : nom de l'AVD.&lt;/li&gt;
&lt;li&gt;target (obligatoire) : version du SDK d'android. Sélectionnez 2.3.3&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pour le reste, le paramétrage par défaut est suffisant.&lt;/p&gt;
&lt;br /&gt;&lt;h2&gt;Tester l'application&lt;/h2&gt;
&lt;br /&gt;Tester l'application est très simple. Sous eclipse, cliquez sur le projet à tester, puis Run &amp;gt; Run.&lt;br /&gt;Sélectionnez &quot;Android application&quot;&lt;br /&gt;Sélectionner une source de capture pour la vidéo, puis OK.&lt;br /&gt;&lt;br /&gt;Le système va lancer le programme dans l'émulateur. Un peu de patience, cela peut prendre du temps...&lt;br /&gt;&lt;br /&gt;Vous obtenez alors le tant attendu &quot;Hello, Android&quot; ! &lt;br /&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.casimages.com/img.php?i=111226110120891459.png&quot; target=&quot;_blank&quot; title=&quot;upload image&quot;&gt;&lt;img src=&quot;http://nsa21.casimages.com/img/2011/12/26/mini_111226110120891459.png&quot; alt=&quot;Hebergement gratuit d'image et photo&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Sources : &lt;br /&gt;http://ydisanto.developpez.com/tutoriels/android/debuter/&lt;br /&gt;http://developer.android.com/resources/tutorials/hello-world.html&lt;br /&gt;&lt;br /&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[Mysql] Mise à jour d'un mot de passe root de mysql oublié</title>
    <link>http://phpsymfony.com/index.php?post/2011/09/29/%5BMysql%5D-Mise-%C3%A0-jour-d-un-mot-de-passe-root-de-mysql-oubli%C3%A9</link>
    <guid isPermaLink="false">urn:md5:ebfbe219b60de7719efc138b626a1239</guid>
    <pubDate>Thu, 29 Sep 2011 23:42:00 +0100</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>Mysql</category>
            
    <description>    Vous avez oublié le mot de passe root de mysql ? Pas de problème, il existe une solution pour cela.&lt;br /&gt;&lt;br /&gt;Commencez par couper votre serveur mysql :&lt;br /&gt;&lt;br /&gt;&lt;code&gt;/etc/init.d/mysqld stop&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Lancez la commande suivante :&lt;br /&gt;&lt;br /&gt;&lt;code&gt;/usr/bin/mysqld_safe --skip-grant-tables &amp;amp;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Cela permettra de lancer le serveur en arrière plan. L'option --skip-grant-tables vous permet de passer outre l'authentification.&lt;br /&gt;Attention : vous ne pourrez toutefois pas créer d'utilisateur, ni modifier de droits dans ce mode.&lt;br /&gt;&lt;br /&gt;Connectez vous en tant que root : &lt;br /&gt;&lt;br /&gt;&lt;code&gt;mysql -uroot mysql&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;mysql&amp;gt; update user SET Password=PASSWORD('MyNewPassword') Where User='root';&lt;br /&gt;Query OK, 1 row affected (0.00 sec)&lt;br /&gt;Rows matched: 1&amp;nbsp; Changed: 1&amp;nbsp; Warnings: 0&lt;br /&gt;&lt;br /&gt;mysql&amp;gt; flush privileges;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&amp;gt; exit;&lt;br /&gt;Bye&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;Vous pouvez maintenant killer le processus lancé en arrière plan. Puis, relancez votre serveur mysql :&lt;br /&gt;&lt;br /&gt;&lt;code&gt;/etc/init.d/mysqld start&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Vérifiez que votre identifiant a bien été pris en compte : &lt;br /&gt;&lt;br /&gt;&lt;code&gt;mysql -uroot -pMyNewPassword&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;C'est terminé !&lt;br /&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[sf2] Symfony 2 : c'est parti !</title>
    <link>http://phpsymfony.com/index.php?post/2011/07/26/%5Bsf2%5D-Symfony-2-%3A-c-est-parti-%21</link>
    <guid isPermaLink="false">urn:md5:51bd2953e6f755dce945e95d3b432a74</guid>
    <pubDate>Tue, 26 Jul 2011 13:25:00 +0100</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>Symfony 2</category>
        <category>Symfony 2</category>    
    <description>    C'est annoncé sur le blog officiel de Symfony : la release stable 2.0 est sortie ce jour.&lt;br /&gt;&lt;br /&gt;A cette occasion, plusieurs &quot;launch parties&quot; sont prévues pour permettre aux développeurs de se réunir pour fêter cet évènement.&lt;br /&gt;&lt;br /&gt;Vous trouverez la liste des évènements &lt;a hreflang=&quot;en&quot; href=&quot;http://symfony.com/blog/symfony2-launch-parties&quot;&gt;ici&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Pour ma part, ayant déjà joué un peu avec la béta, je vais préparer un nouveau projet et je posterai différents articles sur son utilisation.&lt;br /&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[Bash] Remplacement de caractères de retour à la ligne par des espaces</title>
    <link>http://phpsymfony.com/index.php?post/2011/07/13/%5BBash%5D-Remplacement-de-caract%C3%A8res-de-retour-%C3%A0-la-ligne-par-des-espaces</link>
    <guid isPermaLink="false">urn:md5:f330abcc9e6a2b8d2c80fcb2c7b4e69c</guid>
    <pubDate>Wed, 13 Jul 2011 18:54:00 +0100</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>BASH</category>
        <category>bash</category><category>tr</category>    
    <description>    &lt;p&gt;Supposons que vous ayez la liste suivante : &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gbretou@gunix:~$ cat test.txt&lt;br /&gt;aaa&lt;br /&gt;bbb&lt;br /&gt;ccc&lt;br /&gt;ddd&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et que vous voulez un résultat sur une ligne, vous pouvez utiliser tr pour convertir vos sauts de ligne en espace simple.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gbretou@gunix:~$ cat test.txt | tr '
' ' '&lt;br /&gt;aaa bbb ccc ddd ati@gm21:~$&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si vous avez un svn st long comme le bras et que vous commitez en ligne de commande : &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;svn st | sed 's/^[AM]//g' | tr '
' ' ' | xargs svn ci -m'My super fun commit message'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si vous voulez éviter des fichiers, pensez au grep -v après le svn st ;)&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[Silex] Premiere utilisation du micro-framework PHP 5.3 Silex</title>
    <link>http://phpsymfony.com/index.php?post/2011/06/13/%5BSilex%5D-Premiere-utilisation-du-micro-framework-Silex</link>
    <guid isPermaLink="false">urn:md5:81a054ce4bbe33e9ac49e6d651549d2d</guid>
    <pubDate>Mon, 13 Jun 2011 13:45:00 +0100</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>Silex</category>
        <category>PHP</category><category>Silex</category><category>Twig</category>    
    <description>    &lt;h2&gt;Présentation de Silex&lt;/h2&gt;
&lt;br /&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://silex-project.org/&quot;&gt;Silex&lt;/a&gt; est un micro-framework pour PHP 5.3 basé sur les briques de Symfony 2 et de Pimple. Ce framework a été créé dans l'objectif de proposer un système simple permettant de réaliser des applications simples sans avoir à utiliser un framework complexe. &lt;br /&gt;Silex a été créé par Fabien Potencier et Igor Wiedler.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Le projet : Jeudi croissants&lt;/h2&gt;
&lt;br /&gt;Nous allons réaliser un projet que vous devriez aimer (ou pas).&lt;br /&gt;Tous les jeudis, nous avons la coutume suivante : une personne désignée doit ramener les croissants et les pains au chocolat pour tout le monde.&lt;br /&gt;Cette personne change bien évidemment chaque semaine.&lt;br /&gt;Nous allons donc réaliser une application se composant de 3 pages: &lt;br /&gt;&amp;nbsp;- d'un front permettant de voir qui est la prochaine personne qui doit ramener les croissants &lt;br /&gt;&amp;nbsp;- d'une page permettant d'augmenter la participation d'un membre&lt;br /&gt;&amp;nbsp;- d'une page permettant de réduire la participation d'un membre&lt;br /&gt;&lt;br /&gt;Cette application n'a pas pour objectif d'être un monstre en matière de sécurité. Il n y aura pas de gestion d'utilisateurs avec des permissions.&lt;br /&gt;Cette coutume est bien évidemment ancrée sous le nom de jeudi croissants (donc pas de Tuesday crescent ou autres ...).&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Mise en place du projet et installation de Silex&lt;/h2&gt;
&lt;br /&gt;Commencons par configurer un vhost très simple : &lt;br /&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
NameVirtualHost *:80
&lt;virtualhost *:80=&quot;&quot;&gt;&amp;lt;VirtualHost *:80&amp;gt;
ServerAdmin webmaster@localhost
ServerName jeudi.local
ServerAlias jeudi.local
DocumentRoot /var/www/jeudi/
DirectoryIndex index.php&lt;br /&gt;&amp;lt;Directory /var/www/jeudi&amp;gt;&lt;br /&gt;                Options Indexes FollowSymLinks MultiViews&lt;br /&gt;                #AllowOverride None&lt;br /&gt;                Order allow,deny&lt;br /&gt;                allow from all&lt;br /&gt;        &amp;lt;/Directory&amp;gt;&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt; &lt;/virtualhost&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;N'oubliez pas de renseigner jeudi.local dans votre fichier /etc/hosts, d'activer le vhost et de recharger la conf apache.&lt;br /&gt;&lt;br /&gt;Pour l'installation de Silex c'est très facile. Il suffit de récupérer le &lt;a hreflang=&quot;en&quot; href=&quot;http://php.net/manual/en/book.phar.php&quot;&gt;phar&lt;/a&gt; et c'est terminé ! &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;cd /var/www/&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;mkdir jeudi&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;cd jeudi&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;wget &quot;http://silex-project.org/get/silex.phar&quot;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Nous aurons besoin du moteur de template &lt;a hreflang=&quot;en&quot; href=&quot;http://www.twig-project.org/&quot;&gt;Twig&lt;/a&gt; pour ce projet.&lt;br /&gt;Twig n'étant pas inclus dans le phar, vous devrez donc le télécharger vous même. Copiez le dans /var/www/jeudi/vendor/twig&lt;br /&gt;&lt;br /&gt;Concernant le stockage des données, nous allons utiliser un simple fichier texte data.txt. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;cd /var/www/jeudi&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;mkdir data&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;touch data/data.txt&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Voici un jeu de fixtures pour votre fichier : &lt;code&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;gbretou:5&lt;br /&gt;atisset:3&lt;br /&gt;mwolff:3&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Assurez vous que le fichier est accessible en écriture.&lt;br /&gt;NB. Il est possible d'utiliser Doctrine 2 avec Silex. Il existe en effet une extension. Cela fera l'objet soit d'une mise à jour de cet article, soit d'un prochain article.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Le code de l'application&lt;/h2&gt;
&lt;br /&gt;On commence donc avec un fichier index.php très basique : &lt;br /&gt;&lt;code&gt;&lt;br /&gt;//index.php&lt;br /&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;require_once __DIR__.'/silex.phar';&lt;br /&gt;$app = new Silex\Application();&lt;br /&gt;// definitions&lt;br /&gt;$app-&amp;gt;run();&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Nous allons devoir ajouter un service pour gérer les intéractions avec le fichier. Nous allons donc créer la classe ParticipationService.&lt;br /&gt;Ce service devra être enregistré dans l'application Silex.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;//index.php&lt;br /&gt;require_once __DIR__.'/ParticipationService.php';&lt;br /&gt;//...&lt;br /&gt;$app['participation'] = $app-&amp;gt;share(function () {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new ParticipationService('./data/data.txt');&lt;br /&gt;});&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Vous trouverez la classe ParticipationService dans l'archive en pièce jointe.&lt;br /&gt;&lt;br /&gt;Afin de pouvoir utiliser Twig, il faudra enregistrer l'extension : &lt;br /&gt;&lt;br /&gt;&lt;code&gt;$app-&amp;gt;register(new Silex\Extension\TwigExtension(), array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'twig.path'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;gt; __DIR__.'/views',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'twig.class_path' =&amp;gt; __DIR__.'/vendor/twig/lib',&lt;br /&gt;));&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;twig.path doit pointer sur votre dossier contenant les fichiers templates.&lt;br /&gt;twig.class_path doit pointer sur le dossier contenant les classes de Twig.&lt;br /&gt;&lt;br /&gt;Nous avons défini que l'application devait se composer de 3 routes : &lt;br /&gt;&amp;nbsp;- une route pour la visualisation&lt;br /&gt;&amp;nbsp;- une route pour l'incrémentation&lt;br /&gt;&amp;nbsp;- une route pour la décrémentation&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;La visualisation&lt;/h3&gt;
&lt;br /&gt;Nous allons définir la route suivante : &lt;br /&gt;&lt;br /&gt;&lt;code&gt;//index.php&lt;br /&gt;$app-&amp;gt;get('/', function () use ($app) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return $app['twig']-&amp;gt;render('index.twig', array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'name'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;gt; 'admin',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'participations' =&amp;gt; $app['participation']-&amp;gt;getParticipations(),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'next'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;gt; $app['participation']-&amp;gt;getNext(),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'matrix'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;gt; $app['participation']-&amp;gt;getParticipationMatrix(),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ));&lt;br /&gt;});&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Avec ce code, lors de l'accès à la homepage du site, le système traitera le template index.twig dans lequel on injecte plusieurs variables : name, participations, next et matrix. Ces variables sont récupérées par le service ParticipationService.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;L'incrémentation et la décrémentation&lt;/h3&gt;
&lt;br /&gt;Voici les routes pour l'incrémentation et la décrémentation : &lt;br /&gt;&lt;code&gt;&lt;br /&gt;//index.php&lt;br /&gt;$app-&amp;gt;get('/increase/{name}/{count}', function ($name, $count) use ($app) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;$app['participation']-&amp;gt;increaseParticipation($name, $count);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;return $app['twig']-&amp;gt;render('update.twig', array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'name' =&amp;gt; $name,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (Exception $e)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;return $app['twig']-&amp;gt;render('error.twig', array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'exception' =&amp;gt; $e-&amp;gt;getMessage(),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;$app-&amp;gt;get('/decrease/{name}/{count}', function ($name, $count) use ($app) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;$app['participation']-&amp;gt;decreaseParticipation($name, $count);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;return $app['twig']-&amp;gt;render('update.twig', array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'name' =&amp;gt; $name,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (Exception $e)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;return $app['twig']-&amp;gt;render('error.twig', array(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'exception' =&amp;gt; $e-&amp;gt;getMessage(),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;});&lt;/code&gt; &lt;br /&gt;&lt;br /&gt;Chaque route se compose de parties variables encadrées par des {}. Ces variables sont ensuite récupérées et transférées à la closure manuellement.&lt;br /&gt;Afin d'avoir une application RESTFUL, on pourrait utiliser un put plutôt qu'un get pour les modifications.&lt;br /&gt;&lt;br /&gt;Pour vous aider dans vos développements, pensez à activer le mode debug : &lt;br /&gt;&lt;br /&gt;&lt;code&gt;$app['debug'] = true;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;br /&gt;Edit du 17/06/2011&lt;/strong&gt; : &lt;br /&gt;
Il est possible de catcher les exceptions mieux que je ne l'ai fait : voir la partie sur les &lt;a hreflang=&quot;en&quot; href=&quot;http://silex-project.org/doc/usage.html#error-handlers&quot;&gt;error handlers&lt;/a&gt;. Je mettrai le code à jour.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;br /&gt;Vous trouverez une archive contenant l'application. N'hésitez pas à me faire part de vos remarques.&lt;br /&gt;&lt;br /&gt;&lt;ins&gt;J'ai aimé&lt;/ins&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;- La rapidité et la simplicité : on a une application avec un feedback visuel en quelques secondes&lt;br /&gt;&amp;nbsp;- La documentation : pour mon utilisation, j'ai trouvé la documentation claire&lt;br /&gt;&lt;br /&gt;&lt;ins&gt;Je n'ai pas aimé (?)&lt;/ins&gt;&lt;br /&gt;&lt;br /&gt;J'aurais souhaité utiliser des tâches pour mettre à jour les informations de participation. Cependant, d'après ce que j'ai constaté, Silex fournit une console qui ne prend en paramètre que 3 valeurs possibles : check, update et version. Je ne sais pas s'il est possible d'étendre ce système pour définir des tâches personnalisées dans le framework.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Comme l'a souligné scrumasteriswatchingu, si vous avez installé suhosin, vous devez ajouter la directive suivante dans votre php.ini&lt;br /&gt;&lt;code&gt;suhosin.executor.include.whitelist = phar&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PS : La coutume Jeudi Croissant a été inventé mwolff ;p&lt;br /&gt;&lt;br /&gt;L'application Jeudi croissant est disponible sur bitbucket : https://bitbucket.org/guiguiboy/jeudi-croissant&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Edit du 16/03/2012&lt;/strong&gt;&lt;br /&gt;Le projet a été mis à jour pour utiliser la dernière version de Silex&lt;br /&gt;&lt;br /&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[PHP] Durée de vie et expiration des sessions</title>
    <link>http://phpsymfony.com/index.php?post/2011/05/24/%5BPHP%5D-Dur%C3%A9e-de-vie-et-expiration-des-sessions</link>
    <guid isPermaLink="false">urn:md5:cd0b31e1ce38176738c6289676dae51e</guid>
    <pubDate>Tue, 24 May 2011 23:29:00 +0100</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>PHP</category>
        <category>PHP</category><category>session</category>    
    <description>    &lt;p&gt;La gestion de l'expiration des sessions de PHP n'est pas triviale surtout quand on utilise le mécanisme par défaut.&lt;/p&gt;
&lt;p&gt;En effet, les informations de sessions sont stockées dans des fichiers sur le serveur. Ces fichiers sont supprimés par une routine (garbage collector) qui détruit les données obsolètes.&lt;/p&gt;
&lt;p&gt;Vous devrez jongler entre les 3 paramètres suivants : &lt;/p&gt;
&lt;p&gt;&amp;nbsp;- &lt;span class=&quot;term&quot;&gt;&lt;em&gt;&lt;tt class=&quot;parameter&quot;&gt;session.gc_maxlifetime : spécifie une période en secondes pendant laquelle les données sont considérées comme corretes. Une fois cette période passée, les données sont alors considères comme obsolètes et sont susceptibles d'être supprimées par le garbage collector.&lt;br /&gt;&lt;/tt&gt;&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;term&quot;&gt;&lt;em&gt;&lt;tt class=&quot;parameter&quot;&gt;- session.gc_probability : &lt;/tt&gt;&lt;/em&gt;&lt;/span&gt;&lt;span class=&quot;term&quot;&gt;&lt;em&gt;&lt;tt class=&quot;parameter&quot;&gt;à utiliser conjointement avec&lt;/tt&gt;&lt;/em&gt;&lt;/span&gt;&lt;span class=&quot;term&quot;&gt;&lt;em&gt;&lt;tt class=&quot;parameter&quot;&gt; session.gc_divisor : permet de définir la probabilité que la routine de garbage collection soit lancé à chaque requête&lt;br /&gt;&lt;/tt&gt;&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;term&quot;&gt;&lt;em&gt;&lt;tt class=&quot;parameter&quot;&gt;- session.gc_divisor : à utiliser conjointement avec session.gc_probability : permet de définir une probabilité que la routine de garbage collection soit lancée à chaque requête&lt;br /&gt;&lt;/tt&gt;&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;(Ces trois paramètres doivent être définis avant l'appel à session_start() si vous souhaitez modifier leur valeur via votre script)&lt;/p&gt;
&lt;p&gt;Avec les valeurs par défaut (session.gc_probability = 1 et session.gc_divisor = 100), vous aurez donc une probabilité de 1% que la routine de garbage collection soit lancée à chaque requête.&lt;/p&gt;
&lt;p&gt;Vous serez donc tenter d'ajuster les valeurs des deux derniers paramètres afin de maximiser la probabilité d'exécution de la routine de garbage collection.&lt;/p&gt;
&lt;p&gt;Vous devez être conscient que le mécanisme est couteux et si vous avez de multiples sessions ouvertes sur votre site, une fréquence d'exécution trop importante peut entrainer des ralentissements&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[VI] Permissions root lors de l'édition d'un fichier verrouillé en écriture</title>
    <link>http://phpsymfony.com/index.php?post/2011/03/23/%5BVI%5D-Permissions-root-lors-de-l-%C3%A9dition-d-un-fichier-verrouill%C3%A9-en-%C3%A9criture</link>
    <guid isPermaLink="false">urn:md5:f22369f3e50bfa99f360c6f27fa23f94</guid>
    <pubDate>Wed, 23 Mar 2011 16:08:00 +0000</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>Editeurs</category>
        <category>vi</category>    
    <description>    &lt;p&gt;Combien de fois, en éditant vos fichiers php.ini par exemple, avez-vous eu ce message&amp;nbsp; &quot;Alerte: Modification d'un fichier en lecture seule&quot;&lt;/p&gt;
&lt;p&gt;Voici la solution :&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:w !sudo tee %&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Avec cette commande, vous n'aurez plus besoin de quitter vi pour le relancer en root juste après.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[Linux] Utilisation courante de tar</title>
    <link>http://phpsymfony.com/index.php?post/2011/02/22/%5BLinux%5D-Utilisation-courante-de-tar</link>
    <guid isPermaLink="false">urn:md5:84c5906d002d7d4b1203ecc847df7833</guid>
    <pubDate>Tue, 22 Feb 2011 18:26:00 +0000</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>Linux</category>
        <category>archive</category><category>linux</category><category>tar</category>    
    <description>    &lt;p&gt;tar est un utilitaire d'archivage permettant de stocker et d'extraire des fichiers d'une archive.&lt;/p&gt;
&lt;p&gt;Voici des cas d'utilisation de cet utilitaire que vous serez amenés à rencontrer le plus souvent dans votre (belle) vie de programmeur : &lt;/p&gt;
&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Création d'archive à partir d'un répertoire : &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;tar -cvf archive.tar %DIR%&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Création d'archive gz à partir d'un répertoire : &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;tar -cvzf archive.tar.gz %DIR%&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Création d'archive bzip2 à partir d'un répertoire : &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;tar -cvjf archive.tar.bz %DIR%&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;&lt;strong&gt;Extraction du contenu d'une archive dans le répertoire courant : &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;tar -xvf archive.tar&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Extraction du fichier test.txt contenu dans une archive dans le répertoire courant : &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;tar -xvf archive.tar test.txt&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Extraction du contenu d'une archive gzippée dans le dossier %DIR% :&lt;/strong&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;tar -xvzf archive.tar.gz -C %DIR%&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Extraction du contenu d'une archive bzip2 dans le répertoire courant :&amp;nbsp;
&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;tar -xvjf archive.tar.bz&lt;/p&gt;
&lt;br /&gt;Pour tous renseignements supplémentaires : man tar est votre ami.&lt;br /&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[PHP] remplacement de split par preg_split : split2preg_split</title>
    <link>http://phpsymfony.com/index.php?post/2011/02/08/%5BPHP%5D-remplacement-de-split-par-preg_split-%3A-split2preg_split</link>
    <guid isPermaLink="false">urn:md5:cf0ade748383410eabde2add8ac4555e</guid>
    <pubDate>Tue, 08 Feb 2011 22:46:00 +0000</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>PHP</category>
        <category>PCRE</category><category>PHP</category><category>POSIX</category><category>preg_split</category><category>split</category>    
    <description>    &lt;p&gt;Depuis PHP 5.3, la fonction split est devenue obsolète (voir &lt;a hreflang=&quot;fr&quot; href=&quot;http://fr2.php.net/split&quot;&gt;le manuel PHP&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Il convient donc de la remplacer par preg_split, son équivalente plus moderne qui utilise l'extension PCRE.&lt;/p&gt;
&lt;p&gt;J'ai donc développé un bout de code qui va permettre de remplacer les appels split par preg_split.&lt;/p&gt;
&lt;p&gt;Voici le script : (il affiche sur la sortie standard le fichier converti)&lt;/p&gt;
&lt;br /&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;/****************************************************************************/&lt;br /&gt;/************************ split2preg_split **********************************/&lt;br /&gt;/************************ author : gbretou **********************************/&lt;br /&gt;/****************************************************************************/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;$file&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $_SERVER['argv'][1];&lt;br /&gt;$lines&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = file($file);&lt;br /&gt;foreach ($lines as $line)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (preg_match('|(.*)(?&amp;lt;![a-zA-Z0-9-_])(split\(([\'\&quot;\$]{1}(.*)[\'\&quot;]?),(.*)$)|', $line, $matches))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $pattern = $matches[3];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $pattern = recalculateRegex($pattern);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; echo $matches[1] . &quot;preg_split(&quot; . $pattern . &quot;,&quot; . $matches[5] . &quot;
&quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; echo $line;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;&amp;nbsp;* Recalculates the regex&lt;br /&gt;&amp;nbsp;* 2 cases : &lt;br /&gt;&amp;nbsp;*&amp;nbsp; - case 1 : a PHP variable is provided for the pattern&lt;br /&gt;&amp;nbsp;*&amp;nbsp; - case 2 : a simple string is provided&lt;br /&gt;&amp;nbsp;*/&lt;br /&gt;function recalculateRegex($pattern)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $delimiter = '/';&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (substr($pattern, 0, 1) == '$')&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return sprintf(&quot;'%s' . str_replace('%s', '\%s', %s) . '%s'&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $delimiter,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $delimiter,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $delimiter,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $pattern,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $delimiter&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return sprintf(&quot;%s%s%s%s%s&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; substr($pattern, 0, 1),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $delimiter,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; str_replace($delimiter, &quot;\$delimiter&quot;, substr($pattern, 1, -1)),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $delimiter,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; substr($pattern, 0, 1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Pour le lancer sur un fichier PHP, vous pouvez faire :
&lt;p&gt;&lt;code&gt;php split_modifier.php [FICHIER]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;ou si vous souhaitez le lancer sur tous les fichiers PHP d'un répertoire : &lt;/p&gt;
&lt;p&gt;&lt;code&gt;find . -name '*.php' | xargs php split_modifier.php &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Ce programme présente plusieurs limites : &lt;/p&gt;
&lt;p&gt;&amp;nbsp;- si votre split est sur plusieurs lignes, il ne sera pas pris en compte car l'expression régulière ne sera pas matchée&lt;/p&gt;
&lt;p&gt;&amp;nbsp;- le fait d'ajouter un délimiteur ne permet pas de convertir toutes les expressions POSIX en PCRE (&lt;a hreflang=&quot;fr&quot; href=&quot;http://fr2.php.net/manual/en/intro.pcre.php#94011&quot;&gt;exemple&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;- il affiche le résultat sur la sortie standard et ne fait pas de remplacement directement dans le fichier&lt;/p&gt;
&lt;p&gt;En fonction des retours que j'aurais, je modifierais le script.&lt;/p&gt;
&lt;p&gt;Néanmoins, pour le deuxième point, je vous propose de créer vos propres tests puis de comparer si le retour du fichier avec split est identique que celui avec preg_split. Voici déjà quelques lignes :&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;$delimiter = &quot;/&quot;;&lt;br /&gt;var_dump(split('/', &quot;test / test&quot;));&lt;br /&gt;var_dump(split('\|', &quot;test / test&quot;)); //this is a comment&lt;br /&gt;var_dump(split('\|', &quot;test | test&quot;));&lt;br /&gt;var_dump(split('/ ', &quot;test / test&quot;)); //this is a comment&lt;br /&gt;var_dump(split('[/.-]', '31-12-2010'));&lt;br /&gt;var_dump(split('[/.-]', '31/12/2010'));&lt;br /&gt;var_dump(split(&quot;[
\t ]+&quot;, &quot;Please cut&amp;nbsp;&amp;nbsp; \t me 
 in pieces&quot;));&lt;br /&gt;var_dump(split('\|/', 'test /test |/ test / test'));&lt;br /&gt;var_dump(split($delimiter, 'test / test / test / test'));&lt;br /&gt;var_dump(preg_split('|t/t|', 'this another test')); //must not be changed&lt;br /&gt;var_dump(my_split('/', 'this / is / another / test'));&lt;br /&gt;&lt;br /&gt;function my_split($pattern, $value) //must not be changed!&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return split($pattern, $value);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;/p&gt;
&lt;br /&gt;Pour faire une comparaison, je vous propose de suivre le cheminement suivant :
&lt;p&gt;&amp;nbsp;- mettez vos tests avec split dans le fichier split_test.php&lt;/p&gt;
&lt;p&gt;&amp;nbsp;- remplacez vos split par preg_split dans un fichier preg_split_test.php&lt;/p&gt;
&lt;p&gt;&amp;nbsp;- lancez les deux fichiers puis comparez leur retour via un diff.&lt;/p&gt;
&lt;p&gt;(MAJ le 18/02 pour gestion des fonctions)&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[Apache] Module mod_pagespeed</title>
    <link>http://phpsymfony.com/index.php?post/2011/01/11/%5BApache%5D-Module-mod_pagespeed</link>
    <guid isPermaLink="false">urn:md5:a3450a99039fa288cafa8d536abeed0a</guid>
    <pubDate>Tue, 11 Jan 2011 22:58:00 +0000</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>Apache</category>
        <category>apache</category>    
    <description>    &lt;p&gt;Depuis l'année dernière, la vitesse de chargement d'une page est devenue un critère pris en compte dans l'algorithme de classement de Google. Il est donc utile, pour le bien de son pagerank, et pour le bien de ses utilisateurs de travailler sur ce critère.&lt;/p&gt;
&lt;p&gt;Il existe de nombreux axes permettant de réduire le temps de chargement des pages : &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Quantité de données sur une page,&lt;/li&gt;
&lt;li&gt;Complexité algorithmique,&lt;/li&gt;
&lt;li&gt;Compression des données,&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour ma part, je me suis interessé au module mod_pagespeed pour Apache 2. Il s'agit d'un module développé par Google.&lt;/p&gt;
&lt;p&gt;Ce module va permettre d'optimiser les pages web et les ressources qu'elles comportent. Ceci est réalisé par la réécriture des ressources par des filtres qui implémentent les meilleurs pratiques du développement web. mod_pagespeed inclut de multiples filtres qui optimisent les feuilles de style CSS, le javascript et le HTML. Il inclut également des filtres pour l'optimisation des images JPEG et PNG. &lt;/p&gt;
&lt;p&gt;Les filtres possibles sont : &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Concaténation de fichiers CSS&lt;/li&gt;
&lt;li&gt;Optimisation des images (mise à l'échelle, recompression)&lt;/li&gt;
&lt;li&gt;Minification du javascript&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Une liste exhaustive peut-être trouvée sur &lt;a hreflang=&quot;en&quot; href=&quot;http://code.google.com/intl/fr/speed/page-speed/docs/filters.html&quot;&gt;ici&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Installation (sur Debian) : &lt;/p&gt;
&lt;p&gt;&amp;nbsp;wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-beta_current_i386.deb&lt;br /&gt;&amp;nbsp;sudo dpkg -i mod-pagespeed-beta_current_i386.deb&lt;br /&gt;&amp;nbsp;sudo /etc/init.d/apache2 restart&lt;/p&gt;
&lt;p&gt;Pour le moment, je n'ai testé ce module qu'avec un petit site. Je vais voir les résultats et posterai un retour d'expérience après avoir testé sur un site plus conséquent.&lt;/p&gt;
&lt;p&gt;&lt;a hreflang=&quot;en&quot; href=&quot;http://code.google.com/intl/fr/speed/page-speed/docs/module.html&quot;&gt;Lien vers le site officiel du projet.&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[python] Spécial Noel : Tirage &quot;aléatoire&quot; d'une liste de cadeau de noel</title>
    <link>http://phpsymfony.com/index.php?post/2010/12/22/%5Bpython%5D-Sp%C3%A9cial-Noel-%3A-Tirage-al%C3%A9atoire-de-listes-par-personne</link>
    <guid isPermaLink="false">urn:md5:5b94e95b2d5a3b93862a16d662afb655</guid>
    <pubDate>Wed, 22 Dec 2010 00:04:00 +0000</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>Python</category>
            
    <description>    &lt;p&gt;Article spécial noël ! &lt;/p&gt;
&lt;p&gt;Voici un script en python qui vous permettra de faire une liste de cadeaux &quot;aléatoire&quot; en fonction d'une liste de participants. Ainsi, vous saurez qui va offrir un cadeau à qui.&lt;/p&gt;
&lt;p&gt;Vous précisez en entrée les participants.&lt;/p&gt;
&lt;p&gt;L'algorithme utilisé par ce programme n'est pas efficace dans la mesure où il mélange les tableaux (offreurs et receveurs) puis vérifie que l'ensemble est une solution du système. &lt;/p&gt;
&lt;p&gt;Néanmoins, les résultats sont rapides pour 7 participants.&lt;/p&gt;
&lt;p&gt;import random&lt;br /&gt;
senders &amp;nbsp; = ['AAA', 'BBB', 'CCC', 'DDD', 'EEE', 'FFF', 'GGG']&lt;br /&gt;
receivers = senders[:]&lt;br /&gt;
&lt;br /&gt;
complete = False&lt;br /&gt;
while complete == False:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;random.shuffle(receivers)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;complete = True&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for i in range(len(receivers)):&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if receivers[i] == senders[i]:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;complete = False&lt;br /&gt;
&lt;br /&gt;
for i in range(len(receivers)):&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;print senders[i] + &quot; doit offrir un cadeau a &quot; + receivers[i]&lt;/p&gt;
&lt;p&gt;C'était par le même occasion un petit défi me permettant de découvrir python, langage que je souhaiterais approfondir par la suite.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[Linux] Mise en place adresse IP statique sur Debian Lenny</title>
    <link>http://phpsymfony.com/index.php?post/2010/12/20/%5BLinux%5D-Mise-en-place-adresse-IP-statique-sur-Debian-Lenny</link>
    <guid isPermaLink="false">urn:md5:005a9c6f7244c834e86fe8cd46f721fc</guid>
    <pubDate>Mon, 20 Dec 2010 22:43:00 +0000</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>Linux</category>
        <category>debian</category><category>linux</category>    
    <description>    &lt;p&gt;Pour mettre en place une adresse IP fixe sur une debian, éditez le fichier /etc/network/interfaces&lt;/p&gt;
&lt;p&gt;Exemple : &lt;/p&gt;
&lt;p&gt;gbretou@gunix:~$ cat /etc/network/interfaces&lt;br /&gt;# This file describes the network interfaces available on your system&lt;br /&gt;# and how to activate them. For more information, see interfaces(5).&lt;br /&gt;&lt;br /&gt;# The loopback network interface&lt;br /&gt;auto lo&lt;br /&gt;iface lo inet loopback&lt;br /&gt;&lt;br /&gt;# The primary network interface&lt;br /&gt;allow-hotplug eth0&lt;br /&gt;#iface eth0 inet dhcp&lt;br /&gt;iface eth0 inet static&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; address 192.168.0.177&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; netmask 255.255.255.0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; network 192.168.0.0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; broadcast 192.168.0.255&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; gateway 192.168.0.254&lt;/p&gt;
&lt;p&gt;Pour configurer les DNS, vous devrez éditer le fichier /etc/resolv.conf&lt;/p&gt;
&lt;p&gt;Exemple : &lt;/p&gt;
&lt;p&gt;gbretou@gunix:~$ cat /etc/resolv.conf&lt;br /&gt;nameserver 192.168.1.1&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>[VirtualBox] Augmentation taille disque dur virtuel VDI avec HD Clone</title>
    <link>http://phpsymfony.com/index.php?post/2010/11/23/%5BVirtualBox%5D-Augmentation-taille-disque-dur</link>
    <guid isPermaLink="false">urn:md5:f970c1658322d6b08901203e5ee045a7</guid>
    <pubDate>Tue, 23 Nov 2010 19:22:00 +0000</pubDate>
    <dc:creator>Guillaume BRETOU</dc:creator>
        <category>hd clone</category><category>linux</category><category>machine virtuelle</category><category>virtual box</category>    
    <description>    &lt;p&gt;Lorsque l'on se créé une machine virtuelle avec VirtualBox, il faut associer un disque dur virtuel qui sera attaché à la machine. On lui spécifie une taille à la création et on commence à utiliser sa VM.&lt;/p&gt;
&lt;p&gt;Sauf que, plus le temps passe, plus votre disque se remplit, jusqu'au jour où vous vous rendez compte que vous devez augmenter la taille de votre disque dur. &lt;/p&gt;
&lt;p&gt;Voici les différentes étapes à suivre pour mener à bien votre mission.&lt;/p&gt;
&lt;p&gt;Nous allons procéder en 2 étapes : &lt;/p&gt;
&lt;p&gt;&amp;nbsp;- création d'un nouveau disque de taille supérieure&lt;/p&gt;
&lt;p&gt;&amp;nbsp;- copie du disque principal vers le nouveau disque&lt;/p&gt;
&lt;p&gt;(Personnellement, j'ai compté moins d'une heure pour la totalité de l'opération. Cette information est donnée à titre indicatif car de multiples paramètres peuvent intervenir (puissance machine, taille originale, collègue qui vient vous raconter sa vie, ...).&lt;/p&gt;
&lt;h2&gt;Création d'un nouveau disque dur virtuel&lt;/h2&gt;
&lt;p&gt;Cliquez sur configuration -&amp;gt;puis stockage&lt;/p&gt;
&lt;p&gt;Sélectionnez votre contrôleur, puis Ajouter un nouveau disque dur.&lt;/p&gt;
&lt;p&gt;Créez vous un nouveau média avec une taille fixe ou dynamique. Je n'ai pas fais de benchmarks qui permettrait de savoir si un type de disque est mieux qu'un autre. Puis donnez lui une taille supérieure à celle de votre disque dur.&lt;/p&gt;
&lt;p&gt;Par défaut, ce disque sera en esclave secondaire.&lt;/p&gt;
&lt;p&gt;Montez ensuite l'image de HD Clone. &lt;a hreflang=&quot;en&quot; href=&quot;http://www.miray.de/download/sat.hdclone.html&quot;&gt;Vous pourrez la télécharger ici&lt;/a&gt;. Prenez la version universal package.&lt;/p&gt;
&lt;p&gt;Vérifiez enfin l'ordre de boot (ordre d'amorçage en français). Il faut booter sur le lecteur de cd-rom avant le disque dur.&lt;/p&gt;
&lt;h2&gt;Copie du disque dur principal &lt;/h2&gt;
&lt;p&gt;Une fois ceci fait, vous pouvez démarrer votre VM.&lt;/p&gt;
&lt;p&gt;J'ai pris quelques screenshots pour mieux vous guider durant le processus : &lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://phpsymfony.com/imgs/44/10.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://phpsymfony.com/imgs/44/11.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Choisissez Drive -&amp;gt; Drive, puis Next&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://phpsymfony.com/imgs/44/12.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Sélectionnez le disque source ...&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://phpsymfony.com/imgs/44/13.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Puis le disque cible&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://phpsymfony.com/imgs/44/14.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Choisissez des options pour la copie (les options par défaut sont suffisantes)&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://phpsymfony.com/imgs/44/15.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Vous pourrez ensuite ajuster vos partitions. Si vous souhaitez utiliser la totalité du disque, gardez les valeurs par défaut.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://phpsymfony.com/imgs/44/16.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;La copie commence dès que vous cliquez sur &quot;Start&quot;&lt;/p&gt;
&lt;p&gt;Une fois la copie terminée, choisissez &quot;automatically&quot; lorsque HD Clone vous propose d'ajuster automatiquement des données de partition.&lt;/p&gt;
&lt;p&gt;Vous pouvez ensuite éteindre la VM.&lt;/p&gt;
&lt;p&gt;Retirez HD Clone du lecteur de CD virtuel.&lt;/p&gt;
Retirez l'ancien disque dur (le plus petit) de la liste.&lt;br /&gt;
&lt;p&gt;Puis relancez votre VM&lt;/p&gt;
&lt;p&gt;Et : &lt;/p&gt;
&lt;p&gt;df -h &lt;/p&gt;
&lt;p&gt;Et voila, c'est terminé vous avez votre nouveau disque dur.&lt;/p&gt;
&lt;p&gt;Pour ma part, j'ai eu des erreurs lors de la copie. Ces erreurs ont toutefois été résolues avec l'utilisation de fsck.&lt;/p&gt;</description>
    
    
    
      </item>
    
</channel>
</rss>