<?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 - bootstrap</title>
  <link>http://mirmodynamics.com/</link>
  <atom:link href="http://mirmodynamics.com/feed/tag/bootstrap/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>Zend Framework: Un plugin simple pour le Front Controller</title>
    <link>http://mirmodynamics.com/post/2006/11/19/Zend-Framework%3A-Un-plugin-simple-pour-le-Front-Controller</link>
    <guid isPermaLink="false">urn:md5:6c829cc8dbd18739b84ef7758d852a70</guid>
    <pubDate>Sun, 19 Nov 2006 21:30:00 +0100</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Coding</category>
        <category>bootstrap</category><category>howto</category><category>MVC</category><category>organisation</category><category>php</category><category>plugin</category><category>vues</category><category>zend framework</category>    
    <description>&lt;p&gt;L'implémentation du &lt;code&gt;Front Controller&lt;/code&gt; du &lt;a href=&quot;http://framework.zend.com/&quot;&gt;Zend Framework&lt;/a&gt; inclue un système bien pratique de plugins, qui va nous permettre de réaliser plus simplement et proprement &lt;a href=&quot;http://fashion.hosmoz.net/blog/post/2006/08/30/Automatisation-des-vues&quot;&gt;l'automatisation des vues&lt;/a&gt;, initialement embarquée dans une extension de &lt;code&gt;Zend_Controller_Action&lt;/code&gt; (ce qui pose quelques problèmes, nottament au lors de l'utilisation de &lt;code&gt;__forward()&lt;/code&gt; et &lt;code&gt;_redirect()&lt;/code&gt;).&lt;/p&gt;    &lt;p&gt;Techniquement, un plugin est une classe qui implémente l'interface des plugins (&lt;code&gt;Zend_Controller_Plugin_Interface&lt;/code&gt;). Dans la pratique, une classe abstraite est fournie pour simplifier la tache (&lt;code&gt;Zend_Controller_Plugin_Abstract&lt;/code&gt;). Notre premier plugin s'appellera &lt;code&gt;AutoView&lt;/code&gt; (&lt;code&gt;My_Controller_Plugin_AutoView&lt;/code&gt;, stocké dans &lt;code&gt;My/Controller/Plugin/AutoView.php&lt;/code&gt;).&lt;/p&gt;


&lt;p&gt;Un plugin est donc une classe dont les méthodes seront appelées a différents moments de la &lt;em&gt;dispatch loop&lt;/em&gt; du controlleur frontal, comme on peut le voir dans &lt;code&gt;Zend_Controller_Front::dispatch()&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;routeStartup()&lt;/code&gt;, à la mise en route du routeur&lt;/li&gt;
&lt;li&gt;&lt;code&gt;routeShutdown($action)&lt;/code&gt;, à l'arrêt du routeur&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dispatchLoopStartup($action)&lt;/code&gt;, avant la &lt;em&gt;dispatch loop&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;preDispatch($action)&lt;/code&gt;, avant d'executer une action&lt;/li&gt;
&lt;li&gt;&lt;code&gt;postDispatch($action)&lt;/code&gt;, après avoir executé une action&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dispatchLoopShutdown()&lt;/code&gt;, pour finir.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A chaud, on pourrait se dire que &lt;code&gt;postDispatch&lt;/code&gt; est exactement ce dont on n'a besoin, et on se tromperait. Ce qu'il faut savoir, c'est que l'argument &lt;code&gt;$action&lt;/code&gt; passé à &lt;code&gt;postDispatch&lt;/code&gt; contient l'action qui suit celle qui vient d'être executé. Dans la majorité des cas, n'ayant qu'une seule action à executer, &lt;code&gt;$action&lt;/code&gt; sera vide, et on se retrouve l'air un peu con.&lt;/p&gt;


&lt;p&gt;Bon donc, on va user d'un stratagème: notre plugin va stocker les actions qui passent dans &lt;code&gt;preDispatch&lt;/code&gt;, pour s'occuper de la dernière à être passée dans &lt;code&gt;dispatchLoopShutdown&lt;/code&gt;. Dernier détail, notre plugin s'occupera lui même de gérer son instance de &lt;code&gt;Zend_View&lt;/code&gt;. Et sans plus attendre, le code, qui n'a finalement rien de compliqué:&lt;/p&gt;

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

require_once 'Zend/Controller/Plugin/Abstract.php';

class My_Controller_Plugin_AutoView extends Zend_Controller_Plugin_Abstract {

	private $_lastAction;

	public function __construct() {
		$view = new Zend_View;
		$view-&amp;gt;setScriptPath(APP_ROOT.'/views/');
		Zend::register('view', $view);
	}

	public function preDispatch($action) {
		$this-&amp;gt;_lastAction = clone($action);
		return $action;
	}

	public function dispatchLoopShutdown() {
		if (!is_null($this-&amp;gt;_lastAction)) {
			$viewPath = sprintf('%s/%s.php', $this-&amp;gt;_lastAction-&amp;gt;getControllerName(), $this-&amp;gt;_lastAction-&amp;gt;getActionName());
			echo Zend::registry('view')-&amp;gt;render($viewPath);
		}
	}
}

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


&lt;p&gt;Bien, notre plugin vaillament codé, il nous faut désormais expliquer au controlleur frontal qu'on aimerai bien qu'il en tienne compte. Cela se passe fort logiquement dans le &lt;em&gt;bootstrap&lt;/em&gt;, via la méthode &lt;code&gt;registerPlugin&lt;/code&gt; du sus-cité controlleur frontal, qui prend en argument une instance d'un objet implémentant &lt;code&gt;Zend_Controller_Plugin_Interface&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
$controller = Zend_Controller_Front::getInstance();
$controller-&amp;gt;registerPlugin(new My_Controller_Plugin_AutoView);
&lt;/pre&gt;


&lt;p&gt;And viola !&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2006/11/19/Zend-Framework%3A-Un-plugin-simple-pour-le-Front-Controller#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2006/11/19/Zend-Framework%3A-Un-plugin-simple-pour-le-Front-Controller#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/720</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>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>L'environnement d'execution</title>
    <link>http://mirmodynamics.com/post/2006/09/28/Lenvironnement-dexecution</link>
    <guid isPermaLink="false">urn:md5:e76eb4e24c2dc5797a4c4b451158f001</guid>
    <pubDate>Thu, 12 Oct 2006 21:51:00 +0200</pubDate>
    <dc:creator>Geoffrey</dc:creator>
        <category>Coding</category>
        <category>bootstrap</category><category>environnement</category><category>howto</category><category>organisation</category><category>zend framework</category>    
    <description>&lt;p&gt;Voilà un article que j'avais déjà proposé sur un site a caractère privé, un peu remis au gout du jour et étoffé de quelques informations et ressources non négligeables. Nous verrons ici comment mettre en place un environement d'execution standard du Zend Framework, également appelé &lt;em&gt;bootstrap&lt;/em&gt; de l'autre coté de l'atlantique.&lt;/p&gt;    &lt;p&gt;Un petit dessin valant mieux qu'un long discours, entrons dans le vif du sujet. On assume ici un environnement préinstallé: Apache / PHP5 / MySQL, avec une copie du Zend Framework dans &lt;code&gt;/usr/share/zend/&lt;/code&gt;, ainsi que le &lt;code&gt;.htaccess&lt;/code&gt; suivant à la racine de votre site (il semblerait que cette dépendance à &lt;code&gt;mod_rewrite&lt;/code&gt; soit sur la liste des choses à éliminer avant la release):&lt;/p&gt;


&lt;pre&gt;RewriteEnfine On
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php&lt;/pre&gt;


&lt;p&gt;On peut également utiliser les règles suivantes, qui comportent l'avantage d'une plus grande simplicité pour intégrer des éléments d'application externe:&lt;/p&gt;


&lt;pre&gt;RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php&lt;/pre&gt;


&lt;h2&gt;L'environnement&lt;/h2&gt;


&lt;p&gt;Les plus perspicaces d'entre vous l'auront surement déjà deviné, le fichier &lt;code&gt;www/index.php&lt;/code&gt; servira de &lt;em&gt;bootstrap&lt;/em&gt;, c'est à dire de point d'entrée unique pour toute l'application. Le Zend Framework se chargera lui même de décortiquer l'&lt;acronym&gt;URL&lt;/acronym&gt; pour tenter de deviner ce à quoi l'utilisateur pouvait bien penser quand il a cliqué !&lt;/p&gt;


&lt;p&gt;Pour ce qui est de l'arborescence de fichiers conseillée, &lt;a href=&quot;http://fashion.hosmoz.net/blog/post/2006/09/16/Debuter-un-projet%3A-un-brin-dorganisation&quot;&gt;un peu d'organisation est recommandée&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;Pour utiliser le Zend Framework en toute quiétude, il nous faut nous assurer qu'il pourra accéder à ses propres composants. La première chose à faire est donc de modifier l'&lt;code&gt;include_path&lt;/code&gt;:&lt;/p&gt;


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


&lt;p&gt;Il n'est pas inutile également de prendre quelques précautions d'usage:&lt;/p&gt;


&lt;pre&gt;ini_set('error_reporting', E_ALL); # | E_STRICT);

if (get_magic_quotes_gpc()) {
	die('&amp;lt;strong&amp;gt;E_NOOB_ERROR&amp;lt;/strong&amp;gt;: magic_quotes_gpc must be turned off.');
}

set_magic_quotes_runtime(false);&lt;/pre&gt;


&lt;p&gt;&lt;em&gt;Last but not least&lt;/em&gt;, on charge la librairie &lt;code&gt;Zend&lt;/code&gt;:&lt;/p&gt;


&lt;pre&gt;require_once 'Zend.php';&lt;/pre&gt;


&lt;p&gt;Ainsi préparés, nous pouvons nous plonger en toute quiétude dans la mise en place de quelques objets qui nous serons bien utiles tout au long du développement de notre application.&lt;/p&gt;


&lt;h2&gt;Les objets&lt;/h2&gt;


&lt;p&gt;La mise en place des objets est on ne peut plus claire. On configure le front controller (&lt;code&gt;Zend_Controller_Front&lt;/code&gt;) pour lui dire où trouver les &lt;em&gt;controllers&lt;/em&gt;, puis on configure les vues (&lt;code&gt;Zend_View&lt;/code&gt;) pour leur dire où trouver... les vues :-) On enregistre ensuite l'objet &lt;code&gt;$view&lt;/code&gt; dans le registre, qui n'est rien de plus qu'un endroit pratique où stocker des objets/données pour y avoir accès plus tard (&lt;code&gt;Zend::register($name, $value)&lt;/code&gt; et &lt;code&gt;$var = Zend::registry($name);&lt;/code&gt;).&lt;/p&gt;


&lt;p&gt;Une petite liste (non exhaustive) d'objets interressants à stocker dans le registre:&lt;/p&gt;


&lt;h3&gt;Zend_Db&lt;/h3&gt;


&lt;pre&gt;Zend::loadClass('Zend_Db');
Zend::loadClass('Zend_Db_Table');

$params = array(
	'host' =&amp;gt; 'localhost',
	'username' =&amp;gt; 'someobscureusername',
	'password' =&amp;gt; 'someobscurepassword',
	'dbname' =&amp;gt; 'yourdbname'
);

$db = Zend_Db::factory('PDO_MYSQL',$params);
Zend_Db_Table::setDefaultAdapter($db);

Zend::register('db', $db);&lt;/pre&gt;


&lt;h3&gt;Zend_Config&lt;/h3&gt;


&lt;p&gt;Je vous renvois à mon article sur la &lt;a href=&quot;http://fashion.hosmoz.net/blog/post/2006/09/04/Gestion-de-la-configuration&quot;&gt;gestion de la configuration&lt;/a&gt; :-)&lt;/p&gt;


&lt;h3&gt;Zend_View&lt;/h3&gt;


&lt;pre&gt;Zend::loadClass('Zend_View');

$view = new Zend_View;
$view-&amp;gt;setScriptPath(realpath(dirname(__FILE__).'/../app/views/'));

Zend::register('view', $view);&lt;/pre&gt;


&lt;h2&gt;Le Dispatch&lt;/h2&gt;


&lt;p&gt;Dernière étape, le dispatch, qui utilise les objets &lt;code&gt;Zend_Controller_Router&lt;/code&gt; et &lt;code&gt;Zend_Controller_Dispatcher&lt;/code&gt;. Ces deux objets sont au coeur du processus de sélection du controller à executer. Le Router va déterminer, à partir de l'environnement (en général l'URL, via $_SERVER['REQUEST_URI'] par exemple) quelle action executer et dans quel controller, tandis que le Dispatcher va s'occuper lui de les trouver (par exemple dire FooController::bar(), dans controllers/FooController.php).&lt;/p&gt;


&lt;p&gt;Le Zend Framework gère en natif les friendly urls, et ça c'est chouette. Par exemple: les urls suivantes:&lt;/p&gt;

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

&lt;p&gt;Seront analysées comme suit par le Routeur par défaut:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;controller: foo, action: bar&lt;/li&gt;
&lt;li&gt;controller: foo, action: index&lt;/li&gt;
&lt;li&gt;controller: index, action: index&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dernières choses à savoir sur la théorie:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;quand le controlleur est défini par l'url mais non trouvé par le &lt;code&gt;Dispatcher&lt;/code&gt;, celui ci execute &lt;code&gt;index/noRoute&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;les controllers sont des classes qui étendent &lt;code&gt;Zend_Controller_Action&lt;/code&gt; (ou une classe qui elle même l'étend)&lt;/li&gt;
&lt;li&gt;le Dispatcher par défaut va executer(en supposant une url type &lt;code&gt;http://example.org/foo/bar&lt;/code&gt;) &lt;code&gt;FooController::barAction&lt;/code&gt; dans &lt;code&gt;FooController.php&lt;/code&gt; (modulo le path déterminé avec &lt;code&gt;Zend_Controller_Front::setControllerPath&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Les vues&lt;/h2&gt;


&lt;p&gt;Dernier point de cette brève excursion dans le Zend Framework, les vues. Pas grand chose à en dire pour le moment, si ce n'est que par défaut l'objet Zend_View se contente d'include() les fichiers templates. Il parait que l'intégration avec des moteurs de template (Smarty par exemple) est très aisée, mais comme je ne suis pas fan de ce genre de choses, ce ne sera pas couvert ici :-)&lt;/p&gt;</description>
    
    
    
          <comments>http://mirmodynamics.com/post/2006/09/28/Lenvironnement-dexecution#comment-form</comments>
      <wfw:comment>http://mirmodynamics.com/post/2006/09/28/Lenvironnement-dexecution#comment-form</wfw:comment>
      <wfw:commentRss>http://mirmodynamics.com/feed/atom/comments/626</wfw:commentRss>
      </item>
    
</channel>
</rss>