skip to main | skip to sidebar
Code 18
Manuel du savoir-faire à l'usage des geeks et des curieux
RSS
  • Accueil
  • Le web au Québec
  • Liens
  • Twitter
  • Facebook
  • À propos

samedi 28 février 2009

Débuter avec Smarty

Publié par Infinite Loop, à 11 h 23 1 commentaire

Dans la programmation web, on arrive toujours à un point où le code source HTML se mélange avec le JavaScript et le PHP, donnant comme résultat un gros charabia de code spaghetti. En suivant une approche MVC (model - view - controller), on peut facilement utiliser prototype ou jQuery pour extraire le code JavaScript afin qu'il ne s'entrecroise pas avec le HTML. Mais qu'en est-il du PHP ?

Il existe plusieurs engins de gabarits comme le populaire Smarty ou encore PHPTAL qui peuvent nous donner un coup de main. Souvent, le problème est qu'un intégrateur ou un designer doit apporter quelques ajustements et franchement, il n'en a rien à foutre du code PHP. Sa présence ne fait que complexifier sa compréhension du code source (et les programmeurs ne font pas exception...).

Afin de préserver une bonne ambiance de travail entre les départements, il est sage d'opter pour un engin de templates. Pour moi, ce n'est pas juste un mal nécessaire, c'est aussi une bonne façon de structurer son code et conserver une clareté pour les modifications futures.

J'ai choisi aujourd'hui de vous présenter Smarty. Voici quelques lignes directrices :

  • Après avoir téléchargé le package Smarty, déposez-le sur le serveur (de développement et/ou de production) ou dans votre projet.
  • Localisez le répertoire "libs". Il contient le fichier Smarty.class.php que vous devrez attacher à votre projet.
  • Pour votre première page, vous aurez besoin d'un script php et d'une page .tpl (template). Mon exemple illustrera comment construire l'affichage d'une fiche de musicien avec sa discographie.
demo.tpl

Bien qu'on fasse référence à des variables qui ressemblent à celles du PHP, ce fichier ne contiendra aucun code PHP à exécuter. Il utilisera une syntaxe propre à Smarty qui définit des placeholders, des conditions, des boucles, etc., qu'on reconnaîtra à l'utilisation des accolades.

Par exemple, pour faire apparaître le nom de l'artiste dans une balise HTML, on utilisera la syntaxe suivante. Il est aussi possible d'appliquer un traitement à l'aide d'une des fonctions prédéfinies de Smarty (ici capitalize).
<h3>{$artist}</h3>
<h3>{$artist|capitalize}</h3>
À partir d'une liste d'albums, on effectuera une boucle pour afficher un tableau qui contient sa discographie. On bouclera à partir de l'array associatif $albums qui contiendra les propriétés "title" et "year".

Remarquez l'instruction Smarty "cycle" qui permet de créer l'alternance des couleurs automatiquement.
<table>
<tr>
<td>Album</td>
<td>Année</td>
</tr>
{section name=albums_list loop=$albums}
{strip}
<tr style="background-color:{cycle values="#cecece,#ffffff"}">
<td>{$albums[albums_list].title}</td>
<td>{$albums[albums_list].year}</td>
</tr>
{/strip}
{/section}
</table>
On peut insérer une liste déroulante qui offrira au visiteur de noter son appréciation de l'artiste (de 1 à 5 étoiles). Plutôt que d'utiliser la boucle décrite ci-dessus, Smarty offre la possibilité d'utiliser "html_options", une fonction qui crée dynamiquement les balises "option" pour nous selon les paramètres passés. Nul besoin de faire d'itération. Question de rendre le code plus simple à suivre, j'omets volontairement le code HTML et le formulaire.
<label for="iScore">Score:</label>
<select id="iScore" name="iScore">
{html_options options=$optionsScore selected=$selectedScore}
</select>
Une syntaxe alternative permet de remplir la liste autrement. Notez la différence, d'autant plus que je ne veux pas l'utiliser en même temps que l'autre, je l'ai placée en commentaire.
{*
ce code est en commentaire, il n'apparaîtra pas dans le résultat final
<select id="iScore" name="iScore">
{html_options values=$score_value output=$score_label selected=$selectedScore}
</select>
*}
Selon la moyenne des notes attribuées, on peut faire afficher une mention spéciale :
{if $avgScore >= 4}    
<div>
Cet artiste est très apprécié des auditeurs (moyenne: {$avgScore} / 5)
</div>
{/if}
Finalement, Smarty offre plusieurs fonctions built-in qu'on peut utiliser au sein des gabarits. Affichons la date à laquelle la fiche a été générée (date du jour).
<div>
Généré le {$smarty.now|date_format:"%Y-%m-%d"}
</div>
Comme vous pouvez le constater, le code est très simple et on note l'absence de toute trace de PHP. Maintenant, attaquons nous au PHP qui remplira et affichera le gabarit.

Après avoir instancié un objet Smarty, initialisez-le en assignant les répertoires nécessaires pour exécuter le travail. Pour le moment, j'utiliserai seulement template_dir (là où les gabarits seront stockés).

Fichier PHP
require_once('librairies/Smarty/2.6.22/libs/Smarty.class.php');

$smarty = new Smarty();
$smarty->template_dir='smarty/templates';
$smarty->compile_dir='smarty/compile';
$smarty->cache_dir='smarty/cache';

// assigner une valeur statique au placeholder "artist"
// ($artist dans le fichier .tpl)
$smarty->assign('artist', 'Kaki King');

// alternative 1 pour remplir le select box
$scores = array(1=>'*', 2=>'**', 3=>'***', 4=>'****', 5=>'*****');
$smarty->assign("optionsScore", $scores );
$smarty->assign("selectedScore", 3);

// alternative 2 (commentée)
$smarty->assign("score_value", array(1,2,3,4,5));
$smarty->assign("score_label", array("*", "**", "***", "****", "*****"));
$smarty->assign("selectedScore", 3);

// après avoir calculé la moyenne d'appréciation
// (par exemple à partir d'une base de données),
// assigner la valeur à une variable PHP
$avgScore = 4.27;

// il faut ensuite faire l'association entre la variable PHP
// et la variable Smarty.
// ce n'est pas obligatoire qu'elles portent le même nom
$smarty->assign('avgScore', $avgScore);

// liste des albums (imaginez qu'elle provient de la base de données)
$albums = array(
array('title' => 'Everybody Loves You', 'year' => '2003'),
array('title' => 'Legs to Make Us Longer', 'year' => '2004'),
array('title' => 'Until We Felt Red', 'year' => '2006'),
array('title' => 'Dreaming Of Revenge', 'year' => '2008')
);

// assigner les albums. Smarty s'occupera de boucler!
$smarty->assign('albums', $albums);

// afficher le tout
$smarty->display('demo.tpl');
Mon exemple est relativement simple, l'objectif étant de faire une introduction rapide à Smarty, mais ce qu'on peut en tirer est évidemment beaucoup plus vaste. Même si on ajoute un niveau de complexité, on devra avouer que le code est plus propre, plus simple à lire et à maintenir et qu'en bout de ligne, ça ne demande pas beaucoup d'efforts supplémentaires, juste un peu de rigueur. Si j'ai réussi à piquer votre curiosité et que vous souhaitez continuer à expérimenter Smarty, vous pourrez suivre la trace de ce qui se passe en activant la propriété de déboggage suite à l'instanciation de l'objet : $smarty->debugging = true;


Tags: PHP

vendredi 27 février 2009

Excuses de programmeurs

Publié par Infinite Loop, à 19 h 04 2 commentaires

Question de bien terminer la semaine et de faire un peu d'auto-dérision, j'ai retrouvé une liste qui circulait sur le web qui répertorie les 20 excuses les plus populaires que donnent les programmeurs quand on leur rapporte un bogue.

  1. C'est étrange...
  2. Ca n'avait jamais fait ça avant
  3. Ça marchait hier
  4. Comment est-ce possible ?
  5. C'est sûrement un problème matériel
  6. Qu'est-ce que tu as fait de mal pour que ça plante ?
  7. Il doit y avoir quelque chose dans tes données
  8. Je n'ai pas touché à ce module depuis des semaines !
  9. Tu ne dois pas avoir la bonne version
  10. Ce n'est qu'une malheureuse coïncidence
  11. Je ne peux pas tout tester !
  12. CECI ne peut pas être la raison de CA
  13. Ça marche mais ça n'a pas encore été testé
  14. Quelqu'un a dû toucher à mon code
  15. As-tu vérifié qu'il n'y a pas de virus sur ton système ?
  16. Même si ça ne marche pas, qu'est ce que tu en penses ?
  17. Tu ne peux pas utiliser cette version sur ton système
  18. Pourquoi voulez-vous absolument faire ça comme ça ?
  19. Où étiez-vous quand le programme a planté ?
  20. Ça marche sur ma machine
Et en extra, je rajouterais la préférée des développeurs web :
  • C'est la faute à Internet Explorer
Quoi que pour une fois, c'est un peu vrai...


Tags: Citations

jeudi 26 février 2009

Ajouter les numéros de lignes dans du code source

Publié par Infinite Loop, à 20 h 59 0 commentaire

Cet après-midi, je travaillais à commenter du code source dans un document et je devais faire référence aux numéros de lignes pour les expliquer point par point. Cependant, le code source n'en contenait pas (normalement c'est l'éditeur qui les ajoute en marge) et je voulais éviter de placer un imprimé d'écran car je voulais que texte puisse être sélectionné facilement.

Pour y arriver, j'ai utilisé une fonctionnalité de TextPad, un éditeur texte très puissant. Parmi la foule de fonctions qu'il offre, il y en a une qui permet de faire du remplacement à partir d'une expression régulière (fonction disponible dans plusieurs éditeurs) et de façon plus spécifique, d'insérer un numéro séquentiel à l'endroit indiqué.

Par exemple, en utilisant le caret "^" pour identifier le début de ligne, on pourra utiliser l'expression \i pour créer la séquence. Sans paramètre additionnel, elle débutera à 1. Sinon, on pourra faire suivre entre parenthèses le nombre de départ, suivi du saut d'incrémentation (qui peut aussi être négatif). Pour s'assurer que le code est indenté correctement par rapport aux numéros de lignes, j'y ajoute une tabulation.

  • Appuyez sur F8 (ou Menu Search / Replace)
  • Find what : ^
  • Replace with : \i\t
  • Cliquez sur le bouton Replace all
Au autre éditeur que j'utilise souvent, NotePad++ (gratuit), possède une fonction similaire mais elle n'est pas aussi flexible. Par exemple, à partir du menu TextFX / Tools / Insert Line Numbers, une numérotation du style "00000001" s'ajoute automatiquement en début de ligne, sans possibilité de contrôler le nombre de départ ou le saut. En deuxième lieu, on doit procéder à un remplacement de "^00000" par une chaîne vide (par regexp) pour obtenir un résultat qui s'y rapproche (001, 002, 003...) ou utiliser une regexp comme ^0+ pour retirer tous les zéros qui précèdent.

Sinon, NotePad++ peut aussi insérer des numéros incrémentiels, mais il n'est pas encore aussi paufiné que TextPad. Pour y accéder, il faudra aussi utiliser le plugin TextFX / Edit / Insert (Clipboard) through line. Avant d'exécuter cette commande, vous devrez écrire le pattern et le copier au presse-papier. Il sera utilisé pour effectuer le remplacement. Tapez le symbole dièse (#), suivi de nombre de départ et du saut (#1+1 = départ à 1 + saut de 1). Par défaut, # seul suffit pour indiquer une racine de 0 avec une incrémentation de 1. Entrez le pattern, sélectionnez-le et copiez-le (CTRL+C). Ensuite, sélectionnez les lignes où appliquer ce traitement et exécutez la commande "Insert (Clipboard) through line" à partir du menu. Vous remarquerez que le numéro de ligne sera collé sur le code. Pour le séparer, on devra faire un remplacement avec une regexp du genre "^([0-9]+)" qu'on remplacera par "\1\t" (premier pattern trouvé, suivi d'une tabulation).

Toutes ces étapes peuvent être évitées si vous utilisez TextPad. Contrairement à NotePad++, il n'est pas gratuit (30$ US) mais il a l'avantage de posséder ce genre de petits atouts. Si vous êtes programmeur, assurez-vous au moins d'utiliser un ou l'autre.


Tags: Coffre à outils

mercredi 25 février 2009

12 étapes vers un meilleur code ?

Publié par Infinite Loop, à 19 h 08 0 commentaire

Samedi dernier, j'ai glissé un mot sur un test en 12 points simples et peu rigoureux proposé par Joel Spolsky pour évaluer la qualité d'une équipe de développement. Voici la traduction des questions tirée de l'article The Joel Test (paru sur son site web et dans son livre Joel on Software) ainsi que mes commentaires.

Étant un ancien chef de projet pour Excel, il affirme que Microsoft obtiendrait un pointage de 12/12 sur cette liste alors que la majorité des entreprises se situeraient entre 2 et 3. Je me suis amusé à faire le test pour l'entreprise où je travaille et en toute franchise, notre score serait quelque part autour de 5. Évidemment, cette liste a été pensée originalement pour le domaine du logiciel et n'est pas 100% applicable au développement web.

  1. Utilisez-vous un système de gestion de code source ?

    Nous utilisons un logiciel de contrôle de versions de code depuis plusieurs années, que ce soit VSS ou SVN. C'est indispensable, peu importe le type de programmation.

  2. Pouvez-vous faire un build en une seule étape ?

    Dans le langage PHP, le concept de build ne n'applique pas comme ce serait le cas avec du code compilé. Par contre, nous avons créé des outils qui nous permettent de générer automatiquement certains processus (structure, gabarits, etc).

  3. Faites-vous des builds quotidiens ?

    Nous développons des sites et des applications web. Voulez-vous vraiment télécharger la démo de notre site ?

  4. Avez-vous une base de données de bugs ?

    Nous avons mis en place un système de suivi sur les bogues. Les bogues ne sont pas attribués aux programmeurs, ils appartiennent à l'entreprise. Alors la proactivité est encouragée quand vient le temps de les corriger.

  5. Corrigez-vous vos bugs avant d'écrire du nouveau code ?

    Nous corrigeons les bogues dès qu'ils apparaissent (autant que possible!). En fait, nos programmeurs ne créent pas de bogues, nous laissons ça aux autres entreprises :-)

  6. Avez-vous un planning à jour ?

    Une planning plus ou moins concret est effectué à chaque semaine. Comme les PME du web sont souvent appelées à porter plusieurs chapeaux, les entreprises comme la nôtre peuvent parfois ressembler davantage à une boîte de communications. On doit être disponible pour les clients en tout temps, ce qui rend difficile la planification hebdomadaire.

  7. Avez-vous une spec ?

    Des spécifications de base existent pour chaque projet mais la documentation est souvent la laissée pour compte. Les sites web ont une durée de vie limitée alors on y passe peu de temps, tandis que pour les applications web, on y met plus de rigueur.

  8. Les programmeurs bénéficient-ils d'un environnement de travail calme ?

    Environnement de travail calme ? Je n'ai jamais vu ça dans le web! Les entreprises ont tendance à s'installer dans des studios ou des locaux ouverts, sans cubicule. Ça crée une dynamique intéressante pour l'équipe mais on doit se cacher sous des écouteurs pour retrouver le calme et "entrer dans la zone"...

  9. Utilisez-vous les meilleurs outils que vous puissiez vous payer ?

    Mon employeur a vite compris qu'un employé bien outillé est un employé plus performant.

  10. Avez-vous des testeurs ?

    À mon avis, à partir du moment qu'une entreprise atteint une vingtaine d'employés, on peut commencer à penser à engager un testeur à temps plein. Sinon, chaque programmeur est responsable de la qualité de son propre code. Un programmeur sénior devrait avoir comme responsabilité de vérifier le code des stagiaires ou des juniors.

  11. Les candidats écrivent-ils du code pendant leur entretien d'embauche ?

    Je n'aimerais pas être dans les souliers du candidat qui passe un entretien d'embauche chez nous. Nous sommes assez sélectifs.

  12. Faites-vous des tests d'utilisabilité de couloir ?

    Nous n'avons pas de couloir. Sans blague, nous n'effectuons pas de genre de tests car nous avons des spécialistes en ergonomie expérimentés et nous recevons régulièrement des félicitations des clients à ce sujet.
Comme le dit M.Spolsky lui-même, ça vaut ce que ça vaut. Mais c'est un point de vue intéressant.


Tags: Le coin du geek

mardi 24 février 2009

Décompiler un fichier d'aide CHM

Publié par Infinite Loop, à 19 h 30 0 commentaire

Les fichiers qui portent une extension CHM sont des documents d'aide Windows construits à partir de pages HTML compilées en un fichier unique. Les fichiers CHM (Compiled HTML) sont très communs puisque c'est généralement le standard utilisé pour offrir de l'aide dans les applications Windows.

Aussi, il n'est pas rare de voir des livres électroniques (eBooks) sous ce format, même si le PDF est plus courant. Par exemple, si vous en téléchargez un sur le site FreeBookSpot (plusieurs sujets de programmation disponibles!), vous pourrez le consulter à l'aide de l'application Microsoft HTML Help. Ou peut-être préférerez-vous le décompresser en HTML pour le placer comme documentation sur votre réseau local ou sur votre serveur web ?

Si c'est le cas, hh.exe (Microsoft Windows Help Utility) est l'utilitaire à utiliser (à ma connaissance, il est installé par défaut dans XP). À partir de l'interpréteur de commandes, lancez la ligne suivante en spécifiant en premier le répertoire où déposer les fichiers décompressés, suivi de l'emplacement du fichier HTML compilé.

hh.exe -decompile c:\output\ c:\document.chm

Comme résultat : l'ensemble des fichiers HTML, images, etc, ainsi qu'un fichier .hhc (HTML Help Compiler). Celui-ci est l'équivalent d'une table des matières et indique la façon de construire le fichier CHM.

Mise en garde à propos des fichiers CHM sur Windows

Saviez-vous qu'en ouvrant un fichier CHM avec Microsoft HTML Help (l'application par défaut), vous ouvrez une instance d'Internet Explorer pour interpréter la source ? Donc il y a un risque potentiel pour la sécurité. Pour naviguer sur Internet à partir d'un fichier d'aide, cliquez sur l'icône avec le point d'exclamation jaune dans le coin supérieur gauche de l'application (au dessus du menu). Choisissez "Jump to URL" et entrez l'URL de votre moteur de recherche préféré. Très rapidement, j'ai trouvé un site qui permettait d'afficher les headers HTTP du fureteur utilisé. Sans surprise, c'était indiqué MSIE 7.0.


Tags: Coffre à outils, Sécurité

lundi 23 février 2009

Équivalences prototype vs jQuery

Publié par Infinite Loop, à 19 h 11 0 commentaire

J'adore travailler avec la librairie JavaScript prototype, mais force est de constater que le framework semble à l'abandon. La dernière version (1.6) remonte à novembre 2007 et mis à part quelques corrections mineures effectuées lors du release 1.6.0.3 (septembre 2008), il n'y a plus aucune trace d'innovations.

C'est pourquoi j'ai décidé de me tourner vers jQuery, une librairie plus légère et performante que son prédécesseur. Des effets visuels sont aussi disponibles, sans faire appel à des librairies externes comme le fait prototype avec scriptaculous.

À titre de référence, voici une liste rapide de certaines équivalences entre les deux librairies :

1. Initialisation au chargement de la page

// prototype
Event.observe(window, 'load', onLoadFunction );
// ou
document.observe('dom:loaded', onLoadFunction );

// jQuery
$(document).ready( onLoadFunction );
2. Attacher une fonction à un événement
// prototype
Event.observe('buttonId', 'click',
function() {
// implement...
}
);

// jQuery
$('#buttonId').click(
function() {
// implement...
}
);
jQuery possède plusieurs événements, dont blur, change, click, dblclick, focus, keydown, keypress, load, submit, unload...

3. Cacher / Montrer un élément
// prototype
$('divId').show();
$('divId').hide();

// jQuery
$('#divId').show();
$('#divId').hide();
4. Mettre à jour le contenu HTML
// prototype
$('divId').update('Lorem ipsum dolor sit amet...');

// jQuery
$('#divId').html('consectetur adipiscing elit');
5. Effets visuels
// prototype, à l'aide de script.aculo.us
Effect.SlideUp('divId');

// jQuery
$('#divId').slideUp("slow");
6. Avorter un événement
// prototype
Event.stop(e)

// jQuery
e.preventDefault();
7. Ajouter une classe CSS
// prototype
$('a').addClassName('link');

// jQuery
$('a').addClass('link');
Chaînabilité

Toutes les fonctions jQuery ont aussi l'avantage de toujours retourner un objet jQuery, donc on peut enchaîner les appels sans problème :
$('#links').find('a.external').addClass('fooclass');
Utiliser jQuery en même temps que prototype

Vous voulez utiliser jQuery simultanément à une autre librairie JavaScript ? Il suffit d'activer le mode sans conflits :
jQuery.noConflict();
jQuery('#divName').hide();

ou

// créer une référence dans une variable
$j = jQuery.noConflict();
$j('#divName').hide();
Et finalement, tout comme prototype, jQuery peut aussi construire des requêtes AJAX. Mais j'en ferai le sujet d'une autre chronique prochainement.


Tags: JavaScript

dimanche 22 février 2009

Afficher une date en français avec PHP

Publié par Infinite Loop, à 13 h 32 3 commentaires

Ce n'est pas la première fois que je vois des programmeurs utiliser un array pour définir le nom des mois ou des jours dans une langue d'affichage donnée. Le principe est presque trop simple : on place à l'indice 1 du tableau le nom du premier mois de l'année (Janvier) et ainsi de suite.

$months[1] = 'Janvier';
// ...
$months[12] = 'Décembre';
On peut alors extraire la portion qui représente le numéro du mois dans une date (2009-04-01) et se référer à l'indice du tableau pour obtenir le nom du mois.

Mais savez-vous qu'on peut configurer la localisation de PHP pour faire afficher une date en format texte dans la langue désirée ? Alors au lieu d'écrire du code pour rien, tirons-en profit.

D'abord, il faut configurer la localisation :
header('Content-type: text/html; charset=UTF-8') ;
date_default_timezone_set('America/Montreal');

// PHP Linux
setlocale(LC_ALL, 'fr_CA');

// PHP Windows
setlocale(LC_ALL, 'frc');
// ou
setlocale(LC_ALL, 'french-canadian');
Sur Windows, le nom de la locale diffère de celui pour Linux. Il faut donc le configurer selon l'environnement de production sur lequel le script s'exécutera. Référez-vous à la liste des langues de la documentation des librairies C++ sur MSDN.

Ensuite, on utilise la fonction PHP strftime() qui fait toute la magie pour nous.
$mydate = '2009-04-01';

// format "mercredi, 1 avril 2009"
$dt = strftime("%A, %e %B %Y", strtotime($mydate));

// convertir les accents (pour encodage UTF-8)
$dt = mb_convert_encoding($dt, 'utf-8');
echo $dt;
À cause de la librairie C++ de Windows, le paramètre de format %e ne fonctionnera pas. On devra se rabattre sur %d (Windows seulement) pour faire afficher le numéro du jour avec un zéro devant les neuf premiers jours du mois (01 avril plutôt que 1 avril).

Pour une raison qui m'échappe, l'affichage textuel de la date en anglais place des lettres capitales pour chaque mot alors qu'en français, tout est en minuscule. On pourra y remédier avec la fonction ucwords().
// mercredi, 1 avril 2009 => Mercredi, 1 Avril 2009
echo ucwords($dt);
Zend Framework

Comme nous avons vu et compris la mécanique qui s'opère en PHP pur, il faut maintenant savoir que le ZF offre des classes pour faire exactement la même chose en orienté objet.
require_once('Zend/Locale.php');
require_once('Zend/Date.php');

header('Content-type: text/html; charset=UTF-8') ;
date_default_timezone_set('America/Montreal');

$locale = new Zend_Locale('fr_CA');

// utiliser le format de date PHP
Zend_Date::setOptions(array('format_type' => 'php'));

$mydate = '2009-04-01';
$date = new Zend_Date($mydate, Zend_Date::ISO_8601);
$dt = $date->toString('l, j F Y', $locale);
echo ucwords($dt);
Ici, le format du jour sera automatiquement corrigé (01 avril => 1 avril) pour le PHP Windows.


Tags: PHP

Citation no. 18 sur la relation de couple

Publié par Infinite Loop, à 08 h 39 0 commentaire

On explique souvent les relations de couple en utilisant des dictons qui ne veulent rien dire :

  • Qui se ressemble s'assemble
  • Les contraires s'attirent
Tant que chaque torchon trouve sa guenille, tout le monde sera heureux!


Tags: Citations

samedi 21 février 2009

Comparer des versions de fichiers

Publié par Infinite Loop, à 15 h 32 0 commentaire

Dans le premier tome de la série de livres du blogueur Joel Spolsky, l'auteur présente un chapitre qui s'intitule "The Joel Test : 12 steps to better code" (aussi disponible sur le web) qui décrit un test en douze points pour évaluer la qualité de l'équipe de développement de logiciels. Le premier point mentionne l'utilisation d'un système de contrôle de sources comme CVS ou Subversion (souvent abrégé sous le nom SVN). Je suis d'accord avec lui, c'est un outil indispensable, peu importe si on fait parti d'une équipe ou si on est le seul développeur à travailler sur un projet.

Principalement conçu pour pouvoir conserver des copies de versions de fichiers, ce genre d'outil permet aussi de comparer les différentes versions sauvegardées dans le temps et de fusionner deux copies de travail (deux programmeurs qui développent sur un même projet en même temps).

Avec SVN, on peut appeler l'outil "svn diff" par l'invite de commande pour comparer deux documents textes et en sortir un rapport des différences (ligne par ligne). Cependant, au moins un des deux documents doit être versionné pour que ça fonctionne, c'est-à-dire qu'il doit faire parti du repository (base de données centrale où sont stockées les projets et les versions de fichiers).

Comme alternatives, voici deux solutions possibles :

  • si on est sur Linux ou si on a UnxUtils d'installé sur sa machine Windows, on pourra utiliser la commande "diff" (à ne pas confondre avec "svn diff")
  • si on est sur Windows, on peut installer l'interface graphique TortoiseSVN pour gérer les commandes Subversion directement à partir de l'explorateur Windows (menu contextuel)
Au lieu de voir le rapport de différences en mode console, Tortoise permet de comparer visuellement les documents en les juxtaposant et en surlignant les lignes ajoutées, retirées ou qui présentent des disparités. On peut aussi faire défiler les documents au même rythme pour les consulter et les comparer plus facilement.

Il a l'avantage de pouvoir comparer n'importe quels fichiers (indépendants ou versionnés), donc on peut tout simplement sélectionner les deux documents, cliquer sur le bouton droit de la souris pour faire apparaître le menu contextuel, choisir TortoiseSVN / Diff.

Parlant de systèmes de contrôle de sources, j'en profite pour vous introduire à Git, un outil initialement développé par Linus Torvalds lors du développement du kernel Linux. Il paraît qu'il est efficace et axé sur la rapidité.

En passant, Subversion, TortoiseSVN et Git sont tous des produits gratuits et fiables avec un très haut taux d'adoption. De quoi reléguer Microsoft Visual SourceSafe aux oubliettes...


Tags: Coffre à outils

vendredi 20 février 2009

Apprendre le Zend Framework

Publié par Infinite Loop, à 18 h 38 0 commentaire

Depuis le lancement de la version 1.0 du Zend Framework en 2007, la librairie n'a pas cessée d'évoluer. De nombreuses classes sont apparues, la possibilité de faire du MVC (Model - View - Controller) a fait son chemin, et ses possibilités toujours grandissantes ont rendu plus difficile son apprentissage et son intégration. Quand j'y pense, j'ai arrêté de compter combien de versions mineures et de patches sont sorties dans les derniers mois, de quoi en perdre le fil.

Voici quelques bonnes sources d'informations pour bien débuter avec le ZF et l'exploiter à son plein potentiel :

Documentation officielle du Zend Framework
Aussi disponible en format PDF pour téléchargement (inscription requise et gratuite)

  • Introduction et démarrage facile avec MVC
  • Traductions en 6 langues
  • ZF Programmers Reference Guide
Sinon, un bon livre publié en décembre 2008 par Manning Publications est Zend Framework in Action. L'auteur, Rob Allen, a aussi rendu disponible un tutoriels pour ZF sur son site Akra's DevNotes. Jetez-y un oeil. Uune traduction française de l'article "Débuter avec Zend Framework 1.5 (approche MVC)" a été rendue possible grâce à Guillaume Rossolini.

Si vous aimez apprendre par l'exemple, vous pouvez aussi suivre un tutoriel de construction de blogue avec Zend Framework.

Finalement, du côté des références gratuites, Pádraic Brady a créé un livre électronique distribué gratuitement en format PDF (eBook) qui s'intitule Surviving the Deep End. Vous êtes aussi encouragés à saluer son initiative en laissant un petit don, chose que je ne manquerai pas de faire.


Tags: PHP, Zend Framework

jeudi 19 février 2009

The Pragmatic Programmer

Publié par Infinite Loop, à 20 h 28 2 commentaires

Ça fait longtemps que j'aurais dû glisser un mot sur un livre que j'ai lu il y a très longtemps et qui m'a été incroyablement utile lorsque j'en étais à mes débuts dans le monde de la programmation. Pour quelqu'un qui ne souhaite pas mieux qu'apprendre, le livre The Pragmatic Programmer peut rapidement devenir une référence pratique pour guider nos choix à travers différents aspects de la programmation (sans être relié à aucun langage particulier).

Écrit au tournant des années 2000 par Andrew Hunt et David Thomas, The Pragmatic Programmer, From Journeyman to Master (publié chez Addison-Wesley) est rapidement devenu un incontournable de la littérature informatique. D'ailleurs, près de 10 ans après sa sortie, il se classe encore dans les meilleures ventes d'Amazon et ce n'est pas rare de le retrouver dans le top 5 des meilleurs livres pour programmeurs (tous types confondus).

Souvent comparé à Code Complete (1000 pages, Microsoft Press), il a l'avantage d'être plus concis (350 pages), plus efficace et d'aller droit au but. Des exemples concrets et des anecdotes viennent appuyer les propos, ce qui le rend plus stimulant à lire qu'une grosse brique technique.

On y trouve aussi des conseils et une liste de bonnes pratiques liées au développement professionnel d'applications, une source de référence pour des outils qui simplifieront notre travail, la description de notions fondamentales et plusieurs exercices avec les réponses commentées. À la fin, un aide-mémoire répertorie les 70 conseils décrits au sein du livre.

Son succès a été tel qu'il a donné suite à une collection de livres publiés sous le nom "Pragmatic Bookshelf". Mais celui-ci est définitivement l'incontournable du lot. Même si je compte maintenant plusieurs années d'expérience à mon actif, il m'arrive à l'occasion de réviser certains concepts et de les donner en exemples à des stagiaires ou des programmeurs junior. Parfois, lire un passage permet de mieux expliquer la situation que d'essayer de trouver les mots justes.

Si vous êtes encore à l'école ou que vous avez gradué récemment et que vous aspirez à devenir un professionnel des technologies de l'information, vous devez faire votre devoir et lire ce bouquin. Je suis certain qu'il vous sera aussi utile qu'il me l'a été.


Tags: Livres

mercredi 18 février 2009

Lecture un fichier séquentiel avec Perl

Publié par Infinite Loop, à 21 h 03 0 commentaire

En Perl, c'est fréquent d'avoir à manipuler des fichiers textes. Une des premières choses à apprendre est l'ouverture d'un fichier et sa lecture séquentielle, c'est-à-dire ligne par ligne. Comme il y a plusieurs façons de faire, en voici trois variantes.

1. Boucle while

open(FILE_HANDLE_1, 'lyrics.lrc') ||
die ('Ouverture du fichier impossible');

while ($one_line = <FILE_HANDLE_1>) {
chomp($one_line);

if ($one_line ne '') {
# do something...
push(@lines, $one_line);
}
}

close(FILE_HANDLE_1);
Notions à retenir :
  • FILE_HANDLE_1 représente le nom donné à un file handler qui permet la manipulation d'un fichier. On pourra se référer à ce nom par la suite.
  • À l'ouverture du fichier, si la commande échoue, on utilisera l'opérateur || pour indiquer l'instruction alternative à exécuter.
  • Effectuer une boucle pour chaque ligne trouvée dans le fichier.
  • La fonction chomp() permet de supprimer le saut de ligne à la fin de la chaîne de caractère.
  • L'opérateur "ne" (not equal) est utilisé pour comparer des chaînes de caractères. On s'assure ici que la ligne n'est pas vide.
  • On peut ensuite ajouter à l'array @lines chaque ligne lue.
  • On termine en fermant le fichier.
2. Boucle foreach avec $_

On peut aussi utiliser un raccourci en attribuant automatiquement le file handler à une variable de type array, où chaque ligne deviendra un élément de la liste. L'objectif est atteint grâce aux deux lignes suivantes :
open(FILE_HANDLE_2, 'lyrics.lrc') ||
die ('Ouverture du fichier impossible');
@lines = <FILE_HANDLE_2>;
Par contre, si on veut effectuer un traitement sur les lignes, on devra procéder à une itération sur chaque élément de la liste.
foreach (@lines) {
# ici, chaque ligne dans @lines se termine
# par un saut de ligne

# $_ est la valeur courante de l'itération
# dans la boucle
chomp($_);
if ($_ ne '') {
print $_ . "\n";
}
}
Commentaires sur le code :
  • En Perl, la variable $_ représente l'input par défaut lorsque la variable n'est pas explicitement déclarée (voir troisième exemple).
  • Le symbole # permet de mettre une ligne en commentaire.
3. Boucle foreach avec variable nommée

Dans une boucle foreach, si on préfère nommer la variable explicitement plutôt que d'utiliser $_, on peut le faire comme ceci :
foreach $one_line (@lines) {

# à la place de :

foreach (@lines) {
C'est aussi simple que ça.

Justement, j'en profite pour faire un retour sur ce que j'écrivais hier concernant les ressemblances entre PHP et Perl. Ce dernier a transmis en héritage deux autres points que je n'avais pas mentionné :
  • L'opérateur de concaténation est le point .
  • La fonction die() pour lancer un message d'exception et terminer le programme


Tags: Perl

mardi 17 février 2009

Variables de Perl et de PHP

Publié par Infinite Loop, à 20 h 08 0 commentaire

Quand on regarde l'historique du PHP, on remarque que le langage était à l'origine une collection de scripts PERL (Practical Extraction and Report Language... ou comme certains s'amusent à le nommer : Pathetically Eclectic Rubbish Lister) regroupés sous le nom PHP (Personal Home Page Tools). Il n'est pas surprenant que le PHP en ait conservé des traces dans son évolution.

Le choix du symbole $ pour préfixer les noms de variables constitue l'exemple le plus évident. Contraîtrement au Perl, PHP utilise ce symbole pour tous les types de variables, sans distinction. Dans le Perl, ce qu'il y a d'original est qu'une variable est préfixée d'un symbole différent selon le type.

$ est utilisé pour les variables scalaires:

$number = 100;
$string = "Code 18";
$pi = 3.141592;

@ représente les variables de type liste (array) indexés par un nombre:

@levels = ("Sysadmin", "Manager", "User");

//
$levels[0] correspond à Sysadmin

% est réservé aux tableaux associatifs indexés par des clés textuelles (hash):

%config = (
type = "pgsql",
host => "localhost",
database => "postgres",
username => "myuser",
password => "*****"
);

// $config['type'] aura comme valeur "pgsql"

Une particularité intéressante à Perl est qu'à la lecture du code, on a une bonne idée de ce que peuvent contenir les variables puisqu'elles sont en parties typées, contrairement à PHP qui n'est pas strict du tout.

Un autre point important à noter est que des variables de types différents peuvent porter le même nom :

$list = "1,2,3";
@list = (1,2,3);
%list = ("a" => 1, "b" => 2, "c", 3);

Pour en revenir à l'héritage qu'à légué Perl à PHP, on remarquera que la syntaxe suivante est valide dans les deux langages :

$firstname = 'code 18';

// placer une variable à l'intérieur d'une chaîne de caractères
$str = "Mon nom est $firstname.";
echo $str;


Simple constatation :-)

J'ai assisté à plusieurs débats où les participants argumentaient en faveur de leur langage préféré. Les similitudes sont nombreuses et chose certaine, les deux langages sont excessivement puissants. La syntaxe du Perl est certainement la plus archaïque, mais mon avis est que Perl excellee dans l'adminstration de systèmes tandis que PHP se surpasse dans le domaine du web. Il suffit de choisir le bon outil pour faire le bon travail. À chacun sa spécialité...


Tags: Perl, PHP

lundi 16 février 2009

Redimensionner une image avec GD

Publié par Infinite Loop, à 20 h 51 0 commentaire

Avec PHP, redimensionner une image pour en faire un thumbnail (image timbre, vignette... nommez-le comme vous voulez!) est un jeu d'enfant. Il suffit d'avoir accès à la librairie graphique GD qui permet de générer et de manipuler les images de façon avancée.

Pour montrer à quel point c'est simple, les quelques lignes de code suivantes permettent de prendre une image et de la réduire à 25% de sa taille d'origine. Aussi, je commenterai étape par étape ce qui se passe.

Afin de faciliter la lecture, je définis une variable indiquant le chemin de l'image source et une autre pour spécifier à quel endroit et sous quel nom on enregistrera le thumbnail.

$source_file = 'images/image.jpg';
$output_file = 'images/thumb.image.jpg';
Ensuite, on récupère la taille de l'image source et on calcule la largeur et la hauteur de la nouvelle image à créer.
list($src_width, $src_height) = getimagesize($source_file);

$percent = 0.25; // 25%
$thumb_width = $src_width * $percent;
$thumb_height = $src_height * $percent;
Pour procéder à la redimension, on doit d'abord créer un canevas d'image pour y accueillir les données. Ce canevas sera créé à l'aide de la fonction imagecreatetruecolor().
$img_destination = imagecreatetruecolor($thumb_width, $thumb_height);
On récupère la source de l'image pour pouvoir la manipuler. Dans mon exemple, ce sera un fichier JPEG mais on peut aussi utiliser les fonctions imagecreatefromgif() et imagecreatefrompng() pour travailler avec des images au format GIF et PNG.
$img_source = imagecreatefromjpeg($source_file);
L'appel suivant permet de copier l'image source en totalité ou en partie (représenté par la suite de zéros) et de placer le résultat dans la ressource $img_destination.
imagecopyresampled($img_destination, $img_source, 0, 0, 0, 0, $thumb_width, $thumb_height, $src_width, $src_height);
Avec ce qu'on a récupéré, on est prêt à enregistrer le nouveau fichier. Dans la fonction, le dernier chiffre représente la qualité, 100 étant la valeur maximale. Ici aussi, on pourra y substituer les fonctions imagegif() et imagepng() selon le format. D'ailleurs, c'est à cette étape qu'on pourra passer d'un format à un autre (convertir un JPEG en PNG par exemple).
imagejpeg($img_destination, $output_file, 90);
Et on termine par un nettoyage pour libérer la mémoire allouée.
imagedestroy($img_destination);
imagedestroy($img_source);
Ma dernière recommandation : pour une question de performance, évitez de surexploiter la transformation d'images en direct...


Tags: PHP

dimanche 15 février 2009

Output buffering de PHP

Publié par Infinite Loop, à 11 h 29 0 commentaire

PHP possède un mécanisme qui permet d'intercepter le contenu qui serait normalement envoyé vers la sortie standard et qui le place dans une mémoire tampon pour pouvoir contrôler le flux de sortie. C'est ce qu'on appelle du "output buffering" (OB). Autrement dit, plutôt que d'envoyer le contenu vers le fureteur de l'utilisateur, il est temporairement mis de côté pour qu'on puisse le modifier et choisir à quel moment l'afficher.

À titre d'exemple, on voit souvent cette technique utilisée dans la construction de gabarits (templates) ou le caching de pages. Par exemple, le fichier body.tpl pourrait servir de gabarit où trois placeholders sous forme de commentaires (identificateur unique, prénom et emploi) pourront être remplacés à l'exécution.

body.tpl

<h3>Profil #<!-- ID--></h3><div>
Mon nom est <!-- FirstName --> et je suis <!-- JobTitle -->.
</div>
Pour mieux comprendre ce qui se passe, il faut savoir que le OB est actif à partir du moment qu'on appelle ob_start() et qu'il prend fin à l'appel de ob_end_clean() ou de ob_end_flush(). Toutes les lignes qui se trouveront entre ces deux appels seront assujetties à la mémoire tampon.
// Démarrer la mémoire tampon.
// À partir d'ici, tout ce qui serait normalement envoyé à la sortie standard
// sera conservé temporairement dans la mémoire tampon
ob_start();
Toutes les instructions suivantes enverront leur contenu en sortie vers la mémoire tampon.
// inclure des fichiers externes
include('templates/header.tpl');
include('templates/body.tpl');

// impression de contenu
echo 'Généré le ' . date('Y-m-d H:i:s');

// lecture de fichier
$footerFile = 'templates/footer.tpl';
if (file_exists($footerFile)) {
// envoyé aussi au tampon
readfile($footerFile);
}
À partir d'ici, le tampon est garnit et nous avons deux possibilités :
  1. afficher immédiatement le contenu à l'aide de flush()
  2. récupérer le contenu dans une variable avec ob_get_contents() et y apporter des modifications avant de l'envoyer à la sortie
Nous choisirons la façon qui nous donne le plus de flexibilité.
// récupération de la mémoire tampon dans la variable
$output = ob_get_contents();

// Nous n'avons plus besoin du tampon
// Nettoyer sans envoyer son contenu au fureteur
ob_end_clean();

// remplacer les placeholders
$id = 1000;
$output = str_replace('<!-- ID-->', $id, $output);
$output = str_replace('<!-- FirstName -->', 'Code 18', $output);
$output = str_replace('<!-- JobTitle-->', 'programmeur PHP', $output);
Avec le contenu de la variable $output, on pourrait :

1. Envoyer le contenu directement au fureteur
echo $output;
2. Créer un fichier HTML statique (en supposant que vous avez les permissions d'écriture sur le serveur) :
$file = fopen ("static/profil-$id.html", 'w');
fwrite($file, $output);
fclose($file);
Dans php.ini, vous devrez vous assurer que la variable output_buffering n'a pas la valeur "off". Elle peut soit être à "on" (1), soit à un nombre limité de bytes pour améliorer la performance, par exemple 4096. Comme l'instruction PHP ini_set() ne peut être appelée dans ce contexte, une alternative serait de placer la ligne php_value output_buffering 4096 dans le fichier local .htaccess.


Tags: Apache, PHP

Citation no. 17 sur Linux et Windows

Publié par Infinite Loop, à 08 h 28 0 commentaire

Linux, un noyau; Windows, des pépins.

- Proverbe classique

Pour faire plaisir aux hardcore fans de Linux, Wikipédia définit le mot proverbe comme étant une formule langagière de portée générale contenant une morale ou une vérité d'expérience que l'on juge utile de rappeler...


Tags: Citations

samedi 14 février 2009

Convertir des m4a en mp3

Publié par Infinite Loop, à 12 h 23 0 commentaire

Une amie s'est procuré des fichiers musicaux sans DRM par le iTunes Store (AAC, extension m4a) et elle cherchait à les couvrir à un format non-propriétaire, comme le format mp3. Pour lui donner un coup de main, je lui ai indiqué la marche à suivre que j'ai transcrit ici pour vous.

iTunes 8
Dans iTunes, on doit d'abord accéder au menu Edit, et choisir Preferences. Dans l'onglet General, cliquer sur le bouton "Import Settings". Choisir dans la liste déroulante "Import using Mp3 Encoder" et indiquer la qualité désirée. Cliquer OK.

Dans la liste des pièces, en choisir une ou plusieurs, ouvrir le menu contextuel (bouton droit de la souris) et choisir "Create mp3 version". Un nouveau fichier sera créé pour chaque pièce. Sur Windows XP, si iTunes a été installé dans le répertoire par défaut, ils seront déposés dans C:\Documents and Settings\[user]\My Documents\My Music\iTunes\iTunes Music.

Free Converter par Koyote Soft
Sur Windows, une autre alternative est d'utiliser le gratuiciel (freeware) Free Converter qui peut convertir très rapidement des fichiers m4a en mp3. En fait, ce qui le rend intéressant est sa capacité à prendre à la source des fichiers aac, ac3, ape, flac, m4a, mp3, ogg, wav ou wma et de les transformer dans un des formats suivants : aac, ape, flac, mp3, ogg ou wav.

À l'installation, portez attention aux différentes étapes puisque si vous procédez à l'installation par défaut, vous installerez la Dealio Toolbar sur votre fureteur en plus de changer la recherche par défaut pour Yahoo!. Mieux vaut décocher ces deux cases. L'étape suivante permet de choisir les composants à installer. Pour ses besoins, je n'ai sélectionné que "Free Mp3 Wma Converter - Freeware". L'interface est très simple : glisser les fichiers à convertir, choisir le format de sortie et le tour est joué.
Free Converter est aussi disponible pour téléchargement sur CNET.


Tags: Musique

vendredi 13 février 2009

Configuration de base de TinyMCE

Publié par Infinite Loop, à 18 h 35 1 commentaire

Parmi les éditeurs RTE gratuits, TinyMCE est reconnu pour pouvoir s'installer en utilisant seulement deux lignes de code :

tinyMCE.init({
mode : "textareas",
theme : "simple"
});
Évidemment, il faudra préalablement inclure le script js/tiny_mce/tiny_mce.js pour que ça fonctionne (pour plus d'information, suivre le guide d'installation de TinyMCE). Cet appel perment de convertir toutes les balises <textarea> de la page en éditeur de texte riche WYSIWYG (c'est plutôt drôle, si on veut franciser ce terme, l'Office québécois de la langue française propose le terme tel-tel...). Le thème spécifié permet d'obtenir la barre d'outils la plus minimaliste possible, qui comprend les boutons gras, italique, souligné, barré, annuler (undo), refaire (redo) ainsi que les listes. Ce qui me frappe dans cette version, c'est que les boutons sont positionnés au bas de la boîte d'édition et qu'ils sont centrés, contrairement au modèle plus ergonomique auquel on a été habitué dans tout éditeur de texte (je pense à Word ou OpenOffice). Ce qui force automatiquement le programmeur à utiliser les moyens avancés pour pouvoir personnaliser l'affichage.

La première modification qu'on fera sera de changer le mode pour "exact" afin de pouvoir spécifier les ID des textareas à convertir plutôt que de l'appliquer à tous. On utilisera la clé "elements" pour spécifier la liste en prenant soin de les séparer par une virgule.
tinyMCE.init({
mode : "exact",
theme : "simple",
elements : "description,notes"
});
Pour pouvoir le personnaliser, il sera nécessaire de passer du thème "simple" à "advanced". L'éditeur avancé contient plusieurs boutons supplémentaires qui s'ajouteront automatiquement. De façon optionnelle, chaque bouton peut être ajouté, retiré ou déplacé sur chaque ligne de la barre d'outils. Pour le moment, on se contentera de déplacer les boutons au haut du contrôle et on les alignera à gauche :
tinyMCE.init({
mode : "exact",
theme : "advanced",
elements : "description,notes"
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
});
Optionnellement, on pourra indiquer la hauteur et la largeur du contrôle :
tinyMCE.init({
mode : "exact",
theme : "advanced",
elements : "description,notes"
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
height:"300px",
width:"500px"
});
Jusqu'à maintenant, on a un RTE configuré et fonctionnel mais si vous remarquez bien, l'interface est par défaut en anglais (liste de format, tooltip). Heureusement, la langue est configurable mais pas "built-in" alors on devra faire un téléchargement supplémentaire pour y arriver. Dans la liste des language pack pour TinyMCE, cochez la langue désirée et cliquez sur le bouton "Download" au bas de la page. Le fichier compressé contiendra la même arborescence que dans le répertoire d'installation (dossiers: langs, plugins et themes). Il suffit de prendre chacun des fichiers et de les ajouter aux bons répertoires (un "drag and drop" de chaque dossier devrait suffire à les ajouter). Dans mon cas, je choisirai la langue française.

On terminera l'initialisation en spécifiant la langue à l'aide du code ISO de deux lettres qui peut se trouver dans la liste des codes de langues de Wikipedia ou plus spécifiquement en utilisant le nom du fichier (sans extension) qui se trouve dans le répertoire "langs". Pour le français, le fichier fr.js permet de savoir que le code sera "fr".
tinyMCE.init({
mode : "exact",
theme : "advanced",
elements : "description,notes"
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
height:"300px",
width:"500px",
language : "fr"
});
Maintenant, à votre tour de vous amuser à découvrir les multiples fonctionnalités de TinyMCE. Beaucoup d'autres options de configuration sont possibles et plusieurs extensions sont disponibles (dont un spellchecker, émoticons, édition plein écran, etc).


Tags: JavaScript

jeudi 12 février 2009

RTE gratuits à découvrir

Publié par Infinite Loop, à 19 h 47 0 commentaire

Dans les applications web, c'est devenu courant d'utiliser un contrôle JavaScript de type Rich Text Editor pour remplacer la balise <textarea>. Voici cinq RTE que vous pouvez intégrer gratuitement à vos projets :

TinyMCE, par Moxiecode

FckEditor, maintenant connu sous le nom de CKeditor

Yahoo! Rich Text Editor, de la YUI Library (Yahoo! User Interface)

Dijit.Editor, par Dojo Toolkit

openWYSIWYG, par openWebWare

Même si ces composants sont libres d'utilisation, si vous en intégrez un à un projet commercial (ou si vous jugez qu'il vous a fait sauver beaucoup de temps), n'hésitez pas à montrer votre appréciation en effectuant un petit don pour supporter le projet. Les développeurs apprécieront et tout le monde sera gagnant.


Tags: JavaScript

mercredi 11 février 2009

Manipuler des mesures avec Zend_Measure

Publié par Infinite Loop, à 12 h 59 0 commentaire

Dans un projet PHP, la classe Zend_Measure de Zend Framework peut être pratique pour manipuler des unités de mesures. Dans mon cas, j'utilisais des fonctions personnelles pour, par exemple, faire afficher la taille des fichiers en format textuel (souvent appelé "human readable"). L'avantage d'utiliser celle fournie avec le framework est qu'elle permet aussi de faire des additions entre unités de même type, comparer les valeurs, les convertir et de nommer textuellement l'unité de mesure associée au type utilisé.

Comme un exemple vaut mille mots...

// inclure la classe de localisation
require_once('Zend/Locale.php');

// inclure le type de mesure à utiliser
require_once('Zend/Measure/Binary.php');

// initialiser la locale à utiliser
// ici, français, canadien
$locale = new Zend_Locale('fr_CA');
Si vous ne connaissez pas la locale à utiliser, vous pourrez obtenir la liste complète en exécutant les deux lignes suivantes :
$localelist = Zend_Locale::getLocaleList();
print_r($localelist);
En utilisant filesize(), j'obtiendrai la taille du fichier en bytes que je pourrai convertir en différentes unités (Kb, Mb, Gb).
// obtenir la taille d'un fichier
$file_path = 'files/mp3/Antoine Dufour/Development/01-Development.mp3';
$size_in_bytes = filesize($file_path); // 5351552

$measure = new Zend_Measure_Binary($size_in_bytes, Zend_Measure_Binary::BYTE, $locale);

// Convertir en une autre unité à l'aide d'une constante de classe.
// La précision par défaut est de 2 chiffres après la virgule

// 5.10 MB
echo $measure->convertTo(Zend_Measure_Binary::MEGABYTE);

// sinon, on peut remplacer la constante de classe par le type textuel
// 5226.13 kB
echo $measure->convertTo('KILOBYTE');

// 5.10 MB
echo $measure->convertTo('MEGABYTE');

// indiquer une précision de 4
// 0.0050 GB
echo $measure->convertTo('GIGABYTE', 4);
Une petite chose à porter attention est la notation SI (System International) qui utilise une base 10 plutôt que binaire. Ainsi, 103 donne une unité "kilo" de 1000, tandis qu'en binaire, elle serait en de 1024 (210). Selon ce mode de calcul, ça explique pourquoi ma clé USB de 4 Go peut contenir en réalité approximativement 3.7 Go (idem pour certains disques durs, DVD, etc).
// convertir 4 Go SI en l'équivalent binaire
$measure = new Zend_Measure_Binary(4, 'GIGABYTE_SI', $locale);

// 3.73 GB
echo $measure->convertTo('GIGABYTE');
Malheureusement, malgré l'utilisation de la localisation, la classe ne semble pas encore être en mesure de traduire les unités, qui sont pour le moment restreintes aux abréviations (version 1.7.4 du ZF). J'aurais aimé pouvoir franciser les termes : Kb => Ko, Mb => Mo, Gb => Go, mais pour l'instant, c'est un bon début.

Dans mon exemple, je fais référence à une pièce musicale d'Antoine Dufour, un guitariste québécois exceptionnel qui vaut la peine de découvrir. J'ai eu la chance de le voir performer dans une salle très intime à St-Jean-de-Matha il y a quelques années (même que parmi les ~40 spectateurs présents, j'ai cru reconnaître Yves Lambert, anciennement de la Bottine Souriante). Avec trois albums à son actif, il partage aussi la vedette sur DVD avec Andy McKee, au autre guitariste talentueux.


Tags: PHP

mardi 10 février 2009

Monty Python influence l'informatique

Publié par Infinite Loop, à 19 h 41 0 commentaire

La troupe de comique anglaise Monty Python, qui connut son moment de gloire dans les années 70, a eu malgré elle une influence culturelle sur l'univers de l'informatique.

En effet, le mot Spam, terme désormais célèbre pour faire référence aux courriels commerciaux non-sollicités, tirerait son nom d'un sketch du groupe, où le Spam était un ingrédient se trouvant dans pratiquement tous les plats offerts par un restaurant. Tout comme les pourriels, sa présence était visiblement indésirable. À l'origine, le SPAM était un pâté de viande se vendant en boîte dont son nom était formé d'une contraction des mots SPiced hAM (jambon épicé). Et c'est toujours disponible à votre marché d'alimentation préféré.

Une autre influence est à l'origine du choix de nom du langage de programmation Python. D'ailleurs, un des objectifs principaux du langage est de rendre son utilisation amusante. C'est pourquoi on voit souvent des exemples et des tutoriels avec des références obscures à Monty Python.

Pour une brève introduction à leur oeuvre, voici quelques classiques :

  • Le sketch original sur le SPAM de Monty Python
  • Monty Python and the Holy Grail : un film absurde et délirant d'une épopée médiévale
  • My Brain Hurts!
  • Ministry of Silly Walks


Tags: Saviez-vous que

lundi 9 février 2009

Refuser l'accès à certains fichiers avec .htaccess

Publié par Infinite Loop, à 18 h 19 0 commentaire

Récemment, je parlais de l'importance de restreindre l'accès à certains types de fichiers qui pourraient être accessibles par les visiteurs d'un site web. Cela incluait les fichiers .htaccess, .htpasswd, les configurations .ini de Zend_Config ainsi que les bases de données SQLite, pour ne nommer que de ceux-là.

À l'aide d'une instruction FileMatch et d'une expression régulière qu'on place dans le fichier .htaccess d'Apache, on peut facilement y arriver.

Les fichiers débutants par .ht :

<FilesMatch "^\.ht">
Order allow,deny

Deny from all

</FilesMatch>

Les extensions .ini :

<FilesMatch "\.ini$">
Deny from all
</FilesMatch>

Différentes extensions possibles pour SQLite :

<FilesMatch "\.(sqlite|sqlite2|sqlite3|sq|sq2|sq3)$">
Deny from all
</FilesMatch>

En résumé, il faut se rappeler que l'utilisation de cette instruction permet de :

  • cacher les fichiers indiqués de l'index d'un répertoire
  • envoyer un statut HTTP 403 Forbidden si un visiteur tente d'accéder aux fichiers
  • protéger les fichiers importants
  • éviter de laisser glisser des indices qui pourraient compromettre la sécurité


Tags: Apache

dimanche 8 février 2009

Citation no. 16 sur le travail

Publié par Infinite Loop, à 13 h 34 0 commentaire

L'homme n'est pas fait pour travailler, la preuve c'est que cela le fatigue.

- Voltaire


Tags: Citations

Jukebox touchscreen

Publié par Infinite Loop, à 11 h 55 0 commentaire

Étant mélomane, je cherchais un moyen de rendre disponible ma collection mp3 pour remplacer mon système de son conventionnel dans le salon. Avec les années, j'ai converti la totalité de mes CD en format mp3 et depuis environ deux ans, je me procure mes nouveautés musicales en format numérique et en de rares occasions en disque compact.

Oui, j'apprécie encore le bon vieux CD, même s'il tend à disparaître. L'avantage est qu'avec la chute des ventes, le prix du CD avoisine souvent celui du format numérique. De plus, certaines oeuvres possèdent un livret qui est visuellement très artistique qui justifie la différence du prix (les producteurs sont obligés d'en donner plus aux consommateurs pour faire mousser les ventes et contrer le piratage). Et c'est un peu comme un livre : on aura beau trouver pratique le format numérique (eBook) mais il y a un plaisir concret dans la manipulation d'un objet physique. Autant le livre papier que le CD sont aujourd'hui devenus des produits de luxe (et c'est peut-être seulement l'impression de posséder quelque chose de matériel).

Aussi, j'ai toujours préféré posséder un album complet plutôt que des pièces individuelles car je crois qu'il faut savoir découvrir les artistes et ne pas se limiter qu'aux morceaux à succès sur un album. À mes yeux, c'est un peu comme si on lisait un seul chapitre d'un livre pour s'en faire une opinion; ça ne rend pas justice à l'oeuvre et on peut passer à côté de belles découvertes. Sinon, l'autre point en faveur de l'achat CD est que je peux ensuite décider de la qualité de l'encodage et du format numérique qui me plait.

C'est pourquoi j'ai eu l'idée de construire un jukebox numérique à l'aide d'un écran touchscreen. D'abord, j'ai récupéré un vieux boitier et des vieilles pièces d'ordinateur pour monter la base. Selon mon expérience, je recommanderais de considérer trois points importants dans le choix du matériel :

  • un gros disque dur pour qu'il puisse y avoir assez d'espace pour contenir l'ensemble de ma librairie (25000 pièces, 150 Go)
  • plus la librairie est volumineuse, plus le lecteur multimédia est gourmand en mémoire vive
  • un boîtier d'alimentation (power supply) le plus silencieux possible (en général, les ventilateurs internes sont légèrement bruyants)
Au niveau du système d'exploitation, j'ai opté pour Windows car le lecteur multimédia que je comptais utiliser n'était disponique que pour cette plateforme. J'ai installé le strict minimum et j'ai désactivé plusieurs services inutiles à un jukebox. Ensuite, comme je ne voulais pas contrôler le lecteur à l'aide d'un clavier ou d'une souris, je me suis mis à magasiner pour un écran tactile (comme le iPhone, bien qu'au moment de réaliser mon projet, ni le iPhone ni le iPod touch n'étaient sur le marché).

Pour trouver un l'écran tactile, j'ai vérifié chez Microbytes (souvent reconnu pour les meilleurs prix) et il se détaillait aux alentours de 700-800$ CDN. Comme c'était assez dispendieux, j'ai décidé de jeter un oeil aux petites annonces classées pour voir si je pouvais m'en procurer un de seconde main. Comme vous le savez, ce type d'écran est souvent utilisé dans les restaurants pour gérer les commandes et les factures et au rythme où les restaurants ouvrent et ferment, je me disais qu'il devait certainement y avoir un marché pour du matériel usagé. Mais c'est en cherchant sur eBay que j'ai trouvé ce que je voulais.

En fait, il y avait deux marchands qui offraient des écrans touchscreen. Le premier était Dr.Touchscreen, une personne passionnée et plein de bons conseils qui construit, répare et vend des écrans tactiles usagés. Si vous possédez déjà un écran LCD, vous pourrez obtenir de ce vendeur des écrans déjà montés ou encore des kits tactiles serial ou USB de différentes grandeurs que vous pourrez installer vous-même (vous devez ouvrir le boîtier pour y glisser la vitre tactile, donc vous devez être habile). Je le recommande fortement, sans compter que ses prix sont incroyablement bas (50$ pour un kit, moins de 200$ pour un écran tactile).

J'étais sur le point de conclure la transaction quand j'ai déniché un écran tactile 15 po de marque ELO (la plus connue), flambant neuf à 300$ chez un liquidateur de faillite. Exactement celui que vendait Microbytes, pour une fraction du prix! C'était une chance unique qui ne se représenterait pas.

Comme lecteur musical, j'aimais bien iTunes pour son interface visuel et le tape à l'oeil du media flow où on voit les pochettes défiler. Par contre il n'est pas adapté pour la manipulation digitale (les doigts sont trop gros pour pouvoir sélectionner une pièce facilement et on s'accroche inmanquablement un peu partout. Idem pour les menus et les barres de défilement) et comme aucun clavier n'est connecté au jukebox, on ne peut pas faire de recherche. Il me fallait donc chercher pour une application spécialisée pour les écrans tactiles, tant pour l'interface, la facilité d'utilisation et la disponibilité d'un clavier virtuel.

Suite à mes recherches, deux lecteurs ont retenu mon attention : Silverjuke et AlbumPlayer.
  • Silverjuke est un logiciel avec un SDK qui permet de l'adapter au besoin. Je le considère un peu plus comme une application industrielle dans le sens où il possède tout le nécessaire pour le brancher à un système de paiement par jeton. Parmi les fonctions disponibles : gestion des grosses librairies, un karaoké, des effets graphiques, un beau clavier virtuel, la possibilité de barrer l'accès à certaines fonctions en mode plein écran, adapté pour les écrans tactiles et près de 40 thèmes (skins) disponibles. Compatible Mac et PC.
  • AlbumPlayer est plus adapté à une utilisation personnelle. Configuré avec la même collection mp3, il semble plus léger et plus rapide que Silverjuke. Il est très beau visuellement, facile à manipuler et l'affichage des albums et des pièces se fait comme si c'était un CD. AlbumPlayer permet d'être utilisé tant comme lecteur normal (clavier / souris) ou en mode touchscreen. Un clavier virtuel est aussi disponible (beaucoup plus beau que celui de la version précédente) et différentes extensions peuvent être ajoutées : quelques effets, connexion à une télécommande (Media Center Remote), sources de données Last.fm et Wikipedia. Mais celle que je préfère est le screensaver qui peut s'activer et qui présente la pochette de l'album, le nom de l'artiste et de la pièce, dans un affichage très "class". Un seul thème est actuellement disponible, mais la compagnie promet que d'autres seront ajoutés ultérieurement.
Dans les deux cas, ils coûtent exactement le même prix (environ 45$ CDN) et toutes les mises à jour des versions futures sont incluses. Avec la sortie de la version 5 de AlbumPlayer il y a quelques jours, celui-ci l'emporte haut la main tant pour ses fonctionnalités et son look.

Pour terminer, l'avantage d'avoir un jukebox numérique à la maison est de pouvoir faire jouer les morceaux dans n'importe quelle pièce. Ceux qui utilisent un AirPort Express avec iTunes comprendront ce que je veux dire (pour les autres, il s'agit d'une boîte qu'on connecte dans une prise de courant à laquelle on peut brancher des haut-parleurs. Dans iTunes, on peut ensuite choisir dans quelle pièce on fait diffuser la musique). Par défaut, pour utiliser le AirPort Express, on doit nécessairement utiliser iTunes car les autres lecteurs n'offrent pas la compatibilité. Cependant, vous serez heureux d'apprendre qu'il existe une petite application nommée Airfoil (Mac ou Windows), qui permet d'envoyer la sortie audio de n'importe quel lecteur musical vers un récepteur AirPort Express. Dans mon cas, c'est la meilleure configuration que j'ai pu trouver. Ce qui complète ma présentation d'aujourd'hui.


Tags: Le coin du geek, Musique

samedi 7 février 2009

Débuter avec SQLite et PHP

Publié par Infinite Loop, à 10 h 33 0 commentaire

Il y a plusieurs années, je développais un site web PHP que je devais installer chez un hébergeur en Ontario. Je n'avais donc pas le contrôle sur ce qui était installé sur le serveur et chaque service supplémentaire ajouté au forfait d'hébergement requérait un frais d'installation et une récurrence mensuelle pour le client (qui avait un budget assez limité). Le projet nécessitait des besoins modestes au niveau de la base de données et j'avais dû faire le choix le plus économique.

À titre d'exemple, l'option la moins chère qu'offrait l'hébergeur était pour une base de données Access qui coûtait, si je me souviens bien, 25$ de frais d'installation (!) et un frais mensuel de 5 à 10$ (c'était à une époque où on devait louer l'espace d'hébergement au Mo plutôt qu'au Go...). Tout ce que j'avais à faire était de déposer le fichier Access (.mda) par FTP sur un serveur Windows et y accéder avec PHP avec ODBC. MS Access avait été suffisant mais disons que ce n'était pas mon premier choix.

SQLite
Aujourd'hui, si j'avais une décision semblable à prendre, j'opterais probablement pour SQLite. D'abord parce qu'il est installé par défaut avec PHP, ensuite parce qu'il ne nécessite aucune configuration particulière et que la base de données ne roule pas sous la forme client/serveur. Au contraire, elle est directement intégrée au site et est accessible par une librairie de fonctions. Autrement dit, la base de données est conservée dans un fichier unique, hébergé à même le serveur web, un peu comme si je lisais un fichier avec fopen().

Quelques lignes de code
En PHP, on aura accès à SQLite dès que l'extension du même nom est installée (vérifier par phpinfo). Une seule ligne de code permet d'ouvrir la base de données en indiquant le chemin et le nom du fichier. Si le fichier n'existe pas, il sera automatiquement créé. On peut spécifier l'emplacement avec un chemin complet dans le filesystem, sinon il doit être relatif au fichier PHP qui exécute la requête.

// ouverture d'une base de données existante
$db = new SQLiteDatabase('database/config.sqlite');

// une requête simple
$rs = $db->query("SELECT * FROM tablename");

// récupération des résultats
while ($row = $rs->fetch(SQLITE_ASSOC)){
echo $row['colname'] . '
';
}

// mise à jour d'un enregistrement
$db->queryExec("UPDATE tablename SET colname = 'value' WHERE id = 1");
Quelques conseils
  • SQLite 3 ne possède pas encore d'accès protégé par un nom d'usager et un mot de passe
  • On peut accéder à une base de données SQLite avec PDO
  • Il faut faire attention, les fichiers des versions 2 et 3 ne sont pas compatibles entre eux
  • N'oubliez pas de protéger l'accès au fichier SQLite, par exemple à partir du fichier .htaccess
  • L'extension pour Firefox SQLite Manager permet d'ouvrir et de gérer les bases de données
  • Quelques grands noms qui utilisent SQLite : Adobe, Apple, Firefox, Google...


Tags: Coffre à outils, Extensions Firefox, PHP

vendredi 6 février 2009

Regular Expressions (Regexp)

Publié par Infinite Loop, à 18 h 02 0 commentaire

Je prends quelques minutes pour partager avec vous un outil web super pour travailler avec les expressions régulières : Regular Expression Tool. Cet outil comporte tout le nécessaire pour écrire et tester des Regexp pour PHP, que ce soit du type PCRE ou POSIX, ainsi que celles pour JavaScript. On peut même avoir un aperçu en temps réel du résultat de l'expression et un générateur de code qui permet de copier et coller l'appel. Très pratique.

Parlant des expressions régulières, savez-vous que Google offre dans ses résultats de recherche des snippets de code ? Il s'agit de son service Code Search. Pour l'expérimenter, essayez de lancer une recherche dans l'interface standard de Google avec le mot clé "regexp" et vous devriez en voir apparaître dans la liste des résultats.


Tags: Coffre à outils, JavaScript, PHP

jeudi 5 février 2009

Compteur de caractères facile avec Prototype

Publié par Infinite Loop, à 22 h 12 1 commentaire

Dans plusieurs formulaires web, on voit fréquemment une recommandation sur le nombre de caractères à entrer. Dans le cas de Twitter, une limite de 140 caractères est allouée pour inscrire son statut et au fur et à mesure que l'on entre des lettres, le compteur fait un compte à rebour (countdown) pour indiquer le nombre de caractères restants.

On peut facilement reproduire ce comportement en JavaScript (de nombreux scripts sont déjà disponibles un peu partout sur le web) et prototype.js permet de créer un code encore plus clair, en quelques lignes de code seulement.

D'abord, on doit inclure la librarie prototype dans la balise HEAD de la page HTML. Ensuite, on initialise le compteur dès qu'on détecte que le Document Object Model est prêt.

La fonction anonyme qui suit permet d'attacher la fonction countdown() à l'événement "keyup", donc à chaque fois qu'une touche du clavier est enfoncée à l'intérieur du champ de saisie portant l'ID "txt". La fonction countdown() ne fait que faire une soustraction entre le champ maximum autorisé (définit dans un champ hidden du formulaire) et le nombre de caractères entrés jusqu'à maintenant.

<script language="javascript" src="prototype-1.6.0.3-min.js"></script>
<script language="javascript" language="javascript">
document.observe('dom:loaded', function(){
Event.observe('txt', 'keyup', countdown);

// premier appel pour initialiser le compteur
countdown();
});

function countdown(){
$('compteur').update( $F('txt_maxlength') - $F('txt').length );
}
</script>
Exemple de formulaire :
<form>
<div>
<input type="text" id="txt" />
</div>
<div>
<input type="hidden" id="txt_maxlength" value="140" />
<span id="compteur"></span> caractères
</div>
</form>
À noter qu'avec un champ de type "textarea", chaque saut de ligne est compté comme étant un caractère.


Tags: JavaScript

mercredi 4 février 2009

Renommer la corbeille de Windows XP

Publié par Infinite Loop, à 18 h 54 0 commentaire

Avez-vous remarqué que dans Windows XP, contrairement à un dossier ou un fichier, il est impossible de renommer la corbeille (recycle bin) à partir du menu contextuel ?

C'est pourtant possible de le faire mais il faut s'y prendre à partir de la base de registre. Par exemple, si l'envie me prend de renommer ma corbeille "Yves Corbeil" en l'honneur d'un pionnier de la télé québécoise, des loteries de Loto-Québec et des multiples doublement de voix incluant les Simpsons (l'idôle d'un peuple quoi!), voici ce que vous devez faire :

  • Cliquez sur le menu "Start" de Windows
  • Choisissez "Run"
  • Dans la boîte de dialogue, entrez "regedit" et OK
  • L'éditeur de la base de registre démarrera
  • Effectuez une recherche pour la clé @C:\WINDOWS\system32\SHELL32.dll,-8964 ou naviguez jusqu'à HKEY_CURRENT_USER\Software\Microsoft\Windows\ShellNoRoam\MUICache et repérez la clé mentionnée ci-dessus
  • Double-cliquez sur la clé et changez la valeur pour ce que vous voulez, dans mon cas "Yves Corbeil"
  • Sur le bureau, si la corbeille n'est pas renommée automatiquement, sélectionnez l'icône et appuyez sur F5 pour la rafraîchir
Voilà, c'est fait. 1, 2, 3, 4 !

Parlant de corbeille... Ça me fait penser à l'histoire d'une dame qui rangeait tous ses dossiers importants dans la corbeille de Windows et qui, un beau jour, a appelé au support technique pour savoir comment récupérer ses fichiers...


Tags: Curiosités, Humour

mardi 3 février 2009

Quota d'espace sur PostgreSQL

Publié par Infinite Loop, à 22 h 10 0 commentaire

Aujourd'hui, je réfléchissais aux quotas imposés par les forfaits d'hébergement où le client pouvait se voir imposer une limite d'espace disque sur le serveur web et autre pour l'espace occupé par la base de données.

C'est un peu ce qui se produit dans l'entreprise où je travaille. Nous offrons des forfaits sur mesure mais nous devons surveiller l'utilisation que le client en fait pour éviter des abus. De façon générale, nous surveillons surtout les fichiers hébergés sur nos serveurs mais trop souvent, nous négligeons l'espace qu'occupe la base de données puisque PostgreSQL se trouve sur un serveur différent du serveur Apache.

Pour suivre l'utilisation des BD, j'ai écrit un petit script qui interroge le serveur en temps réel (uniquement lors de la consultation de la page PHP, mais j'aurais aussi pu le mettre en cronjob) pour connaître l'espace occupé en temps réel. Sans en restreindre l'utilisation par un quota calculé, nous pouvons quand même suivre l'évolution et ajuster le prix facturé si la taille d'une base de données devient plus volumineuse que ce qui était initialement prévu au contrat.

Voici le type de requête SQL qu'on peut utiliser pour connaître l'état de chacune des bases de données d'un serveur (pg_catalog.pg_database retourne la liste de toutes les bases de données sur le serveur) :

SELECT datname as db_name,
pg_database_size(datname) as db_size,
pg_size_pretty(pg_database_size(datname)) as db_txt_size
FROM pg_catalog.pg_database
ORDER BY db_size DESC;
Avec cette requête, nous nous sommes aperçus que trois clients inscrits à un forfait de base possédaient un site web comptant à peine quelques mégaoctets d'espace web alors que la base de données s'étalait sur plusieurs gigaoctets, et ce sans frais additionnels. Avec cette information, nous pourrons non seulement ajuster le forfait et récupérer de l'argent, mais aussi mieux planifier les procédures de sauvegarde (backup) et optimiser l'utilisation du serveur.


Tags: PostgreSQL

lundi 2 février 2009

Fonction pgSQL avec %rowtype

Publié par Infinite Loop, à 20 h 13 0 commentaire

À l'image de son grand frère PL/SQL (Oracle), le langage PL/pgSQL utilisé à l'intérieur des fonctions de PostgreSQL permet de déclarer des variables scalaire (int, varchar, boolean), mais aussi des variables composites en utilisant la syntaxe de déclaration %ROWTYPE.

L'utilisation de %rowtype permet de définir une variable qui contient la structure d'un enregistrement de la table spécifiée. Prenons la table suivante :

CREATE TABLE cities
(
city_id serial,
city_name varchar(50),
province varchar(02),
history varchar(500)
)
Pour déclarer une variable possédant la même structure que la table "cities", on utilisera :
DECLARE varcity cities%ROWTYPE;
Dans le PL/pgSQL, on pourra ensuite populer la variable à partir d'un SELECT :
SELECT INTO varcity *
FROM cities
WHERE city_id = 100;
Lui attribuer des valeurs :
varcity.city_name := 'Montréal';
varcity.province := 'QC';
varcity.history := 'Voir Wikipedia...';
Et insérer l'enregistrement à partir de la structure :
-- insertion 1 (si city_id est statique)
INSERT INTO cities (city_id, city_name, province)
SELECT varcity.*;

-- insertion 2 (si city_id est auto-increment.)
INSERT INTO cities (city_name, province)
SELECT varcity.city_name, varcity.province;
L'avantage d'utiliser %rowtype est que si on redéfinissait le champ "history" de la table "cities" pour qu'il passe de varchar(500) à un champ "text", il ne serait pas nécessaire d'adapter le code puisque %rowtype redéfinirait automatiquement la variable au moment de l'exécution.


Tags: PostgreSQL

dimanche 1 février 2009

Vider une table dans PostgreSQL

Publié par Infinite Loop, à 14 h 25 0 commentaire

Quand on travaille sur un projet comportant une base de données volumineuse, il est important de connaître quelques petits trucs pour optimiser les requêtes.

Souvent, c'est une suite de petites optimisations qui permet de sauver du temps d'exécution au final. Par exemple, imaginez une table de statistiques qui est mise à jour à une certaine fréquence selon le résultat que compile une requête SQL. Un cronjob lance une routine SQL qui compile les résultats, les conserve dans une table temporaire, supprime toutes les entrées de la table de statistiques et les remplace par les nouveaux résultats compilés.

En temps normal, on aurait simplement exécuté la requête suivante pour vider la table :

DELETE FROM tablename;

Or, la suppression des enregistrements est plus longue car certaines vérifications sont effectuées et un log des actions est conservé.

En remplaçant DELETE par TRUNCATE, on passe par-dessus ces mesures de contrôle, ce qui permet d'accélérer substantiellement la vitesse d'exécution.

Par exemple, avec une table très simple comprenant une clé primaire auto-incrémentée et un champ texte, si on insère 1 million d'enregistrements aléatoires :

-- environ 27 secondes
INSERT INTO table_statistics (random_data)
SELECT md5(random()::varchar) as random_string
FROM generate_series(1,1000000)

Une suppression à l'aide de DELETE FROM table_statistics a pris approximativement 7.5 secondes pour vider la table. Alors qu'en utilisant TRUNCATE table_statistics, elle était complètement vide en 93 millisecondes.

Notez que contrairement à DELETE, il est impossible de combiner une clause WHERE avec TRUNCATE. Tronquer une table permet de la vider, donc c'est tout ou rien. L'implémentation de PostgreSQL permet aussi de vider plusieurs tables en séparant les noms par une virgule.

L'instruction TRUNCATE est disponible entre autre sous PostgreSQL, MySQL, SQL Server et Oracle et chacun des RDBMS a ses propres particularités.


Tags: PostgreSQL

Citation no. 15 sur les étudiants

Publié par Infinite Loop, à 10 h 36 0 commentaire

Heureux l'étudiant qui, comme la rivière, arrive à suivre son cours sans quitter son lit.


Tags: Citations

Messages plus récents Messages plus anciens Accueil
S'abonner à : Messages (Atom)
    Suivre @code18 sur Twitter

    Catégories

    • Apache (21)
    • Citations (167)
    • Club Vidéo (24)
    • Coffre à outils (55)
    • CSS (8)
    • Curiosités (117)
    • Design Pattern (2)
    • Drupal (8)
    • Easter Eggs (22)
    • Extensions Firefox (20)
    • GIMP (7)
    • Histoire (21)
    • HTML (32)
    • Humour (57)
    • Intégration (34)
    • iPod (12)
    • JavaScript (110)
    • Jeu de combat (6)
    • Le coin du geek (128)
    • Liens (12)
    • Linux (56)
    • Livres (78)
    • Lois et principes (46)
    • Marché des saveurs (26)
    • Mathématique (18)
    • Mobile (5)
    • Montréal (32)
    • Musique (112)
    • Pancartes et écriteaux (16)
    • Perl (8)
    • Pérou (1)
    • PHP (130)
    • PostgreSQL (44)
    • Programmation (105)
    • Saviez-vous que (55)
    • Sécurité (22)
    • SEO (5)
    • SQL Server (22)
    • Vieilles publicités (6)
    • Virtualisation (8)
    • Voyages (1)
    • Zend Framework (26)

    Divers

    Archives

    • ►  2015 (6)
      • ►  août 2015 (1)
      • ►  juillet 2015 (1)
      • ►  février 2015 (3)
      • ►  janvier 2015 (1)
    • ►  2014 (8)
      • ►  décembre 2014 (1)
      • ►  novembre 2014 (1)
      • ►  octobre 2014 (1)
      • ►  août 2014 (2)
      • ►  juillet 2014 (2)
      • ►  janvier 2014 (1)
    • ►  2013 (53)
      • ►  décembre 2013 (2)
      • ►  novembre 2013 (1)
      • ►  octobre 2013 (3)
      • ►  septembre 2013 (2)
      • ►  août 2013 (5)
      • ►  juillet 2013 (3)
      • ►  juin 2013 (5)
      • ►  mai 2013 (3)
      • ►  avril 2013 (7)
      • ►  mars 2013 (7)
      • ►  février 2013 (11)
      • ►  janvier 2013 (4)
    • ►  2012 (105)
      • ►  décembre 2012 (8)
      • ►  novembre 2012 (5)
      • ►  octobre 2012 (4)
      • ►  septembre 2012 (1)
      • ►  août 2012 (8)
      • ►  juillet 2012 (7)
      • ►  juin 2012 (7)
      • ►  mai 2012 (10)
      • ►  avril 2012 (13)
      • ►  mars 2012 (15)
      • ►  février 2012 (15)
      • ►  janvier 2012 (12)
    • ►  2011 (146)
      • ►  décembre 2011 (14)
      • ►  novembre 2011 (11)
      • ►  octobre 2011 (12)
      • ►  septembre 2011 (13)
      • ►  août 2011 (15)
      • ►  juillet 2011 (17)
      • ►  juin 2011 (18)
      • ►  mai 2011 (15)
      • ►  avril 2011 (9)
      • ►  mars 2011 (7)
      • ►  février 2011 (3)
      • ►  janvier 2011 (12)
    • ►  2010 (398)
      • ►  décembre 2010 (29)
      • ►  novembre 2010 (28)
      • ►  octobre 2010 (32)
      • ►  septembre 2010 (34)
      • ►  août 2010 (22)
      • ►  juillet 2010 (35)
      • ►  juin 2010 (42)
      • ►  mai 2010 (36)
      • ►  avril 2010 (37)
      • ►  mars 2010 (34)
      • ►  février 2010 (32)
      • ►  janvier 2010 (37)
    • ▼  2009 (429)
      • ►  décembre 2009 (32)
      • ►  novembre 2009 (34)
      • ►  octobre 2009 (33)
      • ►  septembre 2009 (37)
      • ►  août 2009 (37)
      • ►  juillet 2009 (39)
      • ►  juin 2009 (38)
      • ►  mai 2009 (37)
      • ►  avril 2009 (35)
      • ►  mars 2009 (36)
      • ▼  février 2009 (32)
        • Débuter avec Smarty
        • Excuses de programmeurs
        • Ajouter les numéros de lignes dans du code source
        • 12 étapes vers un meilleur code ?
        • Décompiler un fichier d'aide CHM
        • Équivalences prototype vs jQuery
        • Afficher une date en français avec PHP
        • Citation no. 18 sur la relation de couple
        • Comparer des versions de fichiers
        • Apprendre le Zend Framework
        • The Pragmatic Programmer
        • Lecture un fichier séquentiel avec Perl
        • Variables de Perl et de PHP
        • Redimensionner une image avec GD
        • Output buffering de PHP
        • Citation no. 17 sur Linux et Windows
        • Convertir des m4a en mp3
        • Configuration de base de TinyMCE
        • RTE gratuits à découvrir
        • Manipuler des mesures avec Zend_Measure
        • Monty Python influence l'informatique
        • Refuser l'accès à certains fichiers avec .htaccess
        • Citation no. 16 sur le travail
        • Jukebox touchscreen
        • Débuter avec SQLite et PHP
        • Regular Expressions (Regexp)
        • Compteur de caractères facile avec Prototype
        • Renommer la corbeille de Windows XP
        • Quota d'espace sur PostgreSQL
        • Fonction pgSQL avec %rowtype
        • Vider une table dans PostgreSQL
        • Citation no. 15 sur les étudiants
      • ►  janvier 2009 (39)
    • ►  2008 (84)
      • ►  décembre 2008 (34)
      • ►  novembre 2008 (39)
      • ►  octobre 2008 (11)

    Abonnés

Copyright © All Rights Reserved. Code 18 | Converted into Blogger Templates by Theme Craft