<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://mirmodynamics.com/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>Mirmo Dynamics - Tag - doc</title>
  <link>http://mirmodynamics.com/</link>
  <atom:link href="http://mirmodynamics.com/feed/tag/doc/rss2" rel="self" type="application/rss+xml"/>
  <description>Si tu kiffes pas reunoi, t'écoutes pas et puis c'est tout.</description>
  <language>en</language>
  <pubDate>Sun, 14 Mar 2010 19:59:01 +0100</pubDate>
  <copyright>2003-2009 &amp;copy; Geoffrey Bachelet</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Débuter avec le Zend Framework</title>
    <link>http://mirmodynamics.com/post/2007/04/12/Debuter-avec-le-Zend-Framework</link>
    <guid isPermaLink="false">urn:md5:e1875eb76e5eb90ebb656be4b001833a</guid>
    <pubDate>Thu, 12 Apr 2007 00:31:00 +0200</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Coding</category>
        <category>doc</category><category>howto</category><category>php</category><category>traduction</category><category>tutorial</category><category>zend framework</category>    
    <description>    &lt;p&gt;&lt;a href=&quot;http://akrabat.com/2007/04/11/premiers-pas-avec-le-zend-framework/&quot;&gt;Pour&lt;/a&gt; &lt;a href=&quot;http://g-rossolini.developpez.com/tutoriels/php/zend-framework/debuter/?page=sommaire&quot;&gt;info&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;Je suis un peu triste parce que je voulais m'atteler à cette tâche, mais bon il faut croire que j'ai trop lambiné :)&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2007/04/12/Debuter-avec-le-Zend-Framework#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2007/04/12/Debuter-avec-le-Zend-Framework#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/756</wfw:commentRss>
      </item>
    
  <item>
    <title>Mini Howto: Serveur et Packages PEAR</title>
    <link>http://mirmodynamics.com/post/2007/03/02/Mini-Howto%3A-Serveur-et-Packages-PEAR</link>
    <guid isPermaLink="false">urn:md5:a4af0a22fcb4f4e307699e4207bc6406</guid>
    <pubDate>Fri, 02 Mar 2007 12:11:00 +0100</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Geekeries</category>
        <category>chiara</category><category>doc</category><category>howto</category><category>package</category><category>pear</category><category>php</category>    
    <description>    &lt;p&gt;Pour installer le serveur &lt;acronym&gt;PEAR&lt;/acronym&gt;, c'est simple:&lt;/p&gt;


&lt;pre&gt;pear channel-discover pear.chiaraquartet.net
pear install chiara/Chiara_PEAR_Server
pear run-scripts Chiara_PEAR_Server&lt;/pre&gt;


&lt;p&gt;Ensuite on répond aux question, et c'est automagique.&lt;/p&gt;


&lt;p&gt;Après, pour créer des packages, ça se corse. Tout d'abord, on a besoin de &lt;code&gt;PEAR_PackageFileManager&lt;/code&gt;:&lt;/p&gt;


&lt;pre&gt;pear install PEAR_PackageFileManager&lt;/pre&gt;


&lt;p&gt;Ensuite, le but est de générer les &lt;code&gt;package.xml&lt;/code&gt; qui vont bien. Voilà comment j'ai procédé pour le package &lt;code&gt;Zend&lt;/code&gt;:&lt;/p&gt;


&lt;pre&gt;mkdir -p ~/pear/zend/src &amp;amp;&amp;amp; cd ~/pear/zend
wget http://framework.zend.com/download/tgz -O - | tar xzC ~
mv ~/ZendFramework-0.8.0/library/Zend* src/
php ./mkpkg.php make
cd src &amp;amp;&amp;amp; pear package&lt;/pre&gt;


&lt;p&gt;Ceux qui ont bien suivi auront noté que &lt;code&gt;mkpkg.php&lt;/code&gt; est sorti un peu de l'espace :-) Vous trouverez son contenu à la fin du billet.&lt;/p&gt;


&lt;p&gt;Pour résumer, on créé un répertoire de travail (&lt;code&gt;~/pear/zend/&lt;/code&gt;), dans lequel on créé un répertoire &lt;code&gt;src&lt;/code&gt;, qui contiendra tous les fichiers du package, puis le script &lt;code&gt;mkpkg.php&lt;/code&gt; se charge 1) d'analyser le contenu de &lt;code&gt;src&lt;/code&gt;, et 2) de créer le &lt;code&gt;package.xml&lt;/code&gt; qui va bien, selon les instructions qui lui sont fournies.&lt;/p&gt;


&lt;p&gt;Nous disposons désormais  d'un package &lt;code&gt;Zend-0.8.0.tgz&lt;/code&gt; dans &lt;code&gt;~/pear/zend/src&lt;/code&gt;, que nous n'avons plus qu'a uploader via l'interface d'administration du serveur &lt;acronym&gt;PEAR&lt;/acronym&gt; précédemment installé :-)&lt;/p&gt;


&lt;p&gt;Le fichier &lt;code&gt;mkpkg.php&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;?php

require_once('PEAR/PackageFileManager2.php');

PEAR::setErrorHandling(PEAR_ERROR_DIE);

$packagexml = new PEAR_PackageFileManager2;

$e = $packagexml-&amp;gt;setOptions(array(
    'baseinstalldir' =&amp;gt; '/',
    'packagedirectory' =&amp;gt; dirname(__FILE__).'/src',
));

$packagexml-&amp;gt;setPackage('Zend');
$packagexml-&amp;gt;setSummary('Zend Framework');
$packagexml-&amp;gt;setDescription('The Zend\'s PHP Framework');
$packagexml-&amp;gt;setChannel('pear.phpmafia.net');
$packagexml-&amp;gt;setAPIVersion('0.8.0');
$packagexml-&amp;gt;setReleaseVersion('0.8.0');
$packagexml-&amp;gt;setReleaseStability('devel');
$packagexml-&amp;gt;setAPIStability('devel');
$packagexml-&amp;gt;setNotes(&amp;quot;Still a preview release&amp;quot;);
$packagexml-&amp;gt;setPackageType('php'); // this is a PEAR-style php script package
$packagexml-&amp;gt;addRelease(); // set up a release section
$packagexml-&amp;gt;setPhpDep('5.1.2');
$packagexml-&amp;gt;setPearinstallerDep('1.4.0a12');
$packagexml-&amp;gt;addMaintainer('lead', 'ash', 'Geoffrey Bachelet', 'geoffrey+pear@zubrowka.org');
$packagexml-&amp;gt;setLicense('New BSD License', 'http://framework.zend.com/license/new-bsd');
$packagexml-&amp;gt;generateContents(); // create the &amp;lt;contents&amp;gt; tag

$pkg = &amp;amp;$packagexml-&amp;gt;exportCompatiblePackageFile1(); // get a PEAR_PackageFile object

if (isset($_GET['make']) || (isset($_SERVER['argv']) &amp;amp;&amp;amp; @$_SERVER['argv'][1] == 'make')) {
    $pkg-&amp;gt;writePackageFile();
    $packagexml-&amp;gt;writePackageFile();
} else {
    $pkg-&amp;gt;debugPackageFile();
    $packagexml-&amp;gt;debugPackageFile();
}

?&amp;gt;
&lt;/pre&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2007/03/02/Mini-Howto%3A-Serveur-et-Packages-PEAR#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2007/03/02/Mini-Howto%3A-Serveur-et-Packages-PEAR#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/751</wfw:commentRss>
      </item>
    
  <item>
    <title>Interfaces et Classes Abstraites</title>
    <link>http://mirmodynamics.com/post/2007/01/31/Interfaces-et-Classes-Abstraites</link>
    <guid isPermaLink="false">urn:md5:7eff991a33b1612a701afab5a0ed3233</guid>
    <pubDate>Wed, 31 Jan 2007 09:08:00 +0100</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Coding</category>
        <category>bonnes pratiques</category><category>concepts</category><category>doc</category><category>oop</category><category>opinions</category><category>php</category>    
    <description>&lt;p&gt;Les concepts de classes abstraites et d'interfaces sont souvents assez flous quand on débute dans la programmation objet, et on se fourvoie assez souvent sur leur utilisation et leur but. Voila une petite explication qui j'espère sera 1) juste et 2) assez claire pour tout le monde. Si vous pensez que je me fourvoie sur ces 2 concepts de base de la &lt;acronym&gt;POO&lt;/acronym&gt;, n'hésitez pas à me le faire savoir !&lt;/p&gt;    &lt;p&gt;Commençons par le commencement: l'Interface. Une Interface définit une &lt;acronym&gt;API&lt;/acronym&gt; (Application Programming Interface), dont le seul et unique but est de décrire les méthodes disponibles pour un objet donné. Une Interface ne contient pas de code fonctionnel, seulement des synopsis de méthodes et d'attributs. Par exemple, l'utilisation du mot clé &amp;quot;instanceof&amp;quot; permet de déterminer si un objet donné implémente ou non une interface donnée, et d'adapter le comportement de l'application selon la réponse. Le &amp;quot;type hinting&amp;quot; permet également ce genre de choses:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;?php

interface Bar_Interface {
      public function doSomething();
}

class Bar implements Bar_Interface {
      public function doSomething() {
            echo &amp;quot;something was done.&amp;quot;;
      }
}

class Foo {
      public function doSomething(Bar_Interface $bar) {
            $bar-&amp;gt;doSomething();
      }
}

?&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Dans cet exemple, quand Foo::doSomething() est executée, on est certain que l'objet $bar dispose de la méthode doSomething car il implémente l'Interface Bar_Interface.&lt;/p&gt;


&lt;p&gt;Vient ensuite la classe abstraite. La classe abstraite, &amp;quot;abstract class&amp;quot; en V.O., se comporte comme un squelette d'objet. Elle est utile dans le cas où on utilise une série d'objets d'une même famille qui partagent du code commun, mais qui comportent tous leurs particularités propres. Dans ce cas de figure, on commence par implémenter le code commun dans la classe abstraite, dont hériteront les autres objets, dans lesquels le code spécifique pourra à son tour être implémenté. C'est très utile pour certains Design Pattern, comme par exemple &amp;quot;Adapter&amp;quot; ou &amp;quot;Proxy&amp;quot;, qui ont tous deux pour but de permettre des stratégies différentes pour une même situation, situation qui présente le plus souvent des points similaires quelque soit la stratégie adoptée.&lt;/p&gt;



&lt;p&gt;En règle générale, une classe abstraite implémente une interface (et un exemple d'Adapter en cadeau bonux):&lt;/p&gt;

&lt;pre&gt;
&amp;lt;?php

interface Bar_Adapter_Interface {
      public function doSomething();
}

class Bar {
      public function __construct(Bar_Adapter_Interface $adapter) {
            $this-&amp;gt;_adapter = $adapter;
      }

      public function doSomething() {
            return $this-&amp;gt;_adapter-&amp;gt;doSomething();
      }

      static public function factory($adapter) {
            $className = &amp;quot;Bar_Adapter_&amp;quot;.$adapter;
            if (!class_exists($className)) {
                  throw new Exception('Adapter not available: '.$adapter);
            } else {
                  return new Bar(new $className);
            }
      }
}

abstract class Bar_Adapter_Abstract implements Bar_Adapter_Interface {
      protected function getSomething() {
            return &amp;quot;la méthode pour accéder a ce truc est la même pour tout le monde&amp;quot;;
      }
}

class Bar_Adapter_Explode extends Bar_Adapter_Abstract {
      public function doSomething() {
            return explode(' ', $this-&amp;gt;getSomething());
      }
}

class Bar_Adapter_PregSplit extends Bar_Adapter_Abstract {
      public function doSomething() {
            return preg_split('/ /', $this-&amp;gt;getSomething());
      }
}

$bar = Bar::factory('Explode');
print_r($bar-&amp;gt;doSomething());

?&amp;gt;
&lt;/pre&gt;


&lt;p&gt;Ici, l'objet Bar offre la méthode doSomething, qui présentement retourne une chaine explosée, et on propose deux adapteurs pour se faire, l'un utilisant explode(), l'autre preg_split(). Bien sur, cet exemple est complètement trivial :-)&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2007/01/31/Interfaces-et-Classes-Abstraites#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2007/01/31/Interfaces-et-Classes-Abstraites#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/739</wfw:commentRss>
      </item>
    
  <item>
    <title>Migrer un dépot subversion</title>
    <link>http://mirmodynamics.com/post/2006/11/09/Migrer-un-depot-subversion</link>
    <guid isPermaLink="false">urn:md5:84c41cd08be4b33fce92f3f42254d080</guid>
    <pubDate>Thu, 09 Nov 2006 17:25:00 +0100</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Geekeries</category>
        <category>doc</category><category>howto</category><category>svn</category><category>unix</category>    
    <description>    &lt;p&gt;Imaginons que vous souhaitiez déplacer votre dépôt subversion &lt;em&gt;myproject&lt;/em&gt; d'une machine &lt;em&gt;old-server&lt;/em&gt; à une machine &lt;em&gt;new-server&lt;/em&gt;. Vite fait, bien fait:&lt;/p&gt;


&lt;pre&gt;old-server# svnadmin dump /var/lib/subversion/myproject &amp;gt; ~/myproject.svndump
old-server# scp ~/myproject.svndump new-server:
new-server# svnadmin create /var/lib/subversion/myproject
new-server# svnadmin load /var/lib/subversion/myproject &amp;lt; ~/myproject.svndump&lt;/pre&gt;


&lt;p&gt;&lt;strong&gt;Attention&lt;/strong&gt;, il vous faut par contre migrer vos éventuelles &lt;em&gt;hooks&lt;/em&gt; à la main, ils ne sont effectivement pas gérés par &lt;code&gt;svndump&lt;/code&gt;. Une autre méthode, incluant les &lt;em&gt;hooks&lt;/em&gt; celle-ci, serait d'utiliser &lt;code&gt;svnadmin hotcopy&lt;/code&gt;, mais je n'ai pas testé.&lt;/p&gt;


&lt;p&gt;Plus d'infos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://svnbook.red-bean.com/nightly/en/svn.ref.svnadmin.c.dump.html&quot;&gt;svnadmin help dump&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://svnbook.red-bean.com/nightly/en/svn.ref.svnadmin.c.load.html&quot;&gt;svnadmin help load&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://svnbook.red-bean.com/nightly/en/svn.ref.svnadmin.c.hotcopy.html&quot;&gt;svnadmin help hotcopy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2006/11/09/Migrer-un-depot-subversion#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2006/11/09/Migrer-un-depot-subversion#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/716</wfw:commentRss>
      </item>
    
  <item>
    <title>Incubated</title>
    <link>http://mirmodynamics.com/post/2006/11/01/Incubated</link>
    <guid isPermaLink="false">urn:md5:7a9cdfbfea0dc5e4f1cc96795fdb0db3</guid>
    <pubDate>Wed, 01 Nov 2006 16:10:00 +0100</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Geekeries</category>
        <category>bonnes pratiques</category><category>doc</category><category>google</category><category>librairie</category><category>microformats</category><category>optimisation</category><category>organisation</category><category>php</category><category>sso</category><category>svn</category><category>sécurité</category><category>ubuntu</category><category>unit testing</category><category>unix</category><category>way of life</category>    
    <description>&lt;p&gt;Les liens interressants (ou pas) de la semaine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://microformats.org/&quot; title=&quot;http://microformats.org/&quot;&gt;http://microformats.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.georss.org/&quot; title=&quot;http://www.georss.org/&quot;&gt;http://www.georss.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.thinkvitamin.com/features/ajax/create-a-searchable-google-map&quot; title=&quot;http://www.thinkvitamin.com/features/ajax/create-a-searchable-google-map&quot;&gt;http://www.thinkvitamin.com/feature...&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://features.launchpad.net/distros/ubuntu/+specs&quot; title=&quot;https://features.launchpad.net/distros/ubuntu/+specs&quot;&gt;https://features.launchpad.net/dist...&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://iwantmyopenid.org/bounty&quot; title=&quot;http://iwantmyopenid.org/bounty&quot;&gt;http://iwantmyopenid.org/bounty&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://devzone.zend.com/node/view/id/1113&quot; title=&quot;http://devzone.zend.com/node/view/id/1113&quot;&gt;http://devzone.zend.com/node/view/i...&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://weierophinney.net/matthew/uploads/php_development_best_practices.pdf&quot; title=&quot;http://weierophinney.net/matthew/uploads/php_development_best_practices.pdf&quot;&gt;http://weierophinney.net/matthew/up...&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;    &lt;p&gt;J'ai pas mal entendu parler des microformats ces derniers temps, sans vraiment prendre le temps de me pencher dessus. &lt;a href=&quot;http://www.microformats.org/&quot;&gt;microformats.org&lt;/a&gt; présente l'occasion de se plonger dedans et de comprendre que finalement, les microformats peuvent être un facteur de développement non négligeable pour un site ou une application web. &lt;a href=&quot;http://www.georss.org/&quot;&gt;GeoRSS&lt;/a&gt; de son côté propose une implémentation &lt;em&gt;simple&lt;/em&gt; et &lt;em&gt;puissante&lt;/em&gt; (c'est eux qui le disent) du &lt;a href=&quot;http://en.wikipedia.org/wiki/Geotagging&quot;&gt;Geotagging&lt;/a&gt;. A voir si on ne peut pas coupler tout ça avec quelques pirouettes sur &lt;a href=&quot;http://mirmodynamics.com/post/2006/11/01/&quot;&gt;Google Maps&lt;/a&gt;...&lt;/p&gt;


&lt;p&gt;Pendant ce temps, chez Canonical, on établit déjà les &lt;a href=&quot;https://features.launchpad.net/distros/ubuntu/+specs&quot;&gt;specifications fonctionnelles de Feisty Fawn&lt;/a&gt;, et c'est assez prometteur :-)&lt;/p&gt;


&lt;p&gt;Enfin, dans le petit monde du &lt;acronym&gt;PHP&lt;/acronym&gt; et du webdev en général, il n'est jamais trop tard pour souligner l'existence de protocoles d'authentification centralisée libres comme &lt;a href=&quot;http://openid.net/&quot;&gt;OpenID&lt;/a&gt;, qui de plus à lancé un &lt;em&gt;concours&lt;/em&gt; d'implémentation sous forme de &lt;a href=&quot;http://iwantmyopenid.org/bounty&quot;&gt;bounties&lt;/a&gt; ! On notera également les débuts de &lt;a href=&quot;http://devzone.zend.com/node/view/id/1113&quot;&gt;l'extension d' input filtering pour PHP&lt;/a&gt;, qui promet de simplifier grandement la validation de données externes dans les applis &lt;acronym&gt;PHP&lt;/acronym&gt;. Enfin, &lt;a href=&quot;http://weierophinney.net/matthew/uploads/php_development_best_practices.pdf&quot;&gt;les slides de la conférences PHP Best Practices&lt;/a&gt; qui a eu lieu à la ZendCon, c'est vraiment rempli de bons conseils.&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2006/11/01/Incubated#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2006/11/01/Incubated#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/711</wfw:commentRss>
      </item>
    
  <item>
    <title>Howto: Utiliser Zend_Controller_RewriteRouter avec Zend_Config</title>
    <link>http://mirmodynamics.com/post/2006/10/31/Howto%3A-Utiliser-Zend_Controller_RewriteRouter-avec-Zend_Config</link>
    <guid isPermaLink="false">urn:md5:58ec785aef55507ca8784ce7b8d798b3</guid>
    <pubDate>Tue, 31 Oct 2006 20:26:00 +0100</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Coding</category>
        <category>bootstrap</category><category>configuration</category><category>controlleurs</category><category>doc</category><category>howto</category><category>ini</category><category>MVC</category><category>php</category><category>zend framework</category>    
    <description>&lt;p&gt;Comme je le disais plus bas, le Zend Framework Preview 0.2.0 est dans les bacs ! Cette nouvelle mouture apporte son lot de nouveautés, et nous allons nous pencher sur une des plus interressantes: le &lt;em&gt;RewriteRouter&lt;/em&gt;. Le &lt;em&gt;RewriteRouter&lt;/em&gt; est un routeur pour le composant &lt;acronym&gt;MVC&lt;/acronym&gt; du Zend Framework qui va nous permettre de configurer nos &lt;acronym&gt;URL&lt;/acronym&gt; comme dans Ruby on Rails, c'est à dire (en gros), via un fichier de configuration, et c'est là que &lt;em&gt;Zend_Config&lt;/em&gt; entre en jeu.&lt;/p&gt;    &lt;h3&gt;Mettre en place le routeur&lt;/h3&gt;


&lt;p&gt;C'est bien beau tout ça, mais pour l'utiliser, il faut déjà en informer le controlleur. Pour cela, rien de plus simple, on utilise la méthode &lt;code&gt;addRouter&lt;/code&gt;:&lt;/p&gt;


&lt;pre&gt;$router = new Zend_Controller_RewriteRouter;
$controller = Zend_Controller_Front::getInstance();
$controller-&amp;gt;setRouter($router);&lt;/pre&gt;


&lt;p&gt;Le &lt;em&gt;RewriteRouter&lt;/em&gt; est pré-configuré avec deux routes qui permettent d'assurer la compatibilité descendante avec l'ancien routeur, donc jusque là, tout va bien.&lt;/p&gt;


&lt;h3&gt;Déclarer les routes&lt;/h3&gt;


&lt;p&gt;Nous utiliserons un fichier de configuration dédié aux routes, que nous appellerons sobrement &lt;em&gt;routes.ini&lt;/em&gt;, et que nous placerons dans &lt;code&gt;app/&lt;/code&gt;, à coté de son compagnon &lt;em&gt;config.ini&lt;/em&gt;. Ce fichier de configuration contiendra une unique section &lt;code&gt;[routes]&lt;/code&gt;, qui contiendra à son tour les multiples définitions de routes que nous souhaitons y caser. Une route se compose de 5 éléments principaux:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;L'identifiant de la route. C'est un identifiant interne utilisé par le &lt;code&gt;RewriteRouter&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;l'&lt;acronym&gt;URL&lt;/acronym&gt; de la route, c'est ce qui permet au routeur de reconnaitre la route à utiliser,&lt;/li&gt;
&lt;li&gt;les valeurs par défauts des variables,&lt;/li&gt;
&lt;li&gt;les requirements de la route, qui permettent de déterminer si une route est bien formée ou non.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sans plus attendre, un petit exemple: la route qui &lt;em&gt;pourrait&lt;/em&gt; permettre d'accéder à un billet dans dotclear 2:&lt;/p&gt;


&lt;pre&gt;post.route = post/:year/:month/:day/:title
post.reqs.year = &amp;quot;\d+&amp;quot;
post.reqs.month = &amp;quot;\d+&amp;quot;
post.reqs.day = &amp;quot;\d+&amp;quot;
post.reqs.title = &amp;quot;[a-zA-Z0-9_:-]&amp;quot;+
post.defaults.controller = post
post.defaults.action = view
post.defaults.title =&lt;/pre&gt;


&lt;p&gt;Elle &lt;em&gt;pourrait&lt;/em&gt; seulement, car en fait, la regexp du &lt;code&gt;title&lt;/code&gt; est trop restrictive (une &lt;acronym&gt;URL&lt;/acronym&gt; peut contenir d'autres caractères que ceux là), et de plus, les &lt;acronym&gt;URL&lt;/acronym&gt; stockées par dotclear 2 en base de données comprennent tout ce qui se trouve après &lt;code&gt;post/&lt;/code&gt; (par exemple le champs &lt;code&gt;post_url&lt;/code&gt; de ce billet contient: &lt;code&gt;2006/10/31/Howto:-Utiliser-Zend_Controller_RewriteRouter-avec-Zend_Config&lt;/code&gt;).&lt;/p&gt;


&lt;p&gt;Cela étant dit, la route que nous venons de décrire s'appliquera aux &lt;acronym&gt;URL&lt;/acronym&gt;s suivantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/post/2006/30/10/ZendFramework&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/post/42/2006/56/Foobar&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/post/2006/30/10/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mais pas à:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/post/2006/Foobar&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/post/Foobar/2006/30/01&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On note donc d'ores et déjà:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;que la validation des composants d'une route se fait par expression régulière&lt;/li&gt;
&lt;li&gt;qu'on peut ommettre le dernier composant d'une route si il possède une valeur par défaut (récursivement)&lt;/li&gt;
&lt;li&gt;qu'on ne peut pas modifier l'ordre des composants d'une route&lt;/li&gt;
&lt;li&gt;qu'on doit spécifier manuellement le nom du controlleur et de l'action à utiliser&lt;/li&gt;
&lt;li&gt;et c'est déjà pas mal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Décortiquons maintenant une &lt;acronym&gt;URL&lt;/acronym&gt;: &lt;code&gt;/post/2006/30/10/ZendFramework&lt;/code&gt;. Le routeur va diviser cette &lt;acronym&gt;URL&lt;/acronym&gt; ainsi:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Controller: &lt;code&gt;post&lt;/code&gt; (d'après les &lt;em&gt;defaults&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Action: &lt;code&gt;view&lt;/code&gt; (d'après les &lt;em&gt;defaults&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Paramètres: &lt;code&gt;year&lt;/code&gt;: 2006, &lt;code&gt;month&lt;/code&gt;: 30, &lt;code&gt;day&lt;/code&gt;: 10, &lt;code&gt;title&lt;/code&gt;: ZendFramework (d'après l'&lt;acronym&gt;URL&lt;/acronym&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les paramètres ainsi détectés seront disponibles via la méthode &lt;code&gt;$this-&amp;gt;_getParam($name);&lt;/code&gt; a l'intérieur du controlleur.&lt;/p&gt;


&lt;p&gt;Dernier point de ce chapitre, une déclaration de route peut comporter deux variables spéciales: &lt;code&gt;:controller&lt;/code&gt; et &lt;code&gt;:action&lt;/code&gt;, qui servent respectivement à détecter le controller et l'action à utiliser dans l'url. Par exemple, la route &lt;em&gt;builtin&lt;/em&gt; &lt;code&gt;compat&lt;/code&gt; chargé d'assurer la compatibilité descendante se déclare ainsi:&lt;/p&gt;


&lt;pre&gt;compat.route = :controller/:action
compat.defaults.controller = index
compat.defaults.action = index&lt;/pre&gt;


&lt;h3&gt;Assembler le tout&lt;/h3&gt;


&lt;p&gt;Dernière étape, transférer directement toutes ces déclarations dans le Routeur: n'y allons pas par quatre chemin:&lt;/p&gt;


&lt;pre&gt;$router-&amp;gt;addConfig(new Zend_Config_Ini('/path/to/routes.ini', null), 'routes');&lt;/pre&gt;


&lt;p&gt;C'est aussi simple que ça. Ce qui nous donne, en prenant en compte le morceau de code du début de l'article:&lt;/p&gt;


&lt;pre&gt;$router = new Zend_Controller_RewriteRouter;
$router-&amp;gt;addConfig(new Zend_Config_Ini($routes_path, null), 'routes');
$controller = Zend_Controller_Front::getInstance();
$controller-&amp;gt;setRouter($router);&lt;/pre&gt;


&lt;p&gt;And voilà. Je ne saurais que vous conseiller la lecture du &lt;a href=&quot;http://framework.zend.com/manual/en/zend.controller.rewriterouter.html&quot;&gt;manuel&lt;/a&gt; pour plus d'informations (sachant qu'en fait, &lt;code&gt;addRoute&lt;/code&gt; attend en deuxième argument une instance de &lt;code&gt;Zend_Controller_Router_Route&lt;/code&gt;, mais qui s'instancie avec les paramètres qu'ils passent à &lt;code&gt;addRoute&lt;/code&gt;, petite coquille du manuel :p).&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2006/10/31/Howto%3A-Utiliser-Zend_Controller_RewriteRouter-avec-Zend_Config#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2006/10/31/Howto%3A-Utiliser-Zend_Controller_RewriteRouter-avec-Zend_Config#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/710</wfw:commentRss>
      </item>
    
  <item>
    <title>Relayer un stream audio avec icecast2</title>
    <link>http://mirmodynamics.com/post/2006/10/20/Relayer-un-stream-audio-avec-icecast2</link>
    <guid isPermaLink="false">urn:md5:0df1adaf1cd213b3a277c6eb891f838d</guid>
    <pubDate>Fri, 20 Oct 2006 22:05:00 +0200</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Geekeries</category>
        <category>bidouille</category><category>configuration</category><category>doc</category><category>howto</category><category>optimisation</category><category>rigolo</category><category>ubuntu</category><category>unix</category><category>way of life</category><category>work</category>    
    <description>    &lt;p&gt;Pour économiser la bande passante au boulot, j'ai décidé de relayer le stream &lt;em&gt;Club !&lt;/em&gt; de &lt;a href=&quot;http://1.fm/&quot;&gt;1.fm&lt;/a&gt; sur le &lt;acronym&gt;LAN&lt;/acronym&gt;. Après avoir vainement tenté d'utiliser streamripper (on verra plus tard pourquoi vainement), j'ai sorti l'artillerie lourde: &lt;a href=&quot;http://www.icecast.org/&quot;&gt;icecast2&lt;/a&gt;:&lt;/p&gt;


&lt;pre&gt;sudo apt-get install icecast2&lt;/pre&gt;


&lt;p&gt;Si on sait un peu lire, le script de post-configuration nous incite à aller fourrer notre nez dans &lt;code&gt;/etc/default/icecast2&lt;/code&gt;, où l'on apprend (vers la fin) que icecast est désactivé par défaut à cause de la directive &lt;code&gt;ENABLED=false&lt;/code&gt;. C'est en fait une feinte pour nous pousser à configurer le bousin (de toute façon si on le configure pas, il marchera pas). Direction &lt;code&gt;/etc/icecast2/icecast.xml&lt;/code&gt; donc, pour un brin de configuration (les explications qui suivent se basent sur le fichier par défaut d'une installation sur une ubuntu).&lt;/p&gt;


&lt;p&gt;La première partie qui nous interresse s'intitule &lt;code&gt;authentication&lt;/code&gt; (vers la ligne 23). Elle contient les informations d'authentification pour les clients qui se connectent en tant que source (&lt;code&gt;source-password&lt;/code&gt;), les serveurs qui se connectent en tant que slave (&lt;code&gt;relay-password&lt;/code&gt;, en fait je ne suis pas sur à 100%, c'est une déduction) et pour l'interface d'administration (&lt;code&gt;admin-user&lt;/code&gt; et &lt;code&gt;admin-password&lt;/code&gt;). Une fois ces informations modifiées, direction la directive &lt;code&gt;hostname&lt;/code&gt;, qu'on remplira avec au choix, le nom de la machine, son ip, etc. J'ai personellement mis l'ip privée de ma machine (&lt;code&gt;172.16.x.y&lt;/code&gt;), pour que ça correspondent à la prochaine directive qui nous interresse: &lt;code&gt;listen-socket&lt;/code&gt;. Ici on définit le port et l'ip sur laquelle icecast va écouter. En gros, si vous spécifier &lt;code&gt;127.0.0.1&lt;/code&gt;, votre serveur de streaming ne sera accessible qu'en local. On y met donc en général la même chose que dans &lt;code&gt;hostname&lt;/code&gt; (&lt;code&gt;172.16.x.y&lt;/code&gt; par exemple), avec un port qui va bien, libre de préférence (&lt;code&gt;8000&lt;/code&gt; par défaut).&lt;/p&gt;


&lt;p&gt;Maintenant on passe a la partie qui nous interresse vraiment, la section &lt;code&gt;relay&lt;/code&gt;. Rien de bien compliqué ici. Le stream que je souhaite relayer se trouve là: http://64.62.253.223:8060/, or icecast nous demande un &lt;code&gt;server&lt;/code&gt;, un &lt;code&gt;port&lt;/code&gt;, un &lt;em&gt;point de montage&lt;/em&gt; (&lt;code&gt;mount&lt;/code&gt;) et un &lt;em&gt;point de montage local&lt;/em&gt; (&lt;code&gt;local-mount&lt;/code&gt;). Vous avez déjà compris qu'on arrive a cette configuration:&lt;/p&gt;


&lt;pre&gt;   &amp;lt;relay&amp;gt;
       &amp;lt;server&amp;gt;64.62.253.223&amp;lt;/server&amp;gt;
       &amp;lt;port&amp;gt;8060&amp;lt;/port&amp;gt;
       &amp;lt;mount&amp;gt;/&amp;lt;/mount&amp;gt;
       &amp;lt;local-mount&amp;gt;/1.fm&amp;lt;/local-mount&amp;gt;
       &amp;lt;on-demand&amp;gt;0&amp;lt;/on-demand&amp;gt;
       &amp;lt;relay-shoutcast-metadata&amp;gt;1&amp;lt;/relay-shoutcast-metadata&amp;gt;
   &amp;lt;/relay&amp;gt;&lt;/pre&gt;


&lt;p&gt;Ainsi parés, il ne nous reste plus qu'a lancer modifier la directive &lt;code&gt;ENABLED=false&lt;/code&gt; en &lt;code&gt;ENABLED=true&lt;/code&gt; dans &lt;code&gt;/etc/default/icecast2&lt;/code&gt; et à lancer icecast:&lt;/p&gt;


&lt;pre&gt;sudo /etc/init.d/icecast2 start&lt;/pre&gt;


&lt;p&gt;Si vous avez bien tout fait, vous devriez pouvoir streamer depuis &lt;code&gt;http://172.16.x.y:8000/1.fm&lt;/code&gt;, et vos collègues également ! Vous pouvez avoir une vue d'ensemble du serveur ainsi que quelques options d'administration en vous rendant sur l'interface d'admin: http://172.16.x.y:8000/ et en utilisant &lt;code&gt;admin-user&lt;/code&gt; et &lt;code&gt;admin-password&lt;/code&gt; pour vous authentifier.&lt;/p&gt;


&lt;p&gt;A cela on peut ajouter un petit &lt;code&gt;streamripper&lt;/code&gt;:&lt;/p&gt;


&lt;pre&gt;streamripper http://172.16.x.y:8000/1.fm -d ~/streamripped&lt;/pre&gt;


&lt;p&gt;Pour enregistrer. En parlant de streamripper, j'avais tenté au début de relayer avec &lt;code&gt;streamripper -r&lt;/code&gt;, mais malgrès les apparences du &lt;code&gt;netstat -pl&lt;/code&gt; (&lt;code&gt;*:8000 LISTEN&lt;/code&gt;), il ne bind qu'en local, donc impossible d'en faire profiter les collègues :-)&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2006/10/20/Relayer-un-stream-audio-avec-icecast2#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2006/10/20/Relayer-un-stream-audio-avec-icecast2#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/692</wfw:commentRss>
      </item>
    
  <item>
    <title>Écrire de la doc...</title>
    <link>http://mirmodynamics.com/post/2006/10/16/Ecrire-de-la-doc</link>
    <guid isPermaLink="false">urn:md5:15834c4bb500a04cde002333967a8eab</guid>
    <pubDate>Mon, 16 Oct 2006 11:46:00 +0200</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Geekeries</category>
        <category>doc</category><category>php</category><category>phpdoc</category>    
    <description>    &lt;p&gt;... c'est chiant. Surtout pendant cinq longues heures. Mais le résultat est appréciable, merci &lt;a href=&quot;http://www.phpdoc.org/&quot; hreflang=&quot;en&quot;&gt;phpdoc&lt;/a&gt; :-)&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2006/10/16/Ecrire-de-la-doc#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2006/10/16/Ecrire-de-la-doc#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/668</wfw:commentRss>
      </item>
    
</channel>
</rss>