<?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 - arborescence</title>
  <link>http://mirmodynamics.com/</link>
  <atom:link href="http://mirmodynamics.com/feed/tag/arborescence/rss2" rel="self" type="application/rss+xml"/>
  <description>Rien de grand ne se fit jamais sans enthousiasme.</description>
  <language>en</language>
  <pubDate>Wed, 03 Dec 2008 17:01:33 +0100</pubDate>
  <copyright>2003-2008 &amp;copy; Geoffrey Bachelet</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Bootstrap CLI</title>
    <link>http://mirmodynamics.com/post/2006/10/13/Bootstrap-CLI</link>
    <guid isPermaLink="false">urn:md5:1e9ff0bf3342af30f0bcc1b219d7f60a</guid>
    <pubDate>Fri, 13 Oct 2006 18:31:00 +0200</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Coding</category>
        <category>arborescence</category><category>bootstrap</category><category>CLI</category><category>howto</category><category>librairie</category><category>organisation</category><category>surclassage</category><category>zend framework</category>    
    <description>&lt;p&gt;Nous avons parcouru dernièrement la création du bootstrap &lt;acronym&gt;HTTP&lt;/acronym&gt; qui sert de socle à une application utilisant le Zend Framework. Le même principe peut s'appliquer aux scripts &lt;acronym&gt;CLI&lt;/acronym&gt;, mais comme les besoins sont fondamentalements différents, l'implémentation sera elle aussi complètement différente. Nous viserons les objectifs suivants:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ne pas être obligé d'executer le bootstrap en ligne de commande&lt;/li&gt;
&lt;li&gt;Simplifier au maximum l'écriture ultérieure des scripts &lt;acronym&gt;CLI&lt;/acronym&gt;&lt;/li&gt;
&lt;li&gt;Définir un jeu d'options de ligne de commande obligatoire&lt;/li&gt;
&lt;li&gt;Mettre en place un environnement d'execution&lt;/li&gt;
&lt;/ol&gt;    &lt;p&gt;La tentation serait de créer un système qui obligerait ce genre de commandes:&lt;/p&gt;


&lt;pre&gt;$ php batch/bootstrap.php monscript&lt;/pre&gt;


&lt;p&gt;Pour executer, par exemple, le script &lt;code&gt;batch/monscript.php&lt;/code&gt;. Cela simplifierait grandement les choses, mais c'est moche, et puis on peut faire autrement, donc on ne va pas se priver ! Nous utiliserons a cette fin la fonction magique &lt;code&gt;register_shutdown_function&lt;/code&gt;, qui s'occupera d'appeler une fonction qui executera les scripts &lt;em&gt;ad hoc&lt;/em&gt;.&lt;/p&gt;


&lt;p&gt;Avant d'aller plus loin, l'arborescence de fichiers que nous allons utiliser:&lt;/p&gt;


&lt;pre&gt;batch/
	monscript.php
	runtime.php
library/
	Zend.php
	My/
		Batch.php&lt;/pre&gt;


&lt;p&gt;&lt;code&gt;runtime.php&lt;/code&gt; sera le fichier à inclure dans chaque script, tandis que &lt;code&gt;My/Batch.php&lt;/code&gt; contiendra la classe d'abstraction &lt;code&gt;My_Batch&lt;/code&gt;, qui définira les comportements par défaut de nos scripts.&lt;/p&gt;


&lt;p&gt;Voici donc la première partie de notre bootstrap, &lt;code&gt;batch/runtime.php&lt;/code&gt;:&lt;/p&gt;


&lt;pre&gt;ini_set('include_path', get_include_path().PATH_SEPARATOR.realpath(dirname(__FILE__).'/../library/'));

require_once 'Zend.php';
require_once 'My/Batch.php';

register_shutdown_function(array('My_Batch', 'runAll'));&lt;/pre&gt;


&lt;p&gt;Bien sur, cette méthode nous oblige à définir un format à respecter pour les fonctions à executer par la suite, nous partirons donc sur les bases suivantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chaque batch doit être constitué d'une classe dont le nom commence par &lt;code&gt;My_Batch_&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Chaque batch doit posséder une méthode executable &lt;code&gt;run&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ce qui nous donne donc:&lt;/p&gt;


&lt;pre&gt;abstract class My_Batch {
	static public function runAll() {
		$classes = get_declared_classes();
		foreach($classes as $className) {
			if (preg_match('/^My_Batch_(.+)$/', $className, $matches) &amp;amp;&amp;amp; method_exists($className, 'run')) {
				try {
					$batch = new $className;
					$batch-&amp;gt;run();
				} catch (Exception $e) {
					die(sprintf(&amp;quot;%s: %s\n&amp;quot;, $matches[1], $e-&amp;gt;getMessage()));
				}
			}
		}
	}
	
	abstract public function run();
}&lt;/pre&gt;


&lt;p&gt;On en profite pour catcher toute Exception indésirable pour la transformer en un &lt;code&gt;die&lt;/code&gt;, bien plus lisible dans un terminal qu'une backtrace :-)&lt;/p&gt;


&lt;p&gt;Maintenant que nous avons résolu les points 1 et 2, attaquons nous à la suite. Le problème principal que j'ai rencontré lors de l'établissement d'un environnement d'execution, c'est que la gestion de la configuration repose en grande partie sur la valeur de &lt;code&gt;$_SERVER['HTTP_HOST']&lt;/code&gt;, qui n'est bien évidemment pas disponible en &lt;acronym&gt;CLI&lt;/acronym&gt; :-) Il me faut donc forcer le passage en argument du nom de la configuration à utiliser. C'est très simple à faire, grace a la méthode que nous avons employé: il suffit de vérifier la présence de cet argument dans le constructeur de &lt;code&gt;My_Batch&lt;/code&gt; :-)&lt;/p&gt;


&lt;pre&gt;public function __construct() {
	foreach($GLOBALS['argv'] as $i =&amp;gt; $arg) {
		switch ($arg) {
			case '--configname':
			case '-c':
				$this-&amp;gt;_args['configname'] = $GLOBALS['argv'][$i+1];
			break;
		}
	}
	if (!isset($this-&amp;gt;_args['configname'])) {
		throw new Exception('-c or --configname is mandatory');
	}
}&lt;/pre&gt;


&lt;p&gt;Voilà, le gros du travail est fait. Pour le reste, c'est la routine, mise en place d'un environnement avec &lt;code&gt;Zend_Config&lt;/code&gt; et &lt;code&gt;Zend_Db&lt;/code&gt;, a la suite dans le constructeur:&lt;/p&gt;


&lt;pre&gt;	$this-&amp;gt;_config = new Zend_Config(
		Zend_Config_Ini::load(
			dirname(__FILE__).'/../../app/config.ini',
			$this-&amp;gt;_args['configname']
		)
	);
	
	$this-&amp;gt;_db = Zend_Db::factory(
		$this-&amp;gt;_config-&amp;gt;db-&amp;gt;adapter,
		$this-&amp;gt;_config-&amp;gt;db-&amp;gt;config-&amp;gt;asArray()
	);
	
	Zend_Db_Table::setDefaultAdapter($this-&amp;gt;_db);&lt;/pre&gt;


&lt;p&gt;Enfin, voila un exemple de script utilisant ce bootstrap:&lt;/p&gt;


&lt;pre&gt;require_once 'path/to/runtime.php';

class My_Batch_MonScript extends My_Batch {
	public function run() {
		// le code ici
	}
}&lt;/pre&gt;


&lt;p&gt;And voila !&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2006/10/13/Bootstrap-CLI#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2006/10/13/Bootstrap-CLI#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/666</wfw:commentRss>
      </item>
    
  <item>
    <title>Débuter un projet: un brin d'organisation</title>
    <link>http://mirmodynamics.com/post/2006/09/16/Debuter-un-projet%3A-un-brin-dorganisation</link>
    <guid isPermaLink="false">urn:md5:4c703a9b711a28437b1023825ce09008</guid>
    <pubDate>Sat, 16 Sep 2006 13:05:00 +0200</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Coding</category>
        <category>arborescence</category><category>controlleurs</category><category>organisation</category><category>vues</category><category>zend framework</category>    
    <description>    &lt;h2&gt;Architecture des dossiers&lt;/h2&gt;


&lt;p&gt;Commençons par le commencement: le stockage des fichiers. Pour ne pas trébucher sur la longue route que représente l'accomplissement d'un projet, il convient de bien s'organiser dès le début, et savoir précisément où stocker et trouver les choses est une bonne chose. Nous allons donc nous baser sur les recommandations de Zend à ce sujet:&lt;/p&gt;


&lt;pre&gt;monprojet/
     app/
          controllers/
          models/
          views/
     library/
     www/&lt;/pre&gt;


&lt;p&gt;A partir de là, on peut faire évoluer un peu. J'ai personellement rajouté un répertoire &lt;code&gt;dist/&lt;/code&gt;, qui contient les scripts nécessaire à la distribution de mon application (dump des bases &lt;acronym&gt;SQL&lt;/acronym&gt; par exemple), et &lt;a href=&quot;http://www.akrabat.com/2006/09/15/directory-structures-again/&quot;&gt;cet article de Rob&lt;/a&gt; parle de répertoires comme &lt;code&gt;scripts/&lt;/code&gt; (pour contenir les scripts cron par exemple) et &lt;code&gt;tmp/&lt;/code&gt; (à toutes fins utiles).&lt;/p&gt;


&lt;p&gt;Enfin, notons l'utilité d'un répertoire &lt;code&gt;library/ext/&lt;/code&gt; ou assimilé, &lt;a href=&quot;http://fashion.hosmoz.net/blog/post/2006/09/06/Integrer-une-librairie-tierce&quot;&gt;comme  expliqué ici&lt;/a&gt;.&lt;/p&gt;


&lt;h2&gt;Définir ses controlleurs et ses vues&lt;/h2&gt;


&lt;p&gt;Première question a se poser: qu'est-ce qu'un controlleur ? Un controlleur, c'est tout simplement une entité qui va s'occuper de traiter une requête que reçoit l'application. Dans le Zend Framework, les controlleurs possèdent des Actions (sous formes de méthodes), qui permettent d'avoir des &lt;acronym&gt;URL&lt;/acronym&gt; telles que:&lt;/p&gt;


&lt;pre&gt;http://example.com/foo/bar/&lt;/pre&gt;


&lt;p&gt;Dans un tel cas de figure, Zend Framework ira chercher la méthode &lt;code&gt;barAction&lt;/code&gt; du controlleur &lt;code&gt;fooController&lt;/code&gt;. On voit dès l'ors l'interet de bien définir nos besoins en termes de controlleurs dès maintenant, puisque c'est cela qui définira toute l'architecture de l'application. La marche à suivre est la suivante:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lister toutes les fonctionnalitées de l'application&lt;/li&gt;
&lt;li&gt;Les regrouper logiquement&lt;/li&gt;
&lt;li&gt;Traduire tout ça en termes de controlleurs et d'action&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Prenons l'exemple typique d'un portail d'actualité. Voici quelques unes des actions que nous serons susceptibles de proposer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ajouter une news&lt;/li&gt;
&lt;li&gt;Lister des news (action par défaut)&lt;/li&gt;
&lt;li&gt;Voir les détails d'une news&lt;/li&gt;
&lt;li&gt;Ajouter un commentaire&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ce qui se traduit par:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;controlleur News
&lt;ul&gt;
&lt;li&gt;action Ajouter (url: &lt;code&gt;news/ajouter/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;action Lister (url: &lt;code&gt;news/lister/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;action Voir (url: &lt;code&gt;news/voir/id/$id&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;controlleur Commentaires
&lt;ul&gt;
&lt;li&gt;action Ajouter (url: &lt;code&gt;commentaires/ajouter/news/$id&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cela nous permet donc de prévoir l'arborescence suivante:&lt;/p&gt;


&lt;pre&gt;app/
        controllers/
                CommentairesController.php
                IndexController.php
                NewsController.php
        views/
                Commentaires/
                        ajouter.php
                Index/
                        index.php
                News/
                        ajouter.php
                        lister.php
                        voir.php&lt;/pre&gt;



&lt;p&gt;Voilà pour la théorie, pour la pratique, il faut mettre en place un environnement d'execution dans lequel on pourra déployer toutes la puissance du Zend Framework, c'est ce que nous verrons la prochaine fois :-)&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2006/09/16/Debuter-un-projet%3A-un-brin-dorganisation#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2006/09/16/Debuter-un-projet%3A-un-brin-dorganisation#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/598</wfw:commentRss>
      </item>
    
</channel>
</rss>