Toute l'actualité francophone sur PHP en un seul flux

Août 2008 – PHP News: Un script bash pour dumper vos bases MySQL table par table

Il existe différentes méthodes et outils permettant de backuper ses bases de données MySQL. Cela va d’une sauvegarde “offline” par copie des fichiers du dossier data de mysql à une sauvegarde “online” avec mysqlhotcopy ou mysqldump , en passant par l’utilisation d’un serveur esclave MySQL réplicant votre serveur maître.

Ne possédant qu’un seul serveur, il est difficile de faire de la réplication. C’est ainsi que j’utilise les outils mysqlhotcopy et mysqldump pour réaliser les sauvegardes de mon serveur SQL.

Pour une sauvegarde du jour J, j’utilise toujours deux backups :

  • Une des fichiers binaires des bases de données (dossier /data de mysql backupé avec mysqlhotcopy)
  • Un dump SQL de toutes les bases (réalisé par mysqldump)

mysqldump permet de sauvegarder des dumps SQL soit d’une base entière, soit de tables précises dans cette base, soit d’enregistrements précis (option –where), soit carrément sauvegarder toutes les bases (option –all-databases). C’est d’ailleurs cette dernière option que j’utilisais jusqu’à présent, avant d’être confronté au problème suivant :

Je dispose d’un fichier de dump complet de mes bases de données, or ce fichier fait plusieurs centaines de mégaoctets. Je peux aisément restaurer tout le serveur. Mais si j’ai besoin de restaurer une table particulière, comment procéder ?

Etant donné la taille du fichier, toute édition classique afin de copier coller la partie intéressante n’est pas possible. Peut-être que la solution se trouve dans une utilisation astucieuse de cat, grep, awk etc … mais je n’ai pas cherché de ce coté là. Je n’ai pas trouvé non plus du coté de la suite MySQL Workbench qui, bien qu’elle fournisse des outils très intéressants dans la modélisation SQL, celle-ci n’offre pas d’analyseur au niveaux des données.

Exemple : Il est possible d’importer un gros dump SQL dans MySQL Workbench qui permet de reconsituter par rétro-ingénierie la modélisation structurelle des bases de données et des tables contenues dans le script. On peut ensuite exporter les différents objets reconstitués (base ou table par exemple), mais l’export ne concerne que la structure de l’objet, et non ses données (on exporte ainsi le script permettant de créer la table ou la base, mais pas les enregistrements originaux de celles-ci)

En bref, un export total des bases avec mysqldump est difficilement utilisable quand il s’agit de restaurer facilement une base ou une table contenu dans ce dump non éditable.

Voici la solution que j’ai donc implémentée :

  • Un script bash va analyser votre serveur SQL et déterminer vos bases de données, ainsi que les tables qu’elles contiennent. Pour chacune des tables, celui-ci va faire appel à mysqldump pour réaliser un dump de cette table qu’il va alors placer dans le dossier correspondant à la base d’appartenance. Une fois toutes les tables backupées, tout est zippé.

Cette solution a plusieurs avantages :

  • Elle permet d’obtenir un dump sql pour chacune de vos tables, aisément manipulable
  • Elle permet toujours de restaurer tout votre serveur sql : Il suffit simplement de concaténer les différents fichiers pour obtenir le dump général.
  • La taille finale de l’archive est équivalent à celle du dump total.

Voiçi le script commenté :

#!/bin/bash
#Dump table par table MySQL - phpnews.fr

#Déclaration de l'utilisateur MySQL aux droits suffisants pour parcourir vos bases de données
#Droit requis : SELECT global, LOCK TABLES
user='backuper'
pass='p@ssw0rd'

#On définit un nom temporaire utilisé par le script (ici la date jusqu'à la minute)
dirname="dump_`date +%d`.`date +%m`.`date +%y`@`date +%H`h`date +%M`"

#On crée sur le disque un répertoire temporaire (changer le chemin précédant /$dirname)
mkdir "/$dirname"

#On place dans un tableau le nom de toutes les bases de données du serveur
#On peut choisir ici d'exclure certaines bases de données de la sauvegarde grâce à la clause LIKE
#Ex : -e "show databases LIKE 'blog_%'"
databases=( $(mysql -u $user -p"$pass" -e "show databases" | grep -v Database) )

#Pour chacune des bases de données trouvées ...
for database in ${databases[@]}
do
#... on crée dans le dossier temporaire un dossier portant le nom de la base
mkdir "/${dirname}/${database}"
#... on récupère chacune des tables de cette base de données dans un tableau ...
tables=( $(mysql $database -u $user -p$pass -e 'show tables' | grep -v Tables_in) )
#... et on parcourt chacune de ces tables ...
for table in ${tables[@]}
do
#... que l'on dump avec mysqldump dans un fichier portant le nom de la table dans le dossier de la bdd parcourue
$(mysqldump -u $user -p$pass --quick --add-locks --lock-tables --extended-insert $database $table > /${dirname}/${database}/${table}.sql)
done
done

#On bzip le tout
tar -cjf /home/server/backup/sql/dump_tables/tables_${dirname}.tar.bz2 /$dirname/

#On supprime le répertoire temporaire
rm -rf /$dirname/

Et voilà le travail ;)

Note : Ce script pose un problème de respect de la consistance de la base de donnée car les différentes tables ne sont pas sauvegardées au même moment. Je vous invite à lire les commentaires de ce billet et d’utiliser ce script avec discernement.

Août 2008 – Apprendre-PHP.com: Les exceptions - 2ème partie

La première partie de ce tutoriel a été l'occasion de présenter le mécanisme des exceptions de manière très théorique. Au travers d'exemples simples et concrets, nous avons découvert comment générer, lancer et attraper des exceptions en plein vol. A ce stade, nous sommes encore loin de pouvoir profiter pleinement des exceptions dans des applications plus conséquente. C'est pourquoi cette seconde et dernière partie s'intéressera à la manière de dériver la classe Exception pour créer des exceptions personnalisées. Enfin, nous étudierons un mécanisme natif de PHP qui permet de centraliser et d'unifier le traitement des exceptions non capturées dans une fonction de callback appelée automatiquement par l'exception handler.

Août 2008 – PHP Index: Sun microsystems lance son pack AMP

Sun microsystems vient d'annoncer la disponibilité de son pack AMP pour systèmes d'exploitation Solaris et Linux.

Ce pack est constitué du serveur HTTP Apache, du système de gestion de base de données MySQL et du langage PHP (et PERL). Le pack est disponible en téléchargement sur le site de Sun.

Août 2008 – Apprendre-PHP.com: Installer un environnement LAMP6 sur Debian

PHP 6 pointe enfin le bout de son nez ! Eh oui, certains passionnés attendent sa sortie avec impatience. Je teste PHP 6 depuis un an environ et bien-sûr uniquement en test vu que la version stable n'est pas encore sortie à l'heure où j'écris ces lignes. Ce tutoriel est basé sur un article que j'ai écrit pour le magazine Linux+DVD. Il s'agit de déployer pas à pas un environnement LAMP 6 (Apache 2, PHP 6 et MySQL 6) sur une distribution Linux Debian.

Août 2008 – Hello Design: kit de sécurité

Il se trouve en vigueur depuis le 1er juillet 2008, Le kit de sécurité se compose d'un triangle et d'un gilet jaune ou orange comme ceci :
Sinon vous pouvez avoir une contravention de 135 euro si vous ne l'avez pas et 90 euros s'il vous en manque l'un ou l'autre.
 
Maintenant, suite à une enquete d'un magazine automobile, de nombreux triangle sont trop léger et vont s'envoler aux passages de voitures ou camions.
  
Pour avoir un kit de sécurité, je conseille ce site. surtout que le triangle fait environ 1 Kg 300....
Il est même possible d'en avoir plusieurs sur devis... http://actualite.naoss.fr ou sur cette page : cliquer ici
 
 

Août 2008 – tigrou/pwet.fr: En attendant eZ Publish 4.0.1 (ou 4.1)

Edit : il suffit que j'écrive un billet sur le sujet pour que la RC2 sorte avec enfin la correction des problèmes d'URL Alias. La version finale est aussi annoncée d'ici une à deux semaines sur la mailing liste si tout va bien.

eZ Publish 4.0 est sorti en décembre 2007 et depuis rien, aucune version stable. 8 mois c'est vraiment très très très long, il y a donc forcément des bugs gênants dans eZ Publish 4.0 d'autant plus que cette version est un portage vers PHP5 de la version 3.10 ce qui occasionne encore quelques bugs supplémentaires. La roadmap du bugtracker liste les problèmes résolus et non résolus mais il n'est pas toujours simple de faire le lien entre un comportement suspect et un bug dans cette liste.

Par exemple en développant la nouvelle version de ce site, je me suis trouvé face à plusieurs problèmes qui ont nécessité l'inclusion de patchs issus du SVN.

Les cache-block qui n'expirent pas

Il s'agit du bug #12175 qui empêche l'utilisation des cache-block expirant avec une sous-arborescence. Pour règler ce problème sans passer à la version 4.0.1rc1 il faut appliquer 3 patchs successifs sur l'arborescence d'eZ Publish 4.

$ cd /tmp
$ wget http://pwet.fr/content/download/71716/214901/file/patch_cache_block_12175.tar.gz
$ tar -zxvf patch_cache_block_12175.tar.gz
$ cd /path/to/ez/publish/
$ patch -p0 < /tmp/01_cache-block.patch
$ patch -p0 < /tmp/02_cache-block.patch
$ patch -p0 < /tmp/03_cache-block.patch

Les erreurs sur l'application du patch sur le change log peuvent être tranquillement ignorées.

Les variations des images re-dimensionnées en permanence

Celui la, c'est un bug vicieux, on s'en rend compte lors de la mise en production quand la machine est à plat par tous les convert (ou apache si on utilise GD) en train de générer les différentes variations encore et encore. 80 de load average sur ma pauvre Dedibox, elle a du avoir chaud ;-)

un seul patch est nécessaire et c'est immédiat et magique sur la charge de la machine

$ cd /tmp
$ wget http://pwet.fr/content/download/71717/214904/file/image_variations.patch
$ cd /path/to/ez/publish
$ patch -p0 < /tmp/image_variations.patch

J'ai pas eu d'autres bugs bloquants (enfin je les ai pas encore remarqué :)), j'en ai d'ailleurs découvert un sur le SmartCacheClear avec les keywords, la correction est dans le rapport et tient sur une unique ligne.

Août 2008 – Kamelot Blog: PEAR::Pager tuto : Créer des cool Url pour la pagination avec Pager et mod_rewrite

Ce texte est une des traductions d'une série d'articles de Lorenzo Alberton (original)

La plupart des classes de pagination PHP peuvent fonctionner très bien avec des paramètres GET, correctement envoyés par les pages.

Cependant, rares sont celles qui vous laissent le contrôle sur les liens qu'elles créent.

Ceci peut être particulièrement ennuyant quand vous travaillez avec des cool URL (grâce à mod_rewrite ordonne ou fait à la main par votre contrôleur) et la classe de de pagination ne peut pas les respecter, en affichant les liens réels et laids.

Si le scénario ci-dessus n'est pas nouveau pour vous, alors vous devriez probablement tester PEAR::Pager.

C'est un paquet entièrement personnalisable qui devrait satisfaire tous vos besoins, y compris votre format préféré de lien.

Exemple : Comment dire au pager le format de vos liens

Supposons-vous ont un site de commerce électronique, avec un catalogue de produit que l'utilisateur peut passer en revue par catégorie.

Par exemple, pour énumérer tous les produits de la catégorie AAA, vous passez ce paramètre à votre page : http://monserveur.com/produits.php?cat=AAA.

Si le catalogue est assez grand, la dispersion des produits dans plusieurs pages serait une décision intéressante, mais maintenant vous devez également passer le numéro de page à l'URL : http://monserveur.com/produits.php?cat=AAA&pageID=3.

Naturellement votre application intelligente peut produire des URL plus propres, comme ceci : /produits/AAA/3.html qui sont facilement décodés par le mod_rewrite.

Voyons l'exemple de règle .htaccess pour cette transformation d'URL :

[apache]
RewriteEngine on

RewriteBase /
RewriteRule ^produits/(\w+)/(\d+)\.html$ /produits.php?cat=$1&pageID=$2 [L]

Normalement, la classe de pagination les paramètres de cat et de pageID et établirait les liens comme d'habitude, c.-à-d.

/produits.php?cat=AAA&pageID=1
/produits.php?cat=AAA&pageID=2
...
/produits.php?cat=AAA&pageID=6

mais vous pouvez apprendre à PEAR::Pager à produire les liens qui respectent votre convention :

[php]
<?php
require_once 'Pager/Pager.php';

//toujours valider paramètres GET

if (!empty($_GET['cat']) && $myApp->is_valid_cat($_GET['cat'])) {
    $cat = $_GET['cat'];
} else {
    $cat = 'AAA'; //default category
}

// Récupération des produits. 
// S'il y a beaucoup de produits, 
// vous pouvez envisager d'employer les fonctions de Pager_Wrapper 

$produitList = $myApp->getProductsByCat($cat);

$pager_params = array(
    'mode'     => 'Sliding',
    'append'   => false,  //ne pas ajouter les paramètres GET à l'URL
    'path'     => 'http://monserveur.com/produits/' . $cat,
    'fileName' => '%d.html',  //Pager remplace "%d" par le numéro de la page
    'perPage'  => 10, //afficher 10 articles par page
    'itemData' => $produitList,
);
$pager = & Pager::factory($pager_params);
$data  = $pager->getPageData();

//Afficher les produits de la page courante
echo 'Données de la page courante: ';
print_r($data);

//afficher les liens pour la navigation dans la catégorie courante 
echo $pager->links;
?>

Comme vous pouvez voir, vous pouvez dire au pager le chemin et le nom de fichier qu'il devrait employer.

N'oubliez pas de placer l'option de append à FALSE, sinon le pager essayera d'apposer les vars GET à l'URL comme d'habitude.

Example #2: le numéro de la page est dans le chemin et non dans le nom du fichier?

Et si le numéro de la page dans votre url se trouve dans le path et non dans nom fichier?

Ca pourrait ressembler à un problème, puisque Pager recherche la chaîne « %d » dans le paramètre nom de fichier, et se plaint s'il ne peut pas y trouver cette chaîne.

Non, vous ne pouvez pas le mettre dans le paramètre path, mais puisque le pager combinera simplement les paramètres path et nom de fichier pour former l'URL, nous pouvons le duper et mettre une partie du path dans le nom de fichier lui-même.

Pour le moment, si nous avons une url comme http://monserveur.com/produits/AAA/3/index.html, où "3" est le numéro de la page, cette règle de mod_rewrite et ce script php le feront fonctionner:

[apache]
RewriteEngine on

RewriteBase /
RewriteRule ^produits/(\w+)/(\d+)/index\.html$ /produits.php?cat=$1&pageID=$2 [L]
[php]
<?php
require_once 'Pager/Pager.php';

// ...

$pager_params = array(
    'mode'     => 'Sliding',
    'append'   => false,  //ne pas ajouter les paramètres GET à l'URL
    'path'     => 'http://monserveur.com/produits/' . $cat,
    'fileName' => '%d/index.html',  //Pager remplaces "%d" par le numéro de la page
    'perPage'  => 10, //afficher 10 articles par page
    'itemData' => $produitList,
);
$pager = & Pager::factory($pager_params);
$data  = $pager->getPageData();

//afficher les produits de la page courante
echo 'Données de la page courante: ';
print_r($data);

//afficher les liens pour la navigation dans la catégorie courante 
echo $pager->links;
?>

Voilà c'est fait. J'espère que ce tuto était utile.

à lire aussi

Août 2008 – Apprendre-PHP.com: PHP s'arrête à la version 4.4.9

Nous sommes le 08 août et il est tout juste 1h du matin à l'heure où j'écris ces quelques lignes. Alors que je devrais me coucher et me préparer à une bonne nuit de sommeil, PHP 4 s'apprête tout juste à signer son arrêt définitif après tant de bons et loyaux services auprès des amateurs...

Août 2008 – z-f.fr: ZF 2.0, PHP 5.3 et namespaces

Forum: Brèves
Auteur: philippe
Écrit le: Fri, 08 Aug 2008 10:33:41 +0200
Dernier message: Wed, 01 Oct 2008 09:42:33 +0200

Août 2008 – Kamelot Blog: PEAR::PAGER, Paginations d'article, ou comment naviguer dans les paragraphes d'un article avec le paginateur

Ce texte est une des traductions d'une série d'articles de Lorenzo Alberton

Vous avez probablement vu beaucoup de sites Web comporter des articles longs et détaillés, qui sont coupés en paragraphes, chacun présenté dans une page séparée.

Les utilisateurs préfèrent souvent lire les morceaux courts du texte au lieu de faire défiler une très(trop) longue page (à moins qu'ils ne veulent l'imprimer).

Dans ce tuto, nous allons voir comment nous pouvons établir un système de paginations d'article, a l'aide de PEAR::Pager.

La structure de base de données

Nous aurons besoin de deux tables pour stocker nos articles :

  • une avec l'information de base des article (auteur, titre, résumé, date de publication)
  • et une contenant les paragraphes (un par enregistrement, avec le titre et le contenu).

Techniquement, nous pourrions employer juste une table, utilisant quelques délimiteurs spéciaux incorporés dans le texte (tel que le « ====FIN DE PAGE====") pour découper les paragraphes, mais croyez moi qu'à la longue cette une solution bien meilleure

[SQL]
CREATE TABLE articles (
  id INTEGER NOT NULL,
  title VARCHAR(250) NOT NULL,
  abstract TEXT,
  submission_date TIMESTAMP NOT NULL,
  author_id INTEGER NOT NULL,
  CONSTRAINT articles_pkey PRIMARY KEY(id)
);

CREATE TABLE paragraphs (
  article_id INTEGER NOT NULL,
  paragraph_id INTEGER NOT NULL,
  title VARCHAR(250),
  content TEXT,
  CONSTRAINT paragraphs_pkey PRIMARY KEY(article_id, paragraph_id),
  CONSTRAINT paragraphs_fk FOREIGN KEY (article_id) REFERENCES articles(id) ON DELETE CASCADE
);

Données d'exemple

Voici quelques données d'exemple si vous voulez tester tout en lisant ce tuto :

[SQL]
-- Premier Article
INSERT INTO articles (id, title, abstract, submission_date, author_id) VALUES (
  1,
  'How to navigate through the paragraphs of an article with Pager',
  'You\'ve probably seen a lot of websites featuring long, detailed articles, which are split into paragraphs, each of them in a separate page. Users often prefer reading short chunks of text instead of scrolling a very long page (unless they want to print the page, then the opposite applies). In this tutorial, we\'re going to see how we can build an article pagination system, with a little help from PEAR::Pager.',
  CURRENT_TIMESTAMP,
  1
);
INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (1, 1, 'The database structure', 'First paragraph here');
INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (1, 2, 'Sample data', 'Second paragraph here');
INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (1, 3, 'Showtime', 'Third paragraph here');
INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (1, 4, 'Alternate navigation', 'Fourth paragraph here');
INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (1, 5, 'Article summary', 'Fifth paragraph here');
INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (1, 6, 'Printer friendly version', 'Sixth paragraph here');

-- Second Article
INSERT INTO articles (id, title, abstract, submission_date, author_id) VALUES (
  2,
  'PEAR::Pager tutorials',
  'New series of tutorials about PEAR::Pager',
  CURRENT_TIMESTAMP,
  1
);
INSERT INTO paragraphs (article_id, paragraph_id, title, content) VALUES (2, 1, 'Articles index', '1. How to efficiently paginate database results.  2. Create pretty links with Pager and mod_rewrite.  3. Navigation with Pager and AJAX (or simple Javascript).  4. Article pagination.');

Showtime!

Maintenant que nous sommes ok avec la structure de base de données, nous pouvons afficher les articles sur notre site, un paragraphe par la page.

Pour cette tâche, nous allons employer PEAR::MDB2 DBAL et le bien pratique Pager_Wrapper que nous avons déjà vu dans un tuto précédent :

[php]
<?php
//Copier le fichier Pager_Wrapper file là où il peut-être inclu
require_once 'Pager_Wrapper.php';
require_once 'MDB2.php';

$article_id = 1; //if you fetch this parameter via GET/POST, remember to validate it!

//on passe le code de connexion DB 
//on suppose qu'on a une connexion valide dans  $db

$pager_options = array(
    'mode'       => 'Sliding',
    'perPage'    => 1, //On ne veut qu'un paragraphe par page
    'delta'      => 3,
);

$query = 'SELECT articles.title AS article_title,
                 articles.submission_date,
                 articles.abstract,
                 paragraphs.title AS paragraph_title,
                 paragraphs.content
            FROM paragraphs
       LEFT JOIN articles ON articles.id = paragraphs.article_id
           WHERE articles.id = '. (int)$article_id .'
        ORDER BY paragraphs.paragraph_id;

$paged_data = Pager_Wrapper_MDB2($db, $query, $pager_options);

//Afficher les résultats
echo '<h1>'.$paged_data['data'][0]['article_title'].'</h1>';
echo '<p><i>'.$paged_data['data'][0]['submission_date'].'</i></p>';
if ($paged_data['page_numbers']['current'] == 1) {
    // afficher aussi le résumé.
    echo '<p>'.$paged_data['data'][0]['abstract'].'</p>';
}
echo '<h2>'.$paged_data['data'][0]['paragraph_title'].'</h2>';
echo '<p>'.$paged_data['data'][0]['content'].'</p>';

//afficher les liens
echo $paged_data['links'];
?>

Puisque nous avons demandé au paginateur de couper les articles (les paragraphes, dans notre cas) en groupes de "un", il renverra seulement un paragraphe, et nous pouvons naviguer vers les autres paragraphes avec les liens générés par paginateur.

Voici le rendu du script :

Pager with links example


Autre navigation

Si vous n'aimez pas des liens normaux pour la navigation, et préférez un menu de <select> à la place, vous devez ajouter un appel à la la fonction getPageSelectBox () dans Pager_Wrapper_MDB2, avant de renvoyer le tableau de données paginée, puisqu'elle n'est pas incluse dans la version par défaut :

[php]
function Pager_Wrapper_MDB2(&$db, $query, $pager_options = array(), $disabled = false, $fetchMode = MDB2_FETCHMODE_ASSOC)
{
  // Pager_Wrapper_MDB2() body omitted. Add the following lines before the return call:

  // ===== Début du  CODE ajouté  ======
  $selectbox_options = array(
      'optionText' => 'page %d',
      'autoSubmit' => true,
  );
  $page['select_menu'] = $pager->getPageSelectBox($selectbox_options);
  // ===== Fin du  CODE ajouté =====

  return $page;
}

Maintenant on affiche le menu de navigation :

[php]
<?php
// [snip: même code que dans le paragraphe précédent]

//Affichage du menu
echo 'Choisissez une page: '. $paged_data['select_menu'];
?>

Et voilà ce que ca devrait donner: Pager avec exemple de menu select


Sommaire de l'article

Parfois, vous pouvez vouloir montrer un sommaire de l'article, avec une liste des titres de paragraphe, chacun indiquant le paragraphe complet.

Aucun problème, vous pouvez faire cela.

[php]
<?php
$query = 'SELECT title
            FROM paragraphs
           WHERE article_id = '. (int)$article_id
     .' ORDER BY paragraph_id';
$paragraph_titles = $db->queryCol($query);
//on oublide le code de vérification

echo '<h2>Sommaire</h2>';
echo '<ul>';
foreach ($paragraph_titles as $k => $title) {
    if ($k == ($paged_data['page_numbers']['current'] -1)) {
        // Page courrante, ne pas afficher le lien
        echo '<li>' . $title . '</li>';
    } else {
        echo '<li><a href="article.php?id='. (int)$article_id .'&pageID='. ($k+1) .'">'. $title . '</a></li>';
    }
}
echo '</ul>';
?>

Le résultat est un résumé des titres de paragraphe, avec leurs liens Exemple de sommaire


Version imprimable

Si vous voulez proposer une version pour l'impression avec l'article complet, vous pouvez chercher tous les paragraphes et simplement les afficher l'un après l'autre :

[php]
<?php
$query = 'SELECT title,
                 submission_date,
                 abstract
            FROM articles
           WHERE id = '. (int)$article_id;
$article = $db->queryRow($query, null, MDB2_FETCHMODE_ASSOC);

$query = 'SELECT title,
                 content
            FROM paragraphs
           WHERE article_id = '. (int)$article_id
     .' ORDER BY paragraph_id';
$paragraphs = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);

//Afficher les données principales de l'article:
echo '<h1>'.$article['title'].'</h1>';
echo '<p><i>'.$article['submission_date'].'</i></p>';
echo '<p>'.$article['abstract'].'</p>';


// Afficher les paragraphes de l'article:
foreach ($paragraphs as $paragraph) {
    echo '<h2>'.$paragraph['title'].'</h2>';
    echo '<p>'.$paragraph['content'].'</p>';
}

?>

J'espère que ce tuto était utile (la traduc aussi :).

Si vous avez besoin de quelques clarifications, ou avez quelques suggestions , envoyez-nous un mail :

  • Lorenzo de préférence mais en anglais.
  • Moi de préférence mais en anglais.

Août 2008 – Kamelot Blog: Articles sur spl

J'ai envie de m'intéresser à la Standard PHP Librairy. J'ai cherché quelques tutos et références.

Tuto& articles

références

Août 2008 – Kamelot Blog: PEAR::Pager tutor : Navigation avec pagination et Javascript simple

Ce texte est une des traductions d'une série d'articles de Lorenzo Alberton

OK, vous ne pouvez pas résister à la tendance du Web 2.0 vous avez appris que tous que vous pourriez se renseigner sur cette « nouvelle » technologie appelée AJAX, et maintenant vous vous demandez comment vous pourriez vivre sans lui.

Tout le monde n'a pas sauté dans le mouvement, bien que, et beaucoup de bibliothèques existent toujours sans mettre en application ce dispositif, ainsi vous est confronté au dilemme :

Dois-je je continuer à employer que vieille bibliothèque et abandonner mes idées fraîches d'AJAX, ou devrais je mettre en application ma propre version ?

Si vous recherchez une classe de pagination avec ces conditions, je suis heureux de vous rassurer au sujet de PEAR::Pager : il est AJAX-ready, et a été depuis il y a longtemps.

garanti 100% buzzword-compliance !

Example #1 - Pagination et Javascript

D'abord, regardons un exemple simple sur la façon d'armer le paginateur pour créer des liens de Javascript.

Dans cet exemple plutôt simpliste, nous récupérons toutes les données dans les morceaux paginés, stockons chaque page dans un <div> et employons quelques scripting DOM pour cacher toutes les couches sauf la page courante.

@voir fonctionner cet exemple

[php]
<?php
require_once 'Pager/Pager.php';
$data = range(1, 100); //un tableau de données à paginer
$pager_params = array(
    'mode'     => 'Sliding',
    'append'   => false,  //ne pas ajouter les paramètres GET
    'path'     => '',
    'fileName' => 'javascript:revealDiv(%d)',  //Pager replaces "%d" with the page number...
    'perPage'  => 10, //afficher  10 item par page
    'delta'    => 5,
    'itemData' => $data,
);
$pager = & Pager::factory($pager_params);
$n_pages = $pager->numPages();
$links = $pager->getLinks();
?>
<html>
<head>
    <script type="text/javascript">
    var n_pages = <?php echo $n_pages ?>;
    function revealDiv(n)
    {
        for (var count = 1; count <= n_pages; count++) {
          document.getElementById("page"+count).style.display = 'none';
        }
        document.getElementById("page"+n).style.display = 'block';
    }
    </script>
    <style type="text/css">
    div.page {
      background: #FFFF99;
      border-top: 1px solid #FFBF99;
      border-bottom: 1px solid #FFBF99;
    }
    </style>
</head>
<body>
<h1>PEAR::Pager exemple with JavaScript</h1>
<?php echo $links['pages']; ?>
<hr />
<?php
for ($i=1; $i <= $n_pages; ++$i) {
    echo '<div class="page" id="page'.$i.'">';
    echo '<h2>Page '.$i.'</h2>';
    foreach ($pager->getPageData($i) as $item) {
        echo 'Item '.$item.'<br />';
    }
    echo '</div>';
}
?>
<hr />
<script type="text/javascript">
revealDiv(1);
</script>
</body>
</html>

à lire aussi

Août 2008 – PHP Index: PHP 4.4.9 & PHP 5.3 Alpha1

L'équipe de développement de PHP vient d'annoncer la sortie de PHP 4.4.9. Cette version a pour but d'améliorer la stabilité de la branche 4.4.x.

Parmi les correctifs on notera :

  • La Mise à jour de PCRE version 7.7
  • La Correction de possibles crashes dans imageloadfont
  • La Correction de la fonction memnstr()
La liste complète des modifications apportées par PHP 4.4.9 est disponible dans le changelog.

A noter aussi, la sortie de PHP 5.3 Alpha1. Cette nouvelle version de PHP devrait améliorer la stabilité et les performances de la branche 5.x mais aussi apporter de nouvelles syntaxes au langage et à ses extensions. Plusieurs nouvelles fonctionnalités ont déjà été documentées dans la documentation officielle, d'autres sont répertoriées dans le wiki.

Télécharger PHP 5.3 Alpha1
Télécharger PHP 4.4.9

Août 2008 – PHP Index: MySQL 5.0.67

Une nouvelle version de MySQL vient de voir le jour. Cette nouvelle version apporte quelques modifications parmi lesquelles :

  • L'ajout de la variable système plugin_dir
  • Le moteur de stockage FEDERATED est à présent désactivé par defaut
  • La mise à jour de REPAIR TABLE et de CHECK TABLE
Le changelog
Télécharger MySQL 5.0.67

Août 2008 – Apprendre-PHP.com: Méthodes magiques : __set() et __get()

PHP a fait un grand pas en avant en matière de programmation orientée objet avec sa version 5. Depuis cette version, il permet d'implémenter des méthodes au comportement prédéfini par PHP. Ces méthodes sont appelées « méthodes magiques », les méthodes __set() et __get() en font partie.

Août 2008 – tigrou/pwet.fr: Optimiser son site sous Ubuntu : Configurer l'en-tête Expires

Lire un livre sur comment optimiser son site web c'est bien, appliquer les conseils qui s'y trouvent c'est encore mieux. Parmi les 14 bonnes pratiques, 3 peuvent être appliquées très rapidement au niveau système en quelques lignes de commande et de configuration du serveur web pour un résultat quasi immédiat :

Dans un premier temps, je vais m'intéresser à la règle 3, je suppose que vous avez déjà un serveur web Apache2 actif servant des fichiers (peu importe la technologie autour). La configuration suivante est utilisée sur ma Dedibox sous Ubuntu avec Apache2 mais doit pouvoir s'appliquer à peu près partout.

Ajoutez et configurez l'en-tête Expires

L'en-tête Expires indique quand un élément devra expirer du cache du navigateur; mettre une date d'expiration dans un futur lointain permet de maximiser l'utilisation du cache navigateur et donc d'éviter les téléchargements inutiles, ce qui est particulièrement utile pour les éléments statiques (images, feuilles de style, ...) qui ont tendances à changer ... peu fréquemment mais à ralentir l'affichage de la page si ils ne sont pas en cache. Pour ces éléments, il est possible de configurer l'expiration dans Apache avec le module expires. Pour les pages dynamiques ou éléments générés dynamiquement, c'est au script d'envoyer l'en-tête et sa valeur adéquate par exemple avec la fonction header() en PHP.

L'activation du module pour Apache2, il faut utiliser a2enmod avec la ligne suivante et ensuite recharger apache :

$ sudo a2enmod expires
$ sudo /etc/init.d/apache2 reload

Il reste alors à configurer ce module. Je stocke la configuration de ce module dans le fichier /etc/apache2/conf.d/expires dont voici le détail :

ExpiresActive On
ExpiresByType image/gif "access plus 30 days"
ExpiresByType image/jpg "access plus 30 days"
ExpiresByType image/jpeg "access plus 30 days"
ExpiresByType image/png "access plus 30 days"
ExpiresByType image/x-icon "access plus 30 days"
ExpiresByType text/css "access plus 30 days"
ExpiresByType application/x-javascript "access plus 30 days"

Tous les éléments statiques des types listés expirent 30 jours après leur premier téléchargement. Après un nouveau reload d'Apache, vous devriez voir apparaître l'en-tête Expires par exemple avec l'extension Firebug de Firefox au premier chargement des éléments de la page. Ensuite le navigateur utilisera son cache ce qui devrait accélérer l'affichage des pages suivantes utilisant les mêmes éléments.

Août 2008 – Apprendre-PHP.com: Les classes abstraites et finales

PHP intègre un autre concept de la programmation orientée objet : les classes abstraites. Ce cours définit et introduit la notion de classes abstraites. Nous présenterons ce que sont les classes abstraites, à quoi elles servent au développement et comment les déclarer et les utiliser. Nous étudierons enfin le cas particulier des classes et méthodes finales qui participent à la sécurité du code en programmation orientée objet.

Août 2008 – PHP Québec: 10/2 19:00 Rencontre Montréal, octobre

PHP Québec vous convie à la rencontre mensuelle du mois d'octobre.

En première partie, Jean-Pierre Lessard présentera eyeOS, une bibliothèque et application permettant de développer des applications web similaires à des applications de bureau.

En deuxième partie, Sylvain Racine nous fera une présentation de la base de données PostgreSQL, de ses outils d'administration, configuration, modules et language de programmation.

Vous aimeriez faire une présentation ou vous avez un sujet a proposer pour cette rencontre, veuillez contacter les organisateurs board@phpquebec.com

Confirmez votre présence sur :
FaceBook: http://www.facebook.com/home.php#/group.php?gid=2334604744
Upcoming : http://upcoming.yahoo.com/event/1100923/

Date : 2 Octobre 2008
Heure : 19h00
Lieu : École de technologie supérieure
Salle : B-4416
Metro: Bonaventure
Carte : http://www.etsmtl.ca/zone2/enbref/rendre.html
Ville : Montréal


Prochaines activités:
- 2 octobre PHP Québec
- 4-5 octobre codeFest 2.2
- 4-6 mars conférence PHP Québec

Inscrivez vous dès aujourd'hui à la conférence PHP Québec et bénéficiez de tarif de pré-vente.

Août 2008 – PHP Index: Dotclear 2.0

Dotclear 2.0 est dès à présent disponible. Cette version apporte quelques nouveautés par rapport à la version 2.0 RC2.1 tel que :

  • Le rafraîchissement de l'apparence de l'interface d'administration avec le nouveau logo
  • La prévisualisation des billets directement en contexte
  • Un nouveau gestionnaire de langues avec possibilité d'ajouter des langues très facilement
  • Un nouveau plugin d'import/export avec le support de l'import pour Dotclear 1.2 ainsi que WordPress
  • Le support de SQLite amélioré
Le temps écoulé entre la version 1 et 2 étant conséquent, il n'est pas inutile de revenir sur les améliorations et les nouveautés apportées par cette nouvelle version :

Le plugin Page : Longtemps attendu, ce nouveau plugin permet de créer des pages statiques (a propos, mentions légales etc...) à partir de l'administration.

Amélioration de l'interface de rédation des billets : La zone de rédaction des billets à connue de nombreuses améliorations et quelques nouveautés comme la possibilité d'ajouter des vidéos depuis youtube, des mp3 ou des FLV (le lecteur étant déjà intégré dans dotclear 2).

Un éditeur de thème : L'administration propose, comme son nom l'indique, un éditeur de thème permettant de modifier les templates et les css grâce à une interface simplifiée.

Le gestionnaire de média : Ce plugin supporte désormais les fichiers zip. Ce qui permet de pouvoir déposer un grand nombre de fichier d'un seul coup.

Site officiel
Télécharger dotclear 2

Août 2008 – Kamelot Blog: PEAR::Pager tutorials. Navigation avec pagination et Ajax

Ce texte est une des traductions d'une série d'articles de Lorenzo Alberton Suite de PEAR::Pager tuto : Navigation avec pagination et Javascript simple

Comme vous avez pu le voir, the trick was setting the path parameter to an empty string and the fileName parameter to a javascript link, avec l'habituel marqueur "%s" pour le pageID.

Exemple #2: On veut de l'AJAX! On veut de l'AJAX!

Ok, maintenant que vous avez vu les bases, vous devriez avoir tous les éléments à aller plus loin.

Mais si vous êtes paresseux et voulez le voir quand même, voici un exemple sur la façon de faire la même chose que ce que nous avons vu avant, cette fois utilisant des appels AJAX chercher seulement les données utiles pour la page montrée.

Dans cet exemple, j'utilise la librairie PEAR::HTML_AJAX (docs):

Si vous ne pouvez pas attendre voyez cette démo, c'est l'exemple en fonctionnement, regardons comment il est fait :

1) Le fichier html:

nous incluons les fichiers js dynamiques (server.php) pour traiter les demandes AJAX, et appellons HTML_AJAX.replace ("target","testdata.php"), ce qui remplacera le contenu du DIV cible par le rendu du script testdata.php en utilisant un appel d'AJAX.

[php]
<html>
<body>
<h1>PEAR::Pager exemple avec AJAX</h1>

<script type="text/javascript" src="server.php?client=all"></script>

<div id="target">Je suis la cible</div>

<script type="text/javascript">
    HTML_AJAX.replace('target', 'testdata.php');
</script>

</body>
</html>
2) Le fichier testdata.php:

c'est un simple script php qui récupère les données que vous désirez afficher (Dais cet exemple, 100 entiers) et les renvoie au Paginateur.

L'output de ce script remplacera le contenu du DIV cible dans le premier fichier html.

Nous affichons également la date et l'heure courante pour nous prouver que les données sont « fraîches » et construites à chaque appel (c.-à-d. chaque fois que vous cliquez sur un lien de navigation).

[php]
<?php
require_once 'Pager.php';
$data = range(1, 100); //un tableau de données à paginer
$pager_params = array(
    'mode'     => 'Sliding',
    'append'   => false,  //ne pas ajouter les paramètres GET
    'path'     => '',
    'fileName' => 'javascript:HTML_AJAX.replace(\'target\',\'testdata.php?pageID=%d\');',  //Pager replaces "%d" with the page number...
    'perPage'  => 10, //afficher  10 item par page
    'delta'    => 1,
    'itemData' => $data,
);
$pager = & Pager::factory($pager_params);
$n_pages = $pager->numPages();
$links = $pager->getLinks();
echo '<p>Ce containeur est rempli avec un appel AJAX</p>';
echo '<p><span class="datetime">DateTime: '. date('Y-m-d H:i:s') .'</span></p>';
echo '<h3>Page '. $pager->getCurrentPageId() .'</h3>';
foreach ($pager->getPageData() as $item) {
    echo 'Item '. $item .'<br />';
}
echo '<hr />'.$pager->links;
?>
3) Finallement, le fichier server.php :

nous créons une instance de HTML_AJAX_Server pour livrer les les deux les bibliothèques de Javascript et pour traiter les demandes d'AJAX des navigateurs.



[php]
<?php
include 'HTML/AJAX/Server.php';

$server = new HTML_AJAX_Server();
$server->handleRequest();
?>

Août 2008 – PHP Index: Drupal 5.10 & 6.4

Drupal 6.4 et Drupal 5.10 sont disponible.

Ces deux versions n'apportent aucune nouvelle fonctionnalité mais corrigent plusieurs bogues de sécurité présent dans les branches 5.x et 6.x. La mise à jour de ces versions est fortement recommandée.

Télécharger Drupal 5.10
Télécharger Drupal 6.4
Site officiel

Août 2008 – PHP Index: L'internationalisation en PHP

Tutoriel d'utilisation de l'extension PEAR pour internationeliser son application PHP.

Le site DevX.com et Octavia Andreea Anghel expose dans ce tutorial comment internationaliser son application PHP à l'aide de l'extension PEAR. L'internationalisation consiste à rendre une application compatible aux différents langues que l'on souhaite supporter. Il est toujours possible de ne changer que les textes pour assurer la traduction de la langue mais cela n'est pas très abouti et peu professionnel. En effet l'internationnalisation dans sa globalité demande également de supporter le format des nombres, des monnaies ainsi que des dates et heures.
L'extension PEAR met à disposition des classes afin de gérer ces fonctionnalités très simplement et ce tutoriel vous en donne des exemples d'utilisation tout aussi simples.

Lire l'article

Août 2008 – PHP Index: Dotclear 2.0.1

Une version 2.0.1 de Dotclear est disponible au téléchargement depuis quelques jours. Cette version publiée de façon anticipée permet essentiellement la correction d'un bug depuis l'import de Dotclear 1.2.

Il est à noter que le bug de l'import depuis Dotclear 1.2 ne concerne que le module d'import depuis la base de données, l'import depuis un fichier texte fonctionnant correctement.

Pour plus d'information, vous pouvez consulter l'annonce sur le blog Dotclear.

Août 2008 – PHP Index: Création dynamiques de graphiques avec PHP et GDChart

Sur le site de Zend, Vikram Vaswani a récemment publié un tutoriel sur l'utilisation conjointe de PHP et de GDChart pour générer dynamiquement des graphiques et des cartes.

Ayant pu observer que la génération d'images complexes avec l'extension GD de PHP devient rapidement fastidieuse et compliquée, il propose un tutoriel complet sur l'installation et l'utilisation de l'extension GDChart, exemples à l'appui.

Août 2008 – Lapin Blanc: Nouvelle offre d’hébergement à bas prix chez Gandi : installez votre serveur web

Gandi m’a gentiment fourni une invitation à la bêta de leur service d’hébergement. Je compte y passer ce blog et voir comment se comportent les frameworks Symfony et Django sur ces serveurs virtualisés et scalable. J’ai donc pris une part (6€ HT/mois) afin d’y installer un serveur web composé d’Apache, (...)

Août 2008 – sahid.funraill.org: Prechargement d’images en Javascript

Javascript, prechargement d’images (images loader)

Une fonction Javascript toute bete pour faire patienter vos visiteurs durant le chargement d’images un peu lourdes.

Exemple:

Source:

  1. preload = function (o, img_src, w, h) {
  2.   var img = new Image ();
  3.   img.onload = function () {
  4.     o.onload = null;
  5.     if (w) o.width  = w;
  6.     if (h) o.height = h;
  7.     o.src = img.src
  8.   };
  9.   img.src = img_src;
  10. }

preload.js

Ajout d’un effet de fade-in à la fonction (utilisé ici)

Exemple:

Source:

http://sahid.funraill.org/wp-content/uploads/2008/09/preload-with-fadein.html

Usage:

  1. <!– sans redimensionnement –>
  2. <img src="images/ajax-loader.gif" onload="preload (this, ‘images/larges/big.jpg’)"/>
  3.  
  4. <!– avec redimensionnement homothetique sur la largeur –>
  5. <img src="images/ajax-loader.gif" onload="preload (this, ‘images/larges/big.jpg, 300′)"/>
  6.  
  7. <!– avec redimensionnement homothetique sur la hauteur –>
  8. <img src="images/ajax-loader.gif" onload="preload (this, ‘images/larges/big.jpg, null, 300′)"/>
  9.  
  10. <!– avec redimensionnement –>
  11. <img src="images/ajax-loader.gif" onload="preload (this, ‘images/larges/big.jpg, null, 300, 400′)"/>

Août 2008 – PHP Index: eZ Publish 4.0.1, 3.10.1 et 3.9.5

eZ System a publié une nouvelle série de mise à jour pour son CMS, eZ Publish.

Ces versions apportent un très grand nombre de correctifs et il est fortement recommandé d'effectuer la mise à niveau. eZ System a aussi annoncé que les versions 3.9 et 3.10 seraient problablement les dernières de la série 3.x. Pour toute nouvelle installation, il est recommandé d'utiliser la branche 4.x.

eZ Publish 4.0.1
Télécharger
Changelog

eZ Publish 3.10.1
Télécharger
Changelog

eZ Publish 3.9.5
Télécharger
Changelog

Août 2008 – PHP Index: Propel 1.3 & Symfony 1.2

Après deux années de développement, la version 1.3 de Propel est désormais disponible.

Parmi les nouveautés nous trouvons entre autres :

  • L'utilisation de PDO : Propel utilisera PDO pour gérer les connexions à la base de données, ce qui améliorera les performances.
  • La manipulation des dates : Le support des dates (via la classe DateTime) à été amélioré avec PHP 5.2.
  • Les valeurs par défaut : Vous pouvez maintenant utiliser des expressions pour les valeurs par défaut dans le schéma de la base de données.

De plus, la nouvelle version du Framework Symfony (1.2) utilisera propel 1.3 par defaut. Il sera cependant possible d'utiliser Doctrine 1.0 (prévu pour le 1er septembre 2008) avec Symfony 1.2 grâce à sfDoctrinePlugin.

Télécharger Propel 1.3
Le site officiel de Symfony

Août 2008 – Apprendre-PHP.com: Propel 1.3, Doctrine 1.0, Symfony 1.2 et MySQL 6.06

Cela faisait depuis plus d'un an que la version 1.3 de l'ORM Propel était en mode Release Candidate mais le jour est enfin arrivée. L'équipe de Propel a enfin annoncé la sortie stable de la version 1.3. Cette mise à jour est véritablement une grande avancée pour le projet Propel car elle...

Août 2008 – Kamelot Blog: PEAR::Pager tutorials : Pager and Smarty

Ce texte est une des traductions d'une série d'articles de Lorenzo Alberton

Pager and...

Je pense avoir déjà parlé de tous les cas de figure que vous pourriez rencontrer où il est utile d'utiliser PEAR::Pager, mais j'ai reçu de nombreux mails me demander comment utiliser le pager pour faire ceci ou cela.

Les 2 questions les plus récurrentes sont

a) Comment je peux utiliser Pager avec moteur_de_template?

et

b) Comment je peux utiliser Pager_Wrapper avec AJAX?"

En espérant réduire le flot de mails, je vais présenter 2 exemples complets.

La deuxième à trouvé réponse ici : PEAR::Pager tutorials : Pager_Wrapper and Ajax

Pager and Smarty

Les exemples suivants utilisent le populaire moteur de template Smarty, mais vous pouvez facilement transposer à un autre. N'hésitez pas à tester cette transposition et la poster en commentaire.

Premièrement on créée une instance de Pager, ensuite nous assignons les données paginées et les liens à certaines variables du template:

[php]
<?php
require_once 'Pager.php';

// tableau des données à paginer
$liste_des_elements = array(...);

$option_du_pager = array(
    'mode'     => 'Sliding',
    'delta'    => 3,
    'perPage'  => 10,
    'itemData' => $liste_des_elements,
);
$pager =& Pager::factory($option_du_pager);

//On récupère les données paginées dans la variable $data
$data = $pager->getPageData();
if (!is_array($data)) {
    $data = array();
}

//On considère que vous avez déjà instancié Smarty dans $smarty

//Alors on assigne les données et les liens aux variables du template
$smarty->assign('liste_des_elements', $data);
$smarty->assign('pager_links', $pager->links);
$smarty->assign(
    'page_numbers', array(
        'current' => $pager->getCurrentPageID(),
        'total'   => $pager->numPages()
    )
);

$smarty->display('page.tpl');
?>

Et voici le template:

[smarty]
...

{if $page_numbers.total > 1}
(page {$page_numbers.current} / {$page_numbers.total})<br />
{$pager_links}
{/if}

<ul>
{foreach item=row from=$liste_des_elements}
    <li>{$row}</li>
{/foreach}
<ul>

...

Comme vous pouvez le voir, il n'y a rien de difficile.

Complet et clair.

Août 2008 – Kamelot Blog: PEAR::Pager tutorials : Pager_Wrapper et Ajax

Je pense avoir déjà parlé de tous les cas de figure que vous pourriez rencontrer où il est utile d'utiliser PEAR::Pager, mais j'ai reçu de nombreux mails me demander comment utiliser le pager pour faire ceci ou cela.

Les 2 questions les plus récurrentes sont

a) Comment je peux utiliser Pager avec _moteur_de_template_ ?

et

b) Comment je peux utiliser Pager_Wrapper avec AJAX?"

En espérant réduire le flot de mails, je vais présenter 2 exemples complets.

La première à trouvé réponse ici : PEAR::Pager tutorials : Pager and Smarty

Pager_Wrapper and AJAX

Ce second exemple montre comment utiliser Pager_Wrapper pour paginer les données d'une DB et utiliser HTML_AJAX pour les afficher.

Ce texte est une des traductions d'une série d'articles de Lorenzo Alberton

Le fichier html est identique que celui montré dans le tutorial Pager + AJAX :

[html]
<html>
<body>
<h1>Exemple de PEAR::Pager avec AJAX</h1>

<script type="text/javascript" src="server.php?client=all"></script>

<div id="cible_dont_on_modifie_le_contenu">Je suis là cible</div>

<script type="text/javascript">
    HTML_AJAX.replace('cible_dont_on_modifie_le_contenu', 'testdata.php');
</script>

</body>
</html>

Le fichier testdata.php est un simple script qui récupère des données dans une base de donnée à l'aide de Pager_Wrapper.

L'affichage de ce script va remplacer le contenu du div dans le premier fichier html.

Nous ajoutons aussi la date courante pour prouver qu'on affiche des données "fraîche" et qu'on reconstruit le contenu à chaque appel (C'est à dire à chaque fois qu'on clique sur un lien de navigation)

[php]
<?php
//le fichier Pager_Wrapper a été placé où on peut l'inclure
require_once 'Pager_Wrapper.php';
require_once 'MDB2.php';

//supposons qu'on a une connexion dans  $db

$option_du_pager = array(
    'mode'     => 'Sliding',
    'append'   => false,  //ne pas ajouter les paramètres GET aux url générées
    'path'     => '',
    'fileName' => 'javascript:HTML_AJAX.replace(\'target\',\'testdata.php?pageID=%d\');',  //Pager remplace "%d" par le n° de la page...
    'perPage'  => 10, //afficher 10 éléments par page
    'delta'    => 1,
    'itemData' => $data,
);
$statement = 'SELECT prod_name, prod_description FROM products';

$paged_data = Pager_Wrapper_MDB2($db, $statement, $option_du_pager);
if (PEAR::isError($paged_data)) {
    //Ouch 'y a un stuut, reglez le problème.
}

//affichage des résultats
echo '<p>Ce conteneur est récupéré par un appel AJAX</p>';
echo '<p><span class="datetime">DateTime: '. date('Y-m-d H:i:s') .'</span></p>';
echo '<h3>Page ' . $paged_data['page_numbers']['current'] . '/' . $paged_data['page_numbers']['total'] . '</h3>';
foreach ($paged_data['data'] as $item) 
{
    echo '<strong>' . $item['prod_name'] . '</strong>: ' . $item['prod_description'] . '<br />';
}

//Affichage des liens
echo '<hr />'.paged_data['links'];
?>

En fait vous pouvez observer que c'est le même exemple qu'ici

mais avec quelques petits changement repris d'ici.

Août 2008 – PHP Index: IBM : Premiers pas avec CodeIgniter

Dans un article paru sur le site IBM destiné à des développeurs PHP avertis, Thomas Myer explique comment réaliser une application web minimaliste en 1 heure à l'aide du framework PHP CodeIgniter.

L'article commence par aborder les raisons d'utiliser un framework MVC, avant d'expliquer les avantages CodeIgniter dans cette catégorie. Viennent ensuite l'installation et la configuration de CodeIgniter, puis la création d'un projet simple : la réalisation d'une application avec un formulaire de contact de A à Z.

Août 2008 – tigrou/pwet.fr: Sécuriser un site eZ Publish

Clochix a publié cette semaine deux articles à propos de sécurité; le premier sur les CMS en général et le second plus spécifiquement sur eZ Publish. Le problème pointé est l'affichage par défaut de tous les objets dans eZ Publish par les templates par défaut même lorsque cela ne devrait pas arriver. La solution (simple) proposée est de faire des surcharges s'appliquant en dernier et n'affichant rien pour éviter d'afficher tout ce qui n'a pas été prévu. Évidemment il est toujours mieux de restreindre les droits, mais c'est un bon dernier rempart à la divulgation d'informations...

Il y a évidemment d'autres éléments à considérer et j'en oublie probablement d'ailleurs mais voici ceux qui me viennent à l'esprit.

Au niveau template, il faut toujours penser à utiliser l'opérateur wash(), il permet de s'assurer que tous les caractères spéciaux sont échappés pour produire du code XHTML valide mais aussi pour éviter des attaques de type XSS si surtout votre site propose aux internautes de contribuer.

Au niveau système pour un site en production, seul le répertoire var devrait permettre l'écriture au serveur web. On peut aussi restreindre les droits de l'utilisateur MySQL utilisé par eZ Publish pour limiter la portée d'une éventuelle mauvaise utilisation de ce compte.

On peut aussi penser à désactiver les modules et/ou les vues inutiles pour un siteaccess donné. Par exemple, pour ce site, le fichier site.ini.append.php de mon siteaccess correspondant au front comporte la configuration suivante :

[SiteAccessRules]
Rules[]
Rules[]=access;enable
Rules[]=moduleall
Rules[]=access;disable
Rules[]=module;user/register
Rules[]=module;user/forgotpassword
Rules[]=module;user/activate
Rules[]=module;user/success
Rules[]=module;ezinfo 
 

Ces quelques lignes désactivent quelques vues du module user ainsi que le module ezinfo qui sont accessibles aux utilisateurs anonymes alors qu'ils ne me sont pas nécessaires. La vue ezinfo/about en particulier donne des informations sur les extensions activées et surtout sur la version d'eZ Publish ce qui permet de savoir à quoi est potentiellement vulnérable le site. Dans tous les cas, il vaut mieux être à jour, les versions 4.0.0, 3.10.0 et 3.9.4 sont vulnérables à quelques failles connues.

Il faut aussi penser à nommer les fichiers de configuration en .ini.append.php et à encadrer le contenu par des commentaires PHP ce qui évite toute possibilité de lecture via un accès direct par le serveur web. À ce niveau, avoir un site eZ Publish en mode Virtual Host devrait aussi apporter un gain en cachant presque complètement l'arborescence "physique" du site.

Enfin au niveau des extensions il faut évidemment penser à échapper toutes les données inconnues avant de l'utiliser dans une requête SQL (ça n'est pas spécifique à eZ Publish !), la méthode escapeString() de la classe eZDBInterface est faite pour ça.

Août 2008 – Kamelot Blog: PEAR::Pager tutorials. Navigation avec pagination et Ajax

Ce texte est une des traductions d'une série d'articles de Lorenzo Alberton Suite de PEAR::Pager tuto : Navigation avec pagination et Javascript simple

Comme vous avez pu le voir, the trick was setting the path parameter to an empty string and the fileName parameter to a javascript link, avec l'habituel marqueur "%s" pour le pageID.

Exemple #2: On veut de l'AJAX! On veut de l'AJAX!

Ok, maintenant que vous avez vu les bases, vous devriez avoir tous les éléments à aller plus loin.

Mais si vous êtes paresseux et voulez le voir quand même, voici un exemple sur la façon de faire la même chose que ce que nous avons vu avant, cette fois utilisant des appels AJAX chercher seulement les données utiles pour la page montrée.

Dans cet exemple, j'utilise la librairie PEAR::HTML_AJAX (docs):

Si vous ne pouvez pas attendre voyez cette démo, c'est l'exemple en fonctionnement, regardons comment il est fait :

1) Le fichier html:

nous incluons les fichiers js dynamiques (server.php) pour traiter les demandes AJAX, et appellons HTML_AJAX.replace ("target","testdata.php"), ce qui remplacera le contenu du DIV cible par le rendu du script testdata.php en utilisant un appel d'AJAX.

[php]
<html>
<body>
<h1>PEAR::Pager exemple avec AJAX</h1>

<script type="text/javascript" src="server.php?client=all"></script>

<div id="target">Je suis la cible</div>

<script type="text/javascript">
    HTML_AJAX.replace('target', 'testdata.php');
</script>

</body>
</html>
2) Le fichier testdata.php:

c'est un simple script php qui récupère les données que vous désirez afficher (Dais cet exemple, 100 entiers) et les renvoie au Paginateur.

L'output de ce script remplacera le contenu du DIV cible dans le premier fichier html.

Nous affichons également la date et l'heure courante pour nous prouver que les données sont « fraîches » et construites à chaque appel (c.-à-d. chaque fois que vous cliquez sur un lien de navigation).

[php]
<?php
require_once 'Pager.php';
$data = range(1, 100); //un tableau de données à paginer
$pager_params = array(
    'mode'     => 'Sliding',
    'append'   => false,  //ne pas ajouter les paramètres GET
    'path'     => '',
    'fileName' => 'javascript:HTML_AJAX.replace(\'target\',\'testdata.php?pageID=%d\');',  //Pager replaces "%d" with the page number...
    'perPage'  => 10, //afficher  10 item par page
    'delta'    => 1,
    'itemData' => $data,
);
$pager = & Pager::factory($pager_params);
$n_pages = $pager->numPages();
$links = $pager->getLinks();
echo '<p>Ce containeur est rempli avec un appel AJAX</p>';
echo '<p><span class="datetime">DateTime: '. date('Y-m-d H:i:s') .'</span></p>';
echo '<h3>Page '. $pager->getCurrentPageId() .'</h3>';
foreach ($pager->getPageData() as $item) {
    echo 'Item '. $item .'<br />';
}
echo '<hr />'.$pager->links;
?>
3) Finallement, le fichier server.php :

nous créons une instance de HTML_AJAX_Server pour livrer les les deux les bibliothèques de Javascript et pour traiter les demandes d'AJAX des navigateurs.



[php]
<?php
include 'HTML/AJAX/Server.php';

$server = new HTML_AJAX_Server();
$server->handleRequest();
?>

Août 2008 – PHPortail: DotClear 2.0 (28/08/08)

La nouvelle version de Dotclear est sortie avec plus de 2200 changements dans le code et 326 tickets fermés.

Dotclear est un moteur principalement dédié aux blogues.

Les principales...

Août 2008 – PHPortail: Symfony camp, les 12 et 13 septembre 2008, aux Pays-Bas (28/08/08)

Cette année encore, le DOP organise un camp Symfony. L'événement a lieu les 12 et 13 septembre 2008. C'est une occasion unique pour rencontrer la communauté.

Le camp commencera par une...

Août 2008 – PHPortail: Méthodes magiques : __call() (28/08/08)

« PHP a fait un grand pas en avant en matière de programmation orientée objet avec sa version 5. Depuis cette version, il permet d'implémenter des méthodes au comportement prédéfini par PHP....

Août 2008 – PHPortail: Méthodes magiques : __set() et __get() (28/08/08)

« PHP a fait un grand pas en avant en matière de programmation orientée objet avec sa version 5. Depuis cette version, il permet d'implémenter des méthodes au comportement prédéfini par PHP....

Août 2008 – PHPortail: Configurer l'en-tête expires du serveur Web (28/08/08)

"Lire un livre sur comment optimiser son site web c'est bien, appliquer les conseils qui s'y trouvent c'est encore mieux. Parmi les 14 bonnes pratiques, 3 peuvent être appliquées très rapidement...

Août 2008 – PHPortail: Cachez vos sessions sans ennuyer vos utilisateurs (28/08/08)

Memcache est de plus en plus utilisé pour stocker des informations rapides et transitoires pour les applications Web. Memcache assure un service distribué et rapide de cache, mais n'arrive pas...

Août 2008 – PHPortail: MySQL 5.0.67 (28/08/08)

MySQL 5.0.67, la dernière version du système de base de données Open Source, a été publiée. Cette édition communauté est disponible en format source et binaire, pour de nombreuses...

Août 2008 – PHPortail: PHP 4 est mort, vive PHP 5! (28/08/08)

PHP 4 a vu sa toute dernière version sortir dernièrement : PHP 4.4.9 est la dernière et finale version de la lignée des PHP 4. Cette lignée a été baptisée stable depuis le 22 mai 2000, et a...

Août 2008 – PHPortail: Sécurité : Utiliser GNUPG (28/08/08)

Pour chiffrer des données, il existe la bibliothèque mcrypt, intégrée à PHP. Mais il existe aussi l'extension GnuPG qui est un outil pour signer et chiffrer des messages. C'est une option...

Août 2008 – PHPortail: PHP 5.3.0alpha1 (28/08/08)

Johannes Schlützer publie la version alpha1 de PHP 5.3.0. C'est la première version en vue de la finalisation de PHP 5.3.0.

Les nouveautés de cette version :

* Espaces de noms...

Août 2008 – PHPortail: Sécurité : Suhosin 0.9.27 (28/08/08)

Suhosin est un patch de sécurité avancé pour PHP, qui protège la plate-forme contre des vulnérabilités connues et inconnues. Il propose notamment des directives de configuration...

Août 2008 – PHP Index: Devshed : Pagination avec CodeIgniter

Sur le site Developper Shed, Alejandro Gervasio propose un tutoriel sur CodeIgniter pour l'affichage paginé d'une liste de résultats en provenance d'une base de données MySQL.

Ce tutoriel est composé de quatre parties :

Il est à noter que ce tutoriel fait suite à deux tutoriels parus précédemment :

Août 2008 – Kamelot Blog: Samalyse, Ressources PHP/PEAR

Il y en a comme moi qui traduisent, d'autres écrivent directement.

Voici 4 articles de plus faite chez Samalyse.

Cet exemple montre comment lier deux tables de données avec le composant Structures_DataGrid.

Ce tutoriel explique comment facilement générer des tableaux HTML à partir de données SQL, avec tri et pagination, en couplant deux composants PEAR : Structures_Datagrid et DB_Dataobject.

Librairie d'indexation de contenu XML. Ce composant permet de diminuer les temps d'accès aux données XML.

Contribution permettant d'utiliser des fichiers XML avec la librairie de gestion multi-langues Translation2.

Août 2008 – PHP Index: Configurer la barre de débuggage avec Symfony 1.2

Un mini-tutoriel est disponible sur le blog de Symfony pour profiter de la possibilité de configurer entièrement la barre d'outil de débuggage, disponible depuis Symfony 1.2.

Cette nouvelle fonctionnalité permet notamment au développeur de choisir quelles seront les informations qui lui seront affichées et d'en ajouter de nouvelles.

Pour plus d'information, vous consulter consulter l'article sur le blog de Symfony.

Août 2008 – Sorcellerie Web: Komodo Edit

Puisque la question a été posée sur la liste de diffusion de django, voici quelques remarques sur l'éditeur que j'utilise et les raisons de mon choix.

komodo edit Il s'agit donc de Komodo Edit, qui succède depuis maintenant une bonne année à PSPad (qui succédait lui-même à Context). L'essentiel de mon activité de développement se fait au bureau sous Windows, mais je développe également chez moi sous Mac, après quelques années sous Linux. Je souhaitais un éditeur qui soit multi-plateformes afin de n'avoir qu'une interface à apprendre. Pour le reste, voici un résumé :

coloration syntaxique
Les formats supportés (et qui m'intéressent) sont PHP, SQL, HTML, XML, CSS, Python, Javascript, Django (gabarits). Ce qu'il me manque : INI qui est un format que j'utilise pour mes fichiers de configuration.
Auto-complétion
Et vraiment très bien faite. Lorsque l'on commence à taper un nom de fonction, komodo propose une liste de choix, puis une bulle contextuelle avec la liste des arguments. Outre les fonctions natives du language, Komodo supporte également les fonctions et méthodes du projet en cours, et est même capable de récupérer les informations depuis leur docblock, ce qui est une motivation pour les écrire systématiquement :)
completion d'import python sous komodo editC'est aussi très utile pour les directives d'importation en python, quand on ne connait pas encore par coeur l'arborescence des paquets et modules que l'on utilise.
Projets
La creation d'un projet se fait assez facilement, en sélectionnant le dossier concerné. Ceci donne un navigateur de fichier pour le dossier en question.
Edition multiple
Tout à fait vital pour moi, j'ai souvent une douzaine d'onglets ouverts !
Pliage de code
Pratique quand on cherche une méthode au sein d'une classe obèse, même si ça en vaut pas un bon navigateur de code
Chercher-remplacer
Dans le fichier en cours, la selection en cours, tous les fichiers du projet; et supporte les expressions régulières.
Mais un défaut quand même
Ca rame. Comparé à la plupart des éditeurs de texte, Komodo edit est très gourmand en mémoire. Si vous avez un très gros fichier à ouvrir, tel qu'un log ou un dump SQL, mieux vaut essayer un éditeur plus léger.

Août 2008 – Lapin Blanc: Les vacances !

Après 5 mois chez Ankama, enfin les vacances ! Ce fût l’occasion (même si ils élèvent des chiens) de rencontrer (même si ils ont des franges) pas (même si ils sont fan de VBS) mal (même si ils veulent restaurer la grandeur de l’Empire austro-hongrois) de gens sympas (oééééé) et de travailler sur des (...)

Août 2008 – Glagla.org: Profils a mettre à jour !

arg ! Je dois mettre à jour d’urgence :

  • mon cv
  • mon profil linkedin
  • mon profil 6nergies (ou pas …)
  • mon profil viadeo
  • mon profil facebook \o/

Article original publié sur Glagla Dot Org. Tous droits réservés.

Profils a mettre à jour !