<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Hooba Studios</title>
	
	<link>http://www.hooba.ca/blog</link>
	<description />
	<lastBuildDate>Wed, 18 Nov 2009 02:53:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/hoobastudios" /><feedburner:info uri="hoobastudios" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:browserFriendly></feedburner:browserFriendly><item>
		<title>Hooba fait dans les bonnes oeuvres</title>
		<link>http://www.hooba.ca/blog/2009/hooba-fait-dans-les-bonnes-oeuvres/</link>
		<comments>http://www.hooba.ca/blog/2009/hooba-fait-dans-les-bonnes-oeuvres/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 02:53:41 +0000</pubDate>
		<dc:creator>Antoine Leclair</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Théorie]]></category>
		<category><![CDATA[Tranche de vie]]></category>

		<guid isPermaLink="false">http://www.hooba.ca/blog/?p=440</guid>
		<description><![CDATA[Je me suis fait demander récemment de commanditer un concours de vidéo qui est organisé par les bibliothèques de Lévis. Comme la demande venait d&#8217;une personne proche et qu&#8217;ils avaient besoin d&#8217;un site web, j&#8217;ai donc mis la main à la pâte.
Le concours s&#8217;appelle À l&#8217;affiche dans une bibliothèque près de chez vous. Les jeunes [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.dansunebibliothequepresdechezvous.ca/"><img class="size-full wp-image-450 alignleft" title="Concours À l'affiche dans une bibliothèque près de chez vous" src="http://www.hooba.ca/blog/wp-content/uploads/2009/11/dans-une-bibliotheque-pres-de-chez-vous.png" alt="Concours À l'affiche dans une bibliothèque près de chez vous" width="210" height="149" /></a>Je me suis fait demander récemment de commanditer un concours de vidéo qui est organisé par les bibliothèques de Lévis. Comme la demande venait d&#8217;une personne proche et qu&#8217;ils avaient besoin d&#8217;un site web, j&#8217;ai donc mis la main à la pâte.</p>
<p>Le concours s&#8217;appelle <a href="http://www.dansunebibliothequepresdechezvous.ca/">À l&#8217;affiche dans une bibliothèque près de chez vous</a>. Les jeunes doivent faire un vidéo &laquo;&nbsp;bande-annonce&nbsp;&raquo; d&#8217;un livre parmi les livres sélectionnés.</p>
<p>Comme c&#8217;était du bénévolat et que les visiteurs allaient être des jeunes (donc plus enclins à utiliser un navigateur récent), je me suis permis d&#8217;expérimenter un peu avec le CSS3.</p>
<p><span id="more-440"></span></p>
<h3>Box Shadow</h3>
<p><a href="http://www.dansunebibliothequepresdechezvous.ca/"><img class="alignnone size-full wp-image-447 shadow" title="Box Shadow CSS3" src="http://www.hooba.ca/blog/wp-content/uploads/2009/11/bibliotheque-pres-de-chez-vous-box-shadow.jpg" alt="Box Shadow CSS3" width="580" height="254" /></a></p>
<p>Si vous avez un navigateur récent qui n&#8217;est pas Internet Explorer, vous pouvez voir qu&#8217;il y a un une ombre autour du contenu principal. Il s&#8217;agit de la propriété CSS <code>box-shadow</code>. Elle n&#8217;est actuellement implémenté que dans Webkit (Safara, Chrome) et Firefox 3.5+. Comme le CSS3 n&#8217;est pas encore ratifié, il faut ajouter l&#8217;extension des navigateurs à l&#8217;avant de la règle. C&#8217;est à dire <code>-moz</code> pour Firefox et <code>-webkit</code> pour Webkit. Par exemple, sur le site du concours, voici la règle que j&#8217;ai utilisée:</p>
<pre><code>-moz-box-shadow:0 0 20px 3px black;
-webkit-box-shadow:0 0 20px 2px black;
box-shadow:0 0 20px 2px black;</code></pre>
<p>La version sans préfixe sert pour le jour où cette règle CSS deviendra standard. En gros, j&#8217;ai utilisé cinq paramètres:</p>
<ol>
<li><em>Offset</em> horizontal, au cas où on voudrait décaller.</li>
<li><em>Offset</em> vertical, même chose.</li>
<li>Flou (<em>blur</em>), détermine l&#8217;intensité du flou, un peu comme dans Photoshop.</li>
<li>Étendue (<em>spread</em>), sans avoir trop expérimenté, ça ressemble un peu à <code>padding</code>, mais appliqué à l&#8217;ombre. Peut être négatif si on veut la rapetisser.</li>
<li>Couleur. Je crois que la spécification permettra aussi d&#8217;utiliser <code>rgba</code> (avec de la transparence).</li>
</ol>
<h3>IE6 n&#8217;est pas mort</h3>
<p>Après avoir fait le site web, comme tout bon intégrateur, j&#8217;ai fait le tour dans tous les navigateurs majeurs (IE6/7/8, Chrome, Firefox, Safari, Opera) afin d&#8217;y arranger les petits problèmes. Comme à l&#8217;habitude, IE6 est toujours un peu plus tannant, alors dans la même perspective qui m&#8217;avait poussé à expérimenter avec CSS3, j&#8217;ai décidé de rendre le site regardable dans ce navigateur, sans faire pieds et main pour le rendre <em>pixel perfect</em>. À ma grande surprise, lors des premiers jours après la mise en ligne, Google Analytics me disait qu&#8217;environ 90% du trafic était fait avec IE6! J&#8217;ai donc compris que les TI de la ville de Lévis n&#8217;avaient pas encore pris la peine de mettre à jour les navigateurs de certains employés! Par chance, après la vague de curieux à l&#8217;interne, la tendance est plutôt redevenue normale (c&#8217;est à dire, je n&#8217;ai pas revu d&#8217;IE6 depuis).</p>
<h3>CSS3 va rocker</h3>
<p>Dans ce projet, je n&#8217;ai utilisé qu&#8217;une seule règle de CSS3. Elle ajoute un petit quelque chose au site, sans pour autant avoir un effet dévastateur lorsqu&#8217;elle n&#8217;est pas rendue par le navigateur.</p>
<p>Il y a plusieurs autres règles qui, en réduisant l&#8217;utilisation d&#8217;images, vont vraiment accélérer l&#8217;intégration web et réduire la taille des pages.</p>
<p>Les navigateurs utilisés sont de plus en plus à jour: IE6 disparait et IE7 disparait encore plus vite maintenant qu&#8217;IE8 est sorti! On pourra donc très bientôt utiliser les derniers ajouts au fur et à mesure qu&#8217;ils arrivent.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hooba.ca/blog/2009/hooba-fait-dans-les-bonnes-oeuvres/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Should Hooba go English?</title>
		<link>http://www.hooba.ca/blog/2009/should-hooba-go-english/</link>
		<comments>http://www.hooba.ca/blog/2009/should-hooba-go-english/#comments</comments>
		<pubDate>Wed, 14 Oct 2009 03:14:25 +0000</pubDate>
		<dc:creator>Antoine Leclair</dc:creator>
				<category><![CDATA[Nouvelles]]></category>

		<guid isPermaLink="false">http://www.hooba.ca/blog/?p=431</guid>
		<description><![CDATA[I&#8217;ve been thinking of switching from French to English recently, and am still not sure what to do about it. The main reason that pushes me to make Hooba go English is that I eventually want to publish some projects (open source or not) and I want to get a broader reach. I don&#8217;t know [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been thinking of switching from French to English recently, and am still not sure what to do about it. The main reason that pushes me to make Hooba go English is that I eventually want to publish some projects (open source or not) and I want to get a broader reach. I don&#8217;t know if blogging in English is going to be too painful, but I&#8217;ll give it a try.</p>
<p>During the upcoming months I&#8217;ll try to make a transition, so you can expect me to blog both in English and in French. I&#8217;ll see how I can manage publishing in English and make a decision upon that.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hooba.ca/blog/2009/should-hooba-go-english/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MongoDB et autres bases de données NoSQL, le début d’une nouvelle ère</title>
		<link>http://www.hooba.ca/blog/2009/mongodb-et-autres-bases-de-donnees-nosql-le-debut-dune-nouvelle-ere/</link>
		<comments>http://www.hooba.ca/blog/2009/mongodb-et-autres-bases-de-donnees-nosql-le-debut-dune-nouvelle-ere/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 16:39:45 +0000</pubDate>
		<dc:creator>Antoine Leclair</dc:creator>
				<category><![CDATA[Environnement]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.hooba.ca/blog/?p=409</guid>
		<description><![CDATA[Depuis le printemps dernier, on entend parler de plus en plus du mouvement NoSQL. Pour ceux qui auraient eu la tête dans le sable pendant les derniers mois, il s&#8217;agit d&#8217;un mouvement qui cherche à trouver d&#8217;autres solutions pour la gestion des données que les RDBMS (bases de données relationnelles, à la MySQL / SQL [...]]]></description>
			<content:encoded><![CDATA[<p>Depuis <a href="http://nosql.eventbrite.com/">le printemps dernier</a>, on entend parler de plus en plus du mouvement NoSQL. Pour ceux qui auraient eu la tête dans le sable pendant les derniers mois, il s&#8217;agit d&#8217;un mouvement qui cherche à trouver d&#8217;autres solutions pour la gestion des données que les <a href="http://en.wikipedia.org/wiki/RDBMS">RDBMS</a> (bases de données relationnelles, à la MySQL / SQL Server). C&#8217;est donc le retour en force des bases de donnée <em>key/value pair</em> et autres formes de bases de données sans schéma.<span id="more-409"></span></p>
<h3>Les problèmes des RDBMS</h3>
<p>Les bases de données relationnelles ont comme caractéristique principale d&#8217;être très structurées. C&#8217;est sans doute la raison derrière leur grande popularité. Par contre, ce ne sont pas tous les problèmes qui tombent dans le moule de ce type d&#8217;architecture.</p>
<p>Aussi, il devient plutôt difficile, dépassé un certain point, de continuer à <em>scaler</em> horizontalement avec ce type de bases de données. On met la base de donnée sur un autre serveur, ensuite on ajoute des réplications pour avoir des master/slaves, on optimise nos requêtes&#8230; ça peut nous mener très loin, mais pas assez loin pour les gros joueurs. Le problème des performances était donc aussi une des motivations pour chercher une autre solution.</p>
<h3>The new kids on the block</h3>
<p>Alors voilà qu&#8217;apparait toutes les nouvelles bases de données et que le sujet se met à bouillonner. <a href="http://1978th.net/">Tokyo</a>, <a href="http://couchdb.apache.org/">CouchDB</a>, <a href="http://www.mongodb.org/">MongoDB</a>, <a href="http://hadoop.apache.org/hbase/">HBase</a> (du projet <a href="http://hadoop.apache.org/">Hadoop</a>), <a href="http://code.google.com/p/redis/">Redis</a>, <a href="http://incubator.apache.org/cassandra/">Cassandra</a>, etc.</p>
<p>Ces projets sont pour la plupart orienté sur la distributivité de la base de donnée. Elles ont été conçues à la base pour <em>scaler</em> horizontalement.</p>
<h3>Essai de MongoDB avec PHP</h3>
<p>J&#8217;ai donc décidé d&#8217;essayer un de ces systèmes: <a href="http://www.mongodb.org/">MongoDB</a>. Il s&#8217;agit d&#8217;une base de donnée sans schéma: on y stock les données à peu près comme on veut et chaque entrées peut avoir des champs différents. L&#8217;installation est plutôt simple (du moins sous Linux), <a href="http://www.mongodb.org/display/DOCS/Downloads">les fichiers binaires ou le code source</a> sont disponible sur le site web. Lorsque le serveur est installé, il faut installer les <em>drivers</em> pour chaque langage que l&#8217;on compte utiliser (PHP, Python, Ruby, Java, etc. C++, lui, est inclu). J&#8217;ai donc installé le <em>driver</em> pour PHP à partir du <a href="http://www.mongodb.org/display/DOCS/Installing+the+PHP+Driver">code source sur le site web</a>. Seulement ensuite je me suis rendu compte que j&#8217;aurais pu me sauver un peu de compilation en faisant simplement <code>sudo pecl install mongo</code> (sous Ubuntu).</p>
<p>Voici un exemple de code <a href="http://www.mongodb.org/display/DOCS/PHP+Tutorial">tiré à peu près du site de MongoDB</a> pour insérer des données:</p>
<pre><code>$m = new Mongo();
$collection = $m->selectDB( "foo" )->selectCollection( "bar" );

$doc = array( "name" => "MongoDB",
   "type" => "database",
   "count" => 1,
   "info" => (object)array( "x" => 203,
       "y" => 102),
   "versions" => array("0.9.7", "0.9.8", "0.9.9")
);

$collection->insert( $doc );</code></pre>
<p>On les récupère ensuite:</p>
<pre><code>$m = new Mongo();
$collection = $m->selectDB( "foo" )->selectCollection( "bar" );

$obj = $collection->findOne();
</code></pre>
<p>Ou on peut faire une requête pour plusieurs résultats:</p>
<pre><code>$m = new Mongo();
$collection = $m->selectDB( "foo" )->selectCollection( "bar" );

$cursor = $collection->find( array('name' => 'MongoDB') );

while( $cursor->hasNext() ) {
    var_dump( $cursor->getNext() );
}</code></pre>
<h3>Simple, trop simple?</h3>
<p>Avec les bases de données relationnelles, le simple apprentissage du SQL permettait de bien comprendre le paradigme des RDBMS et de bien s&#8217;en servir. Maintenant, avec les nouvelles bases de données qui apparaissent, nous avons beaucoup plus de flexibilité: on y met à peu près ce qu&#8217;on veut. Le prochain objet qu&#8217;on y insère n&#8217;a pas besoin de ressembler au précédent. Cette flexibilité est bienvenue et très puissante (par exemple, on peut faire rouler plusieurs version de la même application en même temps, selon le client, avec la même base de donnée, comme Google le fait avec Gmail).</p>
<p>Cette flexibilité et simplicité vient par contre au prix d&#8217;être complètement laissés à nous-même. Les RDBMS sont vieilles et son fonctionnement bien connu de tous. Des tonnes de livres ont été écrites sur MySQL, SQLite, SQL Server et l&#8217;architecture avec les RDBMS. Les fonctionnalités des nouvelles bases de données sont généralement bien documentées. C&#8217;est très simple (beaucoup plus simple qu&#8217;avec du SQL) d&#8217;y insérer et récupérer des entrées. Par contre, la façon de penser l&#8217;architecture d&#8217;applications qui utilisent ces bases de données est plutôt nébuleuse. Je n&#8217;ai pas encore vu de livre qui traitent de l&#8217;utilisation de ces systèmes et les blogs qui en glissent un mot parlent plutôt de l&#8217;architecture matérielle utilisée, des raisons qui ont poussés la migration et des raisons de leur choix particulier parmi les nouvelles bases de données.</p>
<h3>On va continuer d&#8217;en entendre parler</h3>
<p>Ceci dit, tout ce que j&#8217;ai lu à date sur le sujet est très positif. Est-ce révolutionnaire ou bien avait-on simplement besoin d&#8217;air frais? Une chose est sûr c&#8217;est que les bases de données &laquo;&nbsp;non-relationnelles&nbsp;&raquo; sont là pour rester. Par contre, elles n&#8217;écraseront pas les RDBMS pour toutes les situations de si tôt: elles ne sont pas (et ne tentent pas d&#8217;être) <a href="http://en.wikipedia.org/wiki/ACID">ACID</a>. On continuera donc sans doute à utiliser les RDBMS pour les utilisations comme les transactions financières, où l&#8217;intégrité des données et l&#8217;utilisation de transactions (dans le sens SQL du terme) sont importantes.</p>
<p>Encore faut-il que nos universités abordent le sujet. Parions qu&#8217;ils n&#8217;en parleront pas avant un bon 10 ans!</p>
<p>Si vous connaissez une source (livre, blog, wiki, etc.) où on peut en apprendre sur la conception d&#8217;application et d&#8217;architecture avec ces nouvelles bases de données, laissez-moi savoir!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hooba.ca/blog/2009/mongodb-et-autres-bases-de-donnees-nosql-le-debut-dune-nouvelle-ere/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bon code, Bad code</title>
		<link>http://www.hooba.ca/blog/2009/bon-code-bad-code/</link>
		<comments>http://www.hooba.ca/blog/2009/bon-code-bad-code/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 03:19:15 +0000</pubDate>
		<dc:creator>Antoine Leclair</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Sécurité]]></category>
		<category><![CDATA[Théorie]]></category>

		<guid isPermaLink="false">http://www.hooba.ca/blog/?p=384</guid>
		<description><![CDATA[Il n&#8217;y a pas si longtemps, j&#8217;ai eu à intégrer du code PHP qu&#8217;un autre programmeur avait déjà fait pour un autre site. Le client tenait à ce que j&#8217;utilise son &#171;&#160;module&#160;&#187; de nouvelles en pensant sauver de l&#8217;argent. La première fois que j&#8217;ai eu à intégrer ledit module, ç&#8217;a effectivement été plutôt rapide étant [...]]]></description>
			<content:encoded><![CDATA[<p>Il n&#8217;y a pas si longtemps, j&#8217;ai eu à intégrer du code PHP qu&#8217;un autre programmeur avait déjà fait pour un autre site. Le client tenait à ce que j&#8217;utilise son &laquo;&nbsp;module&nbsp;&raquo; de nouvelles en pensant sauver de l&#8217;argent. La première fois que j&#8217;ai eu à intégrer ledit module, ç&#8217;a effectivement été plutôt rapide étant donné que le site était fait dans le même <em>pattern</em> que le site d&#8217;origine. Par contre, la deuxième fois, c&#8217;était une toute autre chose!<span id="more-384"></span></p>
<h3>Du code non-réutilisable</h3>
<p>J&#8217;espère ne rendre personne triste en publiant cet article, mais je vais vous faire un petit copier-coller d&#8217;une fonction pour illustrer mes points.</p>
<pre>&lt;?php
// _______________________________________________________________________
// Display news list
function fct_display_news_list(){
    // Search
    if(isset($_GET['search']) &amp;&amp; !empty($_GET['search'])){
        $query = " WHERE title LIKE CONVERT(_utf8 '%".$_GET['search']."%' USING latin1) OR content LIKE CONVERT(_utf8 '%".$_GET['search']."%' USING latin1)";
    }else{
        if(isset($_GET['date']) &amp;&amp; ereg("^[0-9]{4}\-[0-9]{2}$", $_GET['date'])){
            $arr = explode("-", $_GET['date']);
            $date_start = mktime(0, 0, 0, $arr[1], 1, $arr[0]);
            $date_end = mktime(0, 0, 0, $arr[1] + 1, 1, $arr[0]);
            $query = " WHERE date_news&gt;=".$date_start." AND date_news&lt;".$date_end;
        }
    }
    if(!isset($query)){
        $query = " ORDER BY date_news DESC LIMIT 3";
    }else{
        $query .= " ORDER BY date_news DESC";
    }

    $query = "SELECT * FROM juris_news".$query;
    $result = mysql_query($query) or die(mysql_error());
    if(mysql_num_rows($result) &gt; 0){
        for($i = 1; $row = mysql_fetch_array($result); $i++){
?&gt;
    &lt;h3 first"); } ?&gt;"&gt;&lt;?= $row['title']; ?&gt;&lt;/h3&gt;
    &lt;p&gt;&lt;?= date("Y-m-d", $row['date_news']); ?&gt;&lt;/p&gt;
    &lt;p&gt;&lt;?= $row['intro']; ?&gt;&lt;/p&gt;
    &lt;p&gt;&lt;a href="actualites.php?id=&lt;?= $row['id']; ?&gt;" onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('news&lt;?= $i; ?&gt;','','medias/img_c_btn_savoir_rl.gif',0)"&gt;&lt;img src="medias/img_c_btn_savoir_up.gif" alt="En savoir plus" name="news&lt;?= $i; ?&gt;" id="news&lt;?= $i; ?&gt;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;?php
        }
    }else{
        echo("&lt;p&gt;Aucune actualit&amp;eacute; trouv&amp;eacute;e.&lt;/p&gt;");
    }
}</pre>
<p>Il s&#8217;agit ici de la première fonction d&#8217;une dizaine de fonctions similaires qui constituent le fichier.</p>
<h3>Premier péché: mélanger la logique avec la présentation</h3>
<p>La principale force de PHP est aussi sa principale faiblesse: il est très facile de mélanger du PHP avec du HTML. On peut avoir une page entière en HTML et y insérer très facilement un peu de PHP. On peut par contre aussi avoir du PHP et y insérer du HTML. Le problème avec cette fonction, c&#8217;est qu&#8217;elle génère (et affiche) du HTML.</p>
<p>On peut voir très facilement que le code HTML affiché n&#8217;est pas réutilisable. Il y a des appels à des fonctions JavaScript et des images dont le chemin d&#8217;accès est <em>hard coded</em>. Par exemple, la fonction affiche:</p>
<pre><code>// mauvais
</code>&lt;p&gt;&lt;a href="actualites.php?id=&lt;?= $row['id']; ?&gt;" onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('news&lt;?= $i; ?&gt;','','medias/img_c_btn_savoir_rl.gif',0)"&gt;&lt;img src="medias/img_c_btn_savoir_up.gif" alt="En savoir plus" name="news&lt;?= $i; ?&gt;" id="news&lt;?= $i; ?&gt;" /&gt;&lt;/a&gt;&lt;/p&gt;</pre>
<p>Il est fort peu probablement que j&#8217;aie à utiliser les mêmes fonctions JavaScript et que j&#8217;utilise les mêmes images. Aussi, le <em>markup</em> HTML généré ne conviendra générallement pas aux besoins d&#8217;un autre site. Par exemple, je doute que <code>&lt;h3 class="blue"&gt;</code> puissent être réutilisé.</p>
<p>La meilleur façon aurait été de simplement arrêter la fonction à la fin de la requête SQL. La fonction aurait simplement pu retourner un <em>array</em>, un objet ou un itérateur. De cette manière, on sépare la logique de la présentation. Par exemple, si la fonction retournait un <em>array</em> <code>$nouvelles</code>, on pourrait l&#8217;intégrer dans la page directement.</p>
<pre><code>&lt;!-- Mieux --&gt;
&lt;!-- Markup de ce qui vient avant dans la page ici... --&gt;
&lt;div id="nouvelles"&gt;
    &lt;h2&gt;Nouvelles&lt;/h2&gt;
    &lt;?php if (!empty($nouvelles)) : ?&gt;
    &lt;?php foreach ($nouvelles as $nouvelle) : ?&gt;
    &lt;p class="date"&gt;&lt;?= date("Y-m-d", $nouvelle['date_news']) ?&gt;&lt;/p&gt;
    &lt;p&gt;&lt;?= $nouvelle['intro'] ?&gt;&lt;/p&gt;
    &lt;p&gt;&lt;a href="actualites.php?id=&lt;?= $nouvelle['id']; ?&gt;" class="more"&gt;En savoir plus&lt;/a&gt;&lt;/p&gt;
    &lt;?php endforeach ?&gt;
    &lt;?php else : ?&gt;
    &lt;p&gt;Aucune nouvelle&lt;/p&gt;
    &lt;?php endif ?&gt;
&lt;/div&gt;
&lt;!-- Suite du site ici... --&gt;
&lt;div id="sidebar"&gt;</code></pre>
<h3>Deuxième péché: La fonction n&#8217;accepte aucun paramètre</h3>
<p>De la façon dont la fonction est codée, on n&#8217;a aucun moyen externe (lire: aucun paramètre) d&#8217;affecter son déroulement. Si <code>$_GET['search']</code> contient quelque chose, une recherche sera faite, sinon, les trois dernières nouvelles sont affichées.</p>
<p>Il serait bien de pouvoir appeler la fonction en lui demandant un certain nombre de nouvelles. Je ne veux pas avoir toujours les trois dernières nouvelles dans tous les sites que je dois faire.</p>
<p>Aussi, si je veux faire une recherche, je ne veux pas nécessairement utiliser <code>$_GET['search']</code> comme chaine à chercher.</p>
<p>Le prototype de cette fonction aurait plutôt dû ressembler à ceci:</p>
<pre><code>function fct_display_news_list($quantity = 3, $search = NULL)</code></pre>
<p>De cette manière, on aurait pu avoir des comportements par défaut si on ne passe aucun argument tout en ayant un certain contrôle en cas de besoin. Si je voulais à ce moment utiliser la fonction en utilisant la valeur de <code>$_GET['search']</code> comme clé de recherche, j&#8217;aurais pu l&#8217;appeler ainsi:</p>
<pre><code>fct_display_news(3, $_GET['search'])</code></pre>
<h3>Troisième péché: la fonction fait trop de choses</h3>
<p>La fonction &laquo;&nbsp;raboute&nbsp;&raquo; des morceaux de requêtes SQL <strong>en créant la fin de la requête</strong> (<code>"WHERE ..."</code>) <strong>en premier</strong>. Je trouve étrange d&#8217;avoir commencé par la fin sans raison apparente. Ça ne fait que complexifier le code.</p>
<p>En plus, pourquoi ne pas avoir simplement séparé la fonction en deux fonctions? Chaque fonction aurait été beaucoup plus claire et facile à maintenir. Exemple:</p>
<pre><code>// mieux
function get_news($quantity = 3, $search = NULL){
    if ($search == NULL)
        return get_latest_news($quantity);
    else // $search != NULL
        return get_searched_news($quantity, $search);
}

function get_lastest_news($quantity = 3){
    // fonction qui retourne les $quantity dernières nouvelles
    // ...
}

function get_searched_news($quantity = 3, $search = NULL){
    // fonction qui retourne les $quantity dernières nouvelles trouvées selon la clé de recherche
    // ...
}</code></pre>
<p>Si on regarde la liste des fonctions du fichier, on se rend vite compte qu&#8217;une approche orienté objet aurait très bien fait la job. Une classe <code>News</code> aurait grandement simplifié le tout.</p>
<h3>Quatrième péché: des noms qui ne veulent rien dire</h3>
<p>Si on retourne dans le code au début de l&#8217;article, on peut voir qu&#8217;il y a plusieurs noms encombrés d&#8217;abréviations superflues ou qui ne veulent rien dire aux yeux de la prochaine personne qui touche le code.</p>
<p>Est-ce que j&#8217;ai vraiment besoin de spécifier dans le nom d&#8217;une fonction qu&#8217;il s&#8217;agit d&#8217;une fonction en y préfixant <code>fct</code>? Aussi, un fichier nommé <code>img_c_btn_savoir_up.gif</code>: un fichier <code>gif</code> est une image, pas besoin de préfixer <code>img</code> à son nom. Dans le même nom de fichier, que veut dire le &laquo;&nbsp;<code>c</code>&laquo;&nbsp;?</p>
<p>Une fonction devrait avoir un nom qui permet de savoir ce qu&#8217;elle fait tout en étant concis. <code>display_news_list</code> aurait été suffisant.</p>
<h3>Cinquième péché: être vulnérable aux injections SQL</h3>
<p>Étant donné que la fonction n&#8217;accepte aucun paramètre, le programmeur a utilisé la valeur de <code>$_GET['search']</code> directement dans sa fonction. Le problème que je veux souligner ici c&#8217;est la manière dont il l&#8217;a utilisée. Il l&#8217;a mis directement dans une requête sans la filtrer:</p>
<pre><code>// mauvais
$query = " WHERE title LIKE CONVERT(_utf8 '%".$_GET['search']."%' USING latin1) OR content LIKE CONVERT(_utf8 '%".$_GET['search']."%' USING latin1)";
</code></pre>
<p>En insérant directement des valeurs fournies par l&#8217;utilisateur (ici, dans la barre d&#8217;adresse) sans les avoir filtrés au préalable est une mauvaise pratique car elle ouvre très grand les portes aux <a href="http://www.hooba.ca/blog/2009/prevenir-les-injections-sql-avec-php-et-mysql/">attaques par injection SQL</a>.</p>
<h3>En conclusion</h3>
<p>Quand on programme, c&#8217;est important de toujours penser à la réutilisabilité du code. Il faut bien sûr parfois faire du code &laquo;&nbsp;<em>quick and dirty</em>&laquo;&nbsp;, mais les choses importantes que je viens d&#8217;énumérer ne sont pas compliqués à respecter. D&#8217;ailleurs, le programmeur aurait en fait sauvé du temps s&#8217;il avait fait du code réutilisable, car il a eu à reprogrammer un autre ensemble complet de fonctions pour le côté administrateur. S&#8217;il avait dès le départ fait une nouvelle classe ou simplement mieux conçu ses fonctions, il aurait facilement pu sauver beaucoup de temps en réutilisant lui-même son propre code à l&#8217;intérieur du même projet.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hooba.ca/blog/2009/bon-code-bad-code/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Contrôle de version avec Mercurial</title>
		<link>http://www.hooba.ca/blog/2009/controle-de-version-avec-mercurial/</link>
		<comments>http://www.hooba.ca/blog/2009/controle-de-version-avec-mercurial/#comments</comments>
		<pubDate>Sat, 06 Jun 2009 03:16:23 +0000</pubDate>
		<dc:creator>Antoine Leclair</dc:creator>
				<category><![CDATA[Environnement]]></category>
		<category><![CDATA[Regardez-ça]]></category>

		<guid isPermaLink="false">http://www.hooba.ca/blog/?p=361</guid>
		<description><![CDATA[Il y a quelques mois, je vous vantais les mérites de Subversion. Je trouve encore que Subversion est un très bon système de contrôle de version. Par contre, à la fin du mois d&#8217;avril, Google Code a annoncé qu&#8217;il allait désormais aussi supporter Mercurial.
Malgré le hype qu&#8217;il y avait pour Git, Google a tout de [...]]]></description>
			<content:encoded><![CDATA[<p>Il y a quelques mois, <a href="http://www.hooba.ca/blog/2008/hebergement-gratuit-de-subversion/">je vous vantais les mérites de Subversion</a>. Je trouve encore que Subversion est un très bon système de contrôle de version. Par contre, à la fin du mois d&#8217;avril, <a href="http://google-code-updates.blogspot.com/2009/04/mercurial-support-for-project-hosting.html">Google Code a annoncé qu&#8217;il allait désormais aussi supporter Mercurial</a>.</p>
<p>Malgré le <em>hype</em> qu&#8217;il y avait pour <a href="http://git-scm.com/">Git</a>, Google a tout de même choisi <a href="http://www.selenic.com/mercurial/">Mercurial</a>, que je ne connaissais pas vraiment. J&#8217;ai donc décidé de l&#8217;essayer.</p>
<p><span id="more-361"></span></p>
<h3>Distribué vs centralisé</h3>
<p>Tout d&#8217;abord, Mercurial est comme Git, dans le sens où il s&#8217;agit d&#8217;un système de contrôle de version <strong>distribué</strong>. Subversion, lui, est centralisé.</p>
<p>Concrètement, Subversion a son <em>repository</em> à <strong>un</strong> endroit (générallement sur un serveur). Chaque utilisateur va chercher les fichiers (<em>checkout</em>), fait ses modifications et les renvoit au serveur (<em>commit</em>).</p>
<p>Mercurial, étant distribué, fonctionne de façon légèrement différente. Lorsqu&#8217;un utilisateur va chercher les fichiers, il va en fait faire une <strong>copie entière</strong> du <em>repository</em>. Le scénario classique est qu&#8217;un utilisateur va chercher les fichiers sur le serveur (<em>clone</em>), fait ses modifications et les &laquo;&nbsp;commet&nbsp;&raquo; (<em>commit</em>) <strong>seulement dans son <em>repository</em> local</strong>. Ensuite, il peut envoyer ses changement dans le <em>repository</em> d&#8217;où il a pris ses fichiers (<em>push</em>).</p>
<p>Avec Mercurial, on ne fait pas un <em>checkout</em> et un <em>commit</em>. On fait une branche (<em>clone</em>), et on la <em>merge</em> (<em>push</em>) après avoir fait un ou des changements (<em>commit</em>). Ça comporte plusieurs avantages pour certains types de projets, mais je n&#8217;en parlerai pas dans cet article.</p>
<h3>Dossier .hg vs dossiers .svn</h3>
<p>Subversion utilise plusieurs dossiers <code>.svn</code>. Lorsque vous travaillez dans votre <em>checkout</em>, il y a un dossier <code>.svn</code> par dossier ou sous-dossier de votre projet. Ils ne sont (supposément) pas très nuisibles.</p>
<p>Par contre, j&#8217;ai souvent fait face à un problème avec ces dossiers. Un client me dit qu&#8217;il veut avoir les fichiers pour montrer à son propre client. Il veut les avoir par FTP. La méthode idéale serait simplement de lui envoyer mon dossier de travail. Par contre, mon dossier de travail est infesté de <code>.svn</code>! Non seulement ces fichiers n&#8217;ont pas d&#8217;affaires là, mais imaginez le temps que ça prendrait mettre tout ces petits dossier en ligne! Croyez-moi, c&#8217;est trop long.</p>
<p>Je pourrais supprimer les dossiers <code>.svn</code> de tout mon projet avec un tour de passe-passe <em>bash</em>:</p>
<pre><code>find ./ -name ".svn" | xargs rm -Rf</code></pre>
<p>Mais faire ça &laquo;&nbsp;détruirait&nbsp;&raquo; mon <em>checkout</em>. J&#8217;aurais besoin de faire un autre <em>checkout</em> avant de continuer à travailler. Je pourrais faire une copie de mon dossier et faire cette commande sur ma copie. Mais copier tous ces sous-dossiers prend parfois bien du temps!</p>
<p>Je pourrais aussi (la solution que j&#8217;utilisais) faire un <code>export</code> à partir de mon <em>repository</em>. Il y a quelques points tannants avec cette méthode. Premièrement, Subversion est plutôt lent pour faire un <code>export</code> ou un <code>checkout</code>. Surtout que certains projets deviennent pesant assez rapidement avec les fichiers Flash et toutes les images (les PNG 24-bits ça monte vite!). Deuxièmement, lorsque le client me demande d&#8217;avoir les fichiers, j&#8217;ai parfois fait certaines modifications que je n&#8217;ai pas encore envoyées dans le <em>repository</em>. Je dois donc en premier faire un <code>commit</code> et ensuite je peux faire le <code>export</code>. Troisième chose, lorsque j&#8217;ai terminé d&#8217;envoyer les fichiers à mon client, je dois supprimer le dossier que je viens de créer. Pas grand chose vous direz, mais c&#8217;est quand même une étape de plus, qui n&#8217;a pas sa place à mon avis.</p>
<p>Mercurial, lui, ne parsème pas ses dossiers un peu partout au travers du répertoire de travail. Il n&#8217;y a qu&#8217;un dossier <code>.hg</code> à la racine du <em>repository</em> (rappelez-vous que le dossier de travail est un <em>repository</em> en soit). Donc, tous les problèmes énoncés ci-haut disparaissent. Je peux directement envoyer mon répertoire de travail, en prenant la peine de désélectionner le dossier <code>.hg</code> (et les autres fichiers, s&#8217;il y a lieu, comme <code>.hgignore</code>).</p>
<h3>Commit local</h3>
<p>Avec Subversion, lorsqu&#8217;on fait un <code>commit</code>, on envoie les modifications au serveur, car c&#8217;est lui qui contient le <em>repository</em>. Avec Mercurial, lorsqu&#8217;on fait un <code>commit</code>, il n&#8217;y a aucune utilisation du réseau. Le <em>repository</em> est local. On peut donc faire plusieurs <code>commit</code> sans envoyer les modifications au <em>repository</em> où on a pris les fichiers. Lorsqu&#8217;on est prêt, on <code>push</code> les <code>commit</code> qu&#8217;on a fait.</p>
<h3>Vitesse</h3>
<p>Je ne peux pas garantir que Mercurial est plus rapide que Subversion, mais je dois avouer que je trouve l&#8217;expérience beaucoup plus fluide avec Mercurial qu&#8217;avec Subversion.</p>
<h3>Facilité</h3>
<p>J&#8217;avais jeté un oeil rapidement à Git il y a quelque temps, mais je ne m&#8217;y était pas attardé. La première impression que j&#8217;avais eu était que ça semblait compliqué. Comme les projets sur lesquels je travaille ne profitent pas vraiment du fait que ce soit extrêmement facile de brancher-<em>merger</em> avec les systèmes distribués, j&#8217;avais simplement laissé Git de côté. Je n&#8217;étais peut-être pas dû pour changer de système à ce moment&hellip;</p>
<p>Par contre, lorsque j&#8217;ai essayé (et maintenant adopté) Mercurial, j&#8217;ai eu une toute autre impression! Il est facile à comprendre et, à mon avis, bien conçu. La courbe d&#8217;apprentissage est très légère.</p>
<h3>Ajout de fichiers</h3>
<p>Avec Subversion, il faut ajouter les fichiers un par un. Encore une fois, ce serait sûrement possible de faire un tour de passe-passe avec <code>grep</code>, mais ça serait plutôt tannant. Si on crée 8 nouveau fichiers, il faut ajouter les 8 fichiers un après l&#8217;autre.</p>
<p>Avec Mercurial, la même commande (<code>add</code>) ajoute tous les nouveaux fichiers. Pas de perte de temps. Si on veut ne pas ajouter certains fichiers (exemple: ceux se terminant avec ~), il suffit de se faire un fichier <code>.hgignore</code> dans la racine de notre projet, et le tour est joué.</p>
<h3>Hébergement</h3>
<p>Premièrement, de la façon dont est conçu Mercurial, il est beaucoup plus facile de ne simplement pas utiliser d&#8217;hébergeur. On se fait un <em>repository</em> avec <code>hg init mon_projet</code> et on peut déjà commencer à travailler dans le dossier! Pas besoin de faire un <code>checkout</code> et de travailler dans le dossier du <em>checkout</em>.</p>
<p>Ensuite, comme Subversion, on peut simplement fonctionner par SSH (si vous avez accès à un autre ordinateur/serveur par SSH). <code>hg push ssh://user@example.com/chemin/vers/repo</code>. C&#8217;est simple et rapide.</p>
<p>Vous pouvez aussi configurer Mercurial pour fonctionner par HTTP si votre projet a un peu d&#8217;envergure. Par contre, ce n&#8217;est probablement pas la solution idéale si vous faites parti d&#8217;une petite compagnie qui travaille sur plusieurs petits projets.</p>
<p>Sinon, il y a un certain nombre d&#8217;hébergeur. Le plus gros est probablement <a href="http://bitbucket.org">bitbucket</a>. Ils offrent l&#8217;hébergement gratuit pour les projets <code>open source</code>, mais aussi de l&#8217;hébergement privé. Ils sont un peu le <a href="http://github.com/">GitHub</a> de Mercurial.</p>
<h3>Essayez-le!</h3>
<p>Tout ça pour vous dire que ça vaut la peine de l&#8217;essayer! Si vous avez peur du <em>command-line</em>, je crois qu&#8217;il y a même des GUI plutôt bien faits pour Windows, OS X et Linux.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hooba.ca/blog/2009/controle-de-version-avec-mercurial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Environnement de développement web: Serveurs Virtuels</title>
		<link>http://www.hooba.ca/blog/2009/environnement-de-developpement-web-serveurs-virtuels/</link>
		<comments>http://www.hooba.ca/blog/2009/environnement-de-developpement-web-serveurs-virtuels/#comments</comments>
		<pubDate>Fri, 01 May 2009 00:37:38 +0000</pubDate>
		<dc:creator>Antoine Leclair</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Environnement]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.hooba.ca/blog/?p=320</guid>
		<description><![CDATA[Il y a quelques mois, je vous montrais comment installer un environnement de développement web de base sous Ubuntu.
Aujourd&#8217;hui je continue là où je vous avais laissé, c&#8217;est-à-dire: vous venez d&#8217;installer Apache, MySQL, PHP et phpMyAdmin et avez vérifié que le tout fonctionnait bien. Votre dossier web est /var/www. Le but de l&#8217;article d&#8217;aujourd&#8217;hui est [...]]]></description>
			<content:encoded><![CDATA[<p>Il y a quelques mois, je vous montrais <a href="http://www.hooba.ca/blog/2008/comment-se-creer-un-environnement-de-developpement-web/">comment installer un environnement de développement web</a> de base sous Ubuntu.</p>
<p>Aujourd&#8217;hui je continue là où je vous avais laissé, c&#8217;est-à-dire: vous venez d&#8217;installer Apache, MySQL, PHP et phpMyAdmin et avez vérifié que le tout fonctionnait bien. Votre dossier web est <code>/var/www</code>. Le but de l&#8217;article d&#8217;aujourd&#8217;hui est de vous permettre d&#8217;utiliser un autre dossier. En fait, vous pourrez utiliser un dossier différent pour chaque projet et y accéder avec des noms de domaines différents. Je vous introduis donc aux serveurs virtuels.<span id="more-320"></span></p>
<h3>Serveurs virtuels</h3>
<p>Un serveur virtuel, c&#8217;est quoi? C&#8217;est ce qui permet à Apache de servir plusieurs domaines ou sous-domaines à partir du même serveur. Par exemple, Apache peut servir <code>www.example.com</code> et <code>blog.example.com</code> en même temps. Chacun ayant son propre serveur virtuel.</p>
<h3>Le dossier d&#8217;Apache</h3>
<p>Tout d&#8217;abord, dans le dossier de configuration d&#8217;Apache, <code>/etc/apache2</code>, il y a, entre autres, les dossiers <code>sites-available</code> et <code>sites-enabled</code>.</p>
<p>Le dossier <code>sites-available</code> contient tous les fichiers de configurations de vos sites web. Pour l&#8217;instant, il n&#8217;en contient qu&#8217;un seul: <code>default</code>, qui dirige vers le dossier <code>/var/www</code>. Nous partirons de ce <code>default</code> pour se créer d&#8217;autres serveurs virtuels.</p>
<p>Le dossier <code>sites-enabled</code> contient des <em>symlinks</em> vers les fichiers de configurations contenus dans <code>sites-available</code>. Ces <em>symlinks</em> existent uniquement lorsque ces sites sont actifs. Lorsqu&#8217;Apache s&#8217;initialise, il vérifie les fichier dans <code>sites-enabled</code>.</p>
<p>Pour activer ou désactiver un site, on utilise les commandes <code>a2ensite</code> et <code>a2dissite</code>.</p>
<h3>Créer un serveur virtuel</h3>
<p>On commence par aller dans le dossier où les fichiers de configuration se situent:</p>
<pre><code>cd /etc/apache2/sites-available</code></pre>
<p>Ensuite, on se fait une copie du fichier <code>default</code> pour notre premier projet:</p>
<pre><code>sudo cp default projetun</code></pre>
<p>Et on modifie le nouveau fichier:</p>
<pre><code>sudo gedit projetun</code></pre>
<p>Première chose à modifier, c&#8217;est le <code>DocumentRoot</code>, c&#8217;est à dire, le dossier racine à partir duquel Apache va servir les pages pour ce site web. J&#8217;utilise générallement un dossier dans mon <em>home</em>. Quelque chose comme <code>/home/hooba/web/projetun/htdocs</code>. Remplacez donc <code>/var/www</code> par le dossier de votre choix pour ce projet. Remplacez aussi le nom du dossier dans la configuration du dossier en tant que tel quelque lignes plus bas (<code>&lt;Directory /var/www/&gt;</code>).</p>
<p>Ensuite, on veut ajouter le nom de domaine du serveur virtuel. Par défaut, Apache utilisait <code>localhost</code>. Après l&#8217;ouverture du <em>tag</em> <code>VirtualHost</code>, ajoutez le nom du serveur que vous voulez utiliser avec <code>ServerName</code>. Par exemple: <code>ServerName projetun.dev</code>.</p>
<p>Le haut de votre fichier devrait donc ressembler à:</p>
<pre><code>&lt;VirtualHost *:80&gt;
	ServerAdmin webmaster@localhost
	ServerName projetun.dev
	DocumentRoot /home/hooba/web/projetun/htdocs
	&lt;Directory /&gt;
		Options FollowSymLinks
		AllowOverride None
	&lt;/Directory&gt;
	&lt;Directory /home/hooba/web/projetun/htdocs&gt;
		Options Indexes FollowSymLinks MultiViews
		AllowOverride None
		Order allow,deny
		allow from all
	&lt;/Directory&gt;
	# ...</code></pre>
<p>Vous pouvez donc sauvegarder le fichier et fermer gedit.</p>
<h3>Activer le serveur virtuel</h3>
<p>Vous avez maintenant un fichier de configuration prêt à être utilisé dans <code>sites-available</code>. Il faut maintenant laisser savoir Apache qu&#8217;il a un nouveau site à servir.</p>
<p>Pour commencer, aller créer un fichier index.html dans le dossier que vous avez spécifié à l&#8217;étape précédente. Un fichier très simple suffira. Par exemple:</p>
<pre><code>&lt;html&gt;&lt;body&gt;
&lt;h1&gt;Tadam!&lt;/h1&gt;
&lt;/body&gt;&lt;/html&gt;</code></pre>
<p>Si vous allez à <code>http://projetun.dev/</code>, vous devriez avoir une erreur du genre &laquo;&nbsp;Serveur introuvable&nbsp;&raquo;. C&#8217;est, en premier lieu, parce qu&#8217;Apache n&#8217;est pas au courant qu&#8217;il doit servir quelque chose à partir de cette URL. On va donc l&#8217;avertir qu&#8217;il y a un nouveau site:</p>
<pre><code>sudo a2ensite projetun</code></pre>
<p>Cette commande crée le <em>symlink</em> nécessaire dans le dossier <code>sites-enabled</code>. Si vous n&#8217;utilisez pas le site <code>default</code>, vous pouvez égallement en profiter pour le désactiver avec:</p>
<pre><code>sudo a2dissite default</code></pre>
<p>Lorsque vous avez fait les modifications nécessaires, vous pouvez dire au <em>daemon</em> Apache qu&#8217;il doit recharger sa configuration:</p>
<pre><code>sudo /etc/init.d/apache2 reload</code></pre>
<h3>Hosts</h3>
<p>Si vous allez à l&#8217;adresse <code>http://projetun.dev/</code>, vous aurez la même erreur que tout à l&#8217;heure. La raison, c&#8217;est que votre navigateur demande à des serveurs DNS &laquo;&nbsp;à quelle adresse IP dois-je faire ma requête pour le domaine <code>projetun.dev</code>?&nbsp;&raquo;. Comme ces serveurs ne sont pas au courant que vous venez de créer un serveur virtuel, il faut empêcher la demande d&#8217;avoir lieu et spécifier immédiatement à quel ordinateur (à quelle adresse IP) on doit faire la requête.</p>
<p>Heureusement, c&#8217;est plutôt simple. Il suffit d&#8217;ajouter une ligne dans le fichier <code>hosts</code>. Il se situe dans le dossier <code>/etc</code>.</p>
<pre><code>sudo gedit /etc/hosts</code></pre>
<p>Ajoutez simplement une ligne à la fin qui indique votre adresse IP, ainsi que le domaine que vous venez de créer. L&#8217;adresse 127.0.0.1 correspond toujours à l&#8217;ordinateur sur lequel s&#8217;exécute le code. La ligne ajouté ressemblera donc à:</p>
<pre><code>127.0.0.1	projetun.dev</code></pre>
<p>Sauvegardez le fichier et quittez gedit.</p>
<h3>Un serveur virtuel fonctionnel</h3>
<p>Si vous avez bien suivi les étapes, lorsque vous allez à l&#8217;adresse <code>http://projetun.dev/</code> vous devriez voir le contenu du fichier <code>index.html</code> que vous avez créé tout à l&#8217;heure. Vous pouvez donc répéter l&#8217;opération pour chacun de vos projets.</p>
<p>Si ça ne fonctionne pas, voici quelques pistes afin de trouver votre problème: avez vous réinitialiser Apache (<code>sudo /etc/init.d/apache2 reload</code>)? Vous pouvez peut-être essayer de le redémarrer au complet avec <code>sudo /etc/init.d/apache2 restart</code>. Est-ce qu&#8217;Apache a les droits nécessaires pour accéder au dossier que vous avez spécifié? Est-ce que le fichier <code>projetun</code> existe bel et bien dans <code>/etc/apache2/sites-enabled</code>? Sinon, il faudrait simplement activer le site avec <code>sudo a2ensite projetun</code>. Si le fichier n&#8217;apparrait pas (ce n&#8217;est pas supposé), vous pourriez toujours essayer de directement faire un <em>symlink</em> vers le fichier dans <code>sites-available</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hooba.ca/blog/2009/environnement-de-developpement-web-serveurs-virtuels/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Un développeur web sans accès internet</title>
		<link>http://www.hooba.ca/blog/2009/un-developpeur-web-sans-acces-internet/</link>
		<comments>http://www.hooba.ca/blog/2009/un-developpeur-web-sans-acces-internet/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 04:07:05 +0000</pubDate>
		<dc:creator>Antoine Leclair</dc:creator>
				<category><![CDATA[Accessibilité]]></category>
		<category><![CDATA[Tranche de vie]]></category>

		<guid isPermaLink="false">http://www.hooba.ca/blog/?p=312</guid>
		<description><![CDATA[Me revoilà, après une semaine d&#8217;absence du web. Mon modem a cessé de fonctionner et j&#8217;ai dû en attendre un neuf.
Malgré mon handicap technologique, j&#8217;ai tout de même dû continuer à travailler. Je vous partage un peu de sagesse acquise spécialement pour l&#8217;occasion. 
Internet sur mon cellulaire, bien plus que du divertissement
Premièrement, je dois avouer [...]]]></description>
			<content:encoded><![CDATA[<p>Me revoilà, après une semaine d&#8217;absence du web. Mon modem a cessé de fonctionner et j&#8217;ai dû en attendre un neuf.</p>
<p>Malgré mon handicap technologique, j&#8217;ai tout de même dû continuer à travailler. Je vous partage un peu de sagesse acquise spécialement pour l&#8217;occasion. <span id="more-312"></span></p>
<h3>Internet sur mon cellulaire, bien plus que du divertissement</h3>
<p>Premièrement, je dois avouer que j&#8217;étais très content d&#8217;avoir un accès internet sur mon téléphone cellulaire pour garder contact par courriel avec mes clients. J&#8217;ai pu échanger mes courriels presque comme à l&#8217;habitude, et j&#8217;ai même utilisé un petit logiciel FTP pour mettre en ligne un travail en cours pour montrer les progrès à un client.</p>
<p>Par contre, je dois avouer que j&#8217;étais un peu frustré de ne pas encore être à l&#8217;ère où il n&#8217;y a pas de frais supplémentaires lorsqu&#8217;on utilise l&#8217;accès internet de son cellulaire à partir de son ordinateur.</p>
<h3>La documentation hors-ligne, une bénédiction</h3>
<p>Deuxièment, j&#8217;avais récement, un peu par hazard, mis à jour ma documentation hors-ligne. PHP, Kohana, MySQL. Je ne les utilise jamais d&#8217;habitude et je les avais mis à jour simplement dans le but de les avoir si jamais j&#8217;étais en déplacement à un endroit où il n&#8217;y a pas d&#8217;accès à internet. Ne pas avoir eu ça, je dois avouer que j&#8217;aurais perdu beaucoup de temps!</p>
<h3>Le 56K, pas aussi bon que dans l&#8217;temps!</h3>
<p>Troisièmement, mon ami Martin m&#8217;a gracieusement fournis son 10h d&#8217;accès téléphonique 56K qu&#8217;il a en prime avec son accès par cable. Ça m&#8217;a permis de me rendre compte que le web d&#8217;aujourd&#8217;hui n&#8217;est plus du tout fait pour les accès aussi lents. Les quelques fois où je me suis connecté, j&#8217;ai eu droit à plusieurs <em>timeouts</em> à cause des pages trop pesantes. Je me souviens de l&#8217;époque où j&#8217;ouvrais 4-5 pages et que j&#8217;allais me chercher un verre de jus en attendant que ça télécharge. Aujourd&#8217;hui, avec le même accès, même en ouvrant une seule page, elle ne se charge pas au complet parce qu&#8217;elle est trop volumineuse. Moi qui aime bien télécharger les <em>podcasts</em> de <a href="http://www.maximerobin.com/">Maxime Robin</a>, à 100Mo l&#8217;émission, j&#8217;ai passé mon tour!</p>
<p>Aussi, j&#8217;ai un modem 56K uniquement sur mon portable. C&#8217;est un <em>WinModem</em>; c&#8217;est à dire, il ne fonctionne que sous Windows. Je développe sous Ubuntu. Tout pour m&#8217;aider!</p>
<h3>Subversion, hébergé sur le web</h3>
<p>J&#8217;utilise générallement <a href="http://subversion.tigris.org/">Subversion</a> pour le contrôle de version. J&#8217;héberge mes <em>repositories</em> sur le web, question d&#8217;y avoir accès de partout. Comme je n&#8217;avais plus accès à internet avec mon ordinateur de développement, je n&#8217;avais plus accès à mes <em>repos</em>. Devrais-je les garder local? Avec <a href="http://git-scm.com/">Git</a>, le problème ne se poserait peut-être même plus, étant donné que j&#8217;aurais pu faire mes <em>commits</em> et les garder en local en attendant de faire les <em>commits</em> sur le web plus tard.</p>
<h3>La conclusion</h3>
<p>On tient pour acquis notre accès à internet. Mais au lieu de proposer qu&#8217;on en devienne moins dépendant, je pousse plutôt dans l&#8217;autre sens: internet devrait être beaucoup plus accessible, à partir de n&#8217;importe où. Ce genre de situation aurait été beaucoup moins problématique si j&#8217;avais pu temporairement utiliser mon cellulaire comme modem. Bonne nouvelle, les tarifs sont à la baisse, et la tendance va probablement s&#8217;accentuer.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hooba.ca/blog/2009/un-developpeur-web-sans-acces-internet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google sur twitter</title>
		<link>http://www.hooba.ca/blog/2009/google-sur-twitter/</link>
		<comments>http://www.hooba.ca/blog/2009/google-sur-twitter/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 16:53:36 +0000</pubDate>
		<dc:creator>Antoine Leclair</dc:creator>
				<category><![CDATA[Nouvelles]]></category>

		<guid isPermaLink="false">http://www.hooba.ca/blog/?p=306</guid>
		<description><![CDATA[L&#8217;ami Google vient de se créer un compte Twitter. Son premier twit:
I&#8217;m 01100110 01100101 01100101 01101100 01101001 01101110 01100111 00100000 01101100 01110101 01100011 01101011 01111001 00001010
Tout ce code binaire est en fait le code ASCII pour &#171;&#160;FEELING LUCKY&#160;&#187;. I&#8217;m feeling lucky&#8230; vous avez déjà fait une recherche en cliquant sur ce bouton vous?
]]></description>
			<content:encoded><![CDATA[<p>L&#8217;ami <a href="http://www.google.com/">Google</a> vient de se créer un compte Twitter. <a href="http://twitter.com/Google">Son premier twit</a>:</p>
<blockquote><p>I&#8217;m 01100110 01100101 01100101 01101100 01101001 01101110 01100111 00100000 01101100 01110101 01100011 01101011 01111001 00001010</p></blockquote>
<p>Tout ce code binaire est en fait le code ASCII pour &laquo;&nbsp;FEELING LUCKY&nbsp;&raquo;. I&#8217;m feeling lucky&#8230; vous avez déjà fait une recherche en cliquant sur ce bouton vous?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hooba.ca/blog/2009/google-sur-twitter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mettre vos pages WordPress en cache</title>
		<link>http://www.hooba.ca/blog/2009/mettre-vos-pages-wordpress-en-cache/</link>
		<comments>http://www.hooba.ca/blog/2009/mettre-vos-pages-wordpress-en-cache/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 16:16:42 +0000</pubDate>
		<dc:creator>Antoine Leclair</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.hooba.ca/blog/?p=287</guid>
		<description><![CDATA[En septembre dernier, sur mon site personnel, j&#8217;ai décidé de jeter mon vieux CMS homemade et de le remplacer par WordPress. Comme vous pouvez le voir, j&#8217;y publie surtout des photos et le gros de mon trafic venait par images.google.com. Lorsque je suis reparti à neuf, j&#8217;ai vu toute mes images dans l&#8217;index de Google [...]]]></description>
			<content:encoded><![CDATA[<p>En septembre dernier, sur <a href="http://www.antoineleclair.ca/">mon site personnel</a>, j&#8217;ai décidé de jeter mon vieux CMS <em>homemade</em> et de le remplacer par WordPress. Comme vous pouvez le voir, j&#8217;y publie surtout des photos et le gros de mon trafic venait par <a href="http://images.google.com/">images.google.com</a>. Lorsque je suis reparti à neuf, j&#8217;ai vu toute mes images dans l&#8217;index de Google disparaître tranquillement, sans que les nouvelles n&#8217;y apparaissent.</p>
<p>Mon blog est pourtant optimisé pour les moteurs de recherche. J&#8217;utilise des balises <code>h1</code> et <code>h2</code> pour mes titres et je mets toujours des balises <code>alt</code> et <code>title</code> à mes images.<span id="more-287"></span></p>
<h3>Vérifier ce qui est indexé</h3>
<p>Tout d&#8217;abord, pour ceux qui ne sauraient pas comment vérifier le contenu de votre site qui est indexé dans Google, il suffit de faire une recherche avec le nom de domaine de votre site, précédé par <code>site:</code>.</p>
<pre><code>site:www.antoineleclair.ca</code></pre>
<p>En décembre dernier, alors que je n&#8217;avais plus aucune image d&#8217;indexée dans <a href="http://images.google.ca/">Google Images</a>, j&#8217;ai décidé de faire une petite recherche sur le sujet. Il ne semble pas y avoir beaucoup de personnes dans ma situation; qui utilisent WordPress pour publier des images et qui vérifient dans Google Images ce qui est indexé. Mais j&#8217;ai fini par trouver quelqu&#8217;un qui avait fait face au même problème et qui l&#8217;avait surmonté par hasard.</p>
<h3>La solution</h3>
<p>Cette personne (désolé, je n&#8217;ai pas la référence) a installé un plugin qui sert à mettre en cache votre site WordPress. Dans son article, elle parlait du plugin <a href="http://mnm.uib.es/gallir/index.php?s=wp-cache">wp-cache</a>. Après avoir installé ce plugin, les images avaient recommencées à être indexées.</p>
<p>Ce plugin n&#8217;a plus l&#8217;air en développement, mais j&#8217;ai tout de même décidé de l&#8217;essayer. Et voilà, 1-2 mois plus tard, mes images se font indexer et mon trafic a quintuplé.</p>
<p>Si jamais le plugin devenait incompatible avec les futures version de WordPress, je suis aussi tombé sur <a href="http://wordpress.org/extend/plugins/wp-super-cache/">WP Super Cache</a>, qui lui, semble être maintenu. Je n&#8217;ai par contre aucune idée si le résultat sera le même par rapport à l&#8217;indexation des images.</p>
<p>Pour l&#8217;instant, problème réglé! Et j&#8217;ai même un gain théorie en performances.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hooba.ca/blog/2009/mettre-vos-pages-wordpress-en-cache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash pour la page web actuelle avec Rails</title>
		<link>http://www.hooba.ca/blog/2009/flash-pour-la-page-web-actuelle-avec-rails/</link>
		<comments>http://www.hooba.ca/blog/2009/flash-pour-la-page-web-actuelle-avec-rails/#comments</comments>
		<pubDate>Mon, 02 Feb 2009 16:35:45 +0000</pubDate>
		<dc:creator>Antoine Leclair</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.hooba.ca/blog/?p=280</guid>
		<description><![CDATA[Dans Rails, flash est un hash spécial qui est disponible seulement pour le rendu de la page subséquente.
On l&#8217;utilise générallement de cette manière:
flash[:notice] = "Connexion réussie"
redirect_to home_path

flash[:notice] est donc disponible dans le prochain controller et view. Dans le cas où nous ne redirigeons pas, nous voulons générallement que flash soit disponible immédiatement, dans le controller [...]]]></description>
			<content:encoded><![CDATA[<p>Dans <a href="www.rubyonrails.org">Rails</a>, <code>flash</code> est un <em>hash</em> spécial qui est disponible seulement pour le rendu de la page subséquente.</p>
<p>On l&#8217;utilise générallement de cette manière:</p>
<pre><code>flash[:notice] = "Connexion réussie"
redirect_to home_path
</code></pre>
<p><span id="more-280"></span><code>flash[:notice]</code> est donc disponible dans le prochain <em>controller</em> et <em>view</em>. Dans le cas où nous ne redirigeons pas, nous voulons générallement que <code>flash</code> soit disponible immédiatement, dans le <em>controller</em> et <em>view</em> actuel. Il suffit d&#8217;utiliser la méthode <code>now</code>.</p>
<pre><code>flash.now[:notice] = "Connexion réussie"</code></pre>
<h3>Autres méthodes de flash</h3>
<p>Le <em>hash</em> <code>flash</code> contient aussi les méthodes <code>discard</code> et <code>keep</code>, pour éliminer ou conserver <code>flash</code>. L&#8217;utilisation est assez simple, alors je vous laisse lire <a href="http://api.rubyonrails.org/classes/ActionController/Flash/FlashHash.html">la page de documentation</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hooba.ca/blog/2009/flash-pour-la-page-web-actuelle-avec-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
