Utiliser un sélecteur CSS jQuery en PHP avec phpQuery

Mars 2013

Si vous utilisez jQuery, vous devez être familier avec le sélecteur CSS qu'on utilise pour sélectionner des éléments dans la structure d'une page web (le DOM).

Et bien phpQuery est une classe qui permet d'utiliser exactement le même sélecteur pour traiter du code HTML ou XML en PHP ! Cette bibliothèque est basée sur l'extension PHP DOM (qui est le parser XML standard en PHP 5), et y ajoute une surcouche permettant de naviguer dans l'arborescence du DOM via un sélecteur CSS.

Les avantages sont nombreux :

  • Si vous connaissez déjà le sélecteur jQuery, vous n'aurez pas besoin d'apprendre à utiliser d'autres outils comme xPath
  • On écrit beaucoup moins de code, car on évite de parcourir les noeuds du DOM à la main (avec des boucles, des getElementsById, element.parentNode...)

Télécharger & installer phpQuery

Première étape, allez sur le site de phpQuery, hébergé sur google code : http://code.google.com/p/phpquery/downloads/list. Cliquez sur Download, et téléchargez le package. Il y en a plusieurs, moi j'utilise le "onefile" qui est le plus pratique si vous ne comptez pas modifier le code, car tout le code est contenu dans un seul fichier.

Prérequis

Pour pouvoir utiliser phpQuery, vous devez utiliser au minimum PHP 5 qui contient nativement l'extension DOM sur laquelle phpQuery est construit. Si vous utilisez encore PHP 4, vous ne pourrez pas faire fonctionner phpQuery.

Aspirer une page web

phpQuery est très pratique pour extraire des données d'une page web, prenons par exemple cette page minimaliste (que j'ai enregistré dans un fichier nommé sample.html):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>Page d'exemple xHTML</title>
</head>
<body>
	<div id="header">
		Lorem ipsum dolor site amet
	</div>
	<div id="content">
		<h1>Easter in South Park</h1>
		<p>Bla bla bla...</p>
		<p><img src="http://i.imgur.com/ucpvn.jpg" alt="South park" /></p>
	</div>
	<div id="footer">
		Copyright <b class="copyright-year">2013</b> <i>www.finalclap.com</i>
	</div>
</body>
</html>

Voilà comment analyser cette page avec phpQuery :

<?php
require 'phpQuery-onefile.php';
header('Content-Type: text/plain; charset=utf-8');

// Ouverture du fichier xHTML
$doc = phpQuery::newDocumentFileHTML('sample.html');

// Lecture dans le DOM avec phpQuery
echo "Titre de la page  : ".pq("head title")->text()             ."\n";
echo "Contenu du header : ".trim(pq("#header")->html())          ."\n";
echo "Image du contenu  : ".pq("#content img")->attr("alt")      ."\n";
echo "Copyright         : ".pq("#footer .copyright-year")->text()."\n";

// Boucler sur des éléments
echo "\n----------------------------\n";
echo "Liste des div dans le body :\n";
$elements = pq("body>div");
foreach( $elements as $element )
{
	echo " - ".pq($element)->attr("id")."\n";
}

// Debugger avec dumpTree (false pour désactiver l'affichage HTML)
echo "\n-----\nDebug\n\n";
pq("div:eq(1)")->dumpTree(false);
?>

Voici ce qu'affiche le code ci-dessus :

Titre de la page  : Page d'exemple xHTML
Contenu du header : Lorem ipsum dolor site amet
Image du contenu  : South park
Copyright         : 2013

----------------------------
Liste des div dans le body :
 - header
 - content
 - footer

-----
Debug

DUMP #0 
div#content
 - h1
 -  - Text:Easter in South
 - p
 -  - Text:Bla bla bla...
 - p
 -  - img

Vous pouvez voir qu'on peut utiliser toutes les fonctionnalités de jQuery. Il faut juste remplacer $ par pq. Comme dans jQuery, tout est chainable, car toutes les méthodes d'un objet phpQuery retournent un objet phpQuery.

Tout comme dans jQuery, lorsqu'on utilise une boucle (foreach) pour parcourir un tableau d'éléments, chaque élément reçoit un objet DOM natif. Pour en faire un objet phpQuery, il faut l'entourer par pq() (en d'autres termes, il faut l'envelopper dans du pq...). C'est l'équivalent du $(this) de jQuery.

Allez donc jeter un oeil sur cette page : supprimer les doublons avec excel.

Ce qu'il faut bien garder à l'esprit c'est que seules les fonctionnalités de manipulation du DOM (Tree Traversal) qui ont été implémentées dans phpQuery. Certaines fonctionnalités comme l'AJAX n'ont aucun sens en PHP, côté serveur.

Je vous conseille de consulter la documentation pour voir toutes les fonctions jQuery qui ont été portées sur phpQuery : http://code.google.com/p/phpquery/wiki/jQueryPortingState.

Mettre à jour du contenu HTML

Ce genre d'outil peut aussi s'avérer très utile pour importer ou maintenir du contenu HTML, comme les billets d'un blog Wordpress. On peut par exemple s'en servir pour mettre à jour tous les liens internes d'un site, en utilisant un sélecteur CSS pour traiter les liens (<a>) et restituer le code HTML modifié.

Alternatives à phpQuery

Il existe d'autres moyens de requête une arborescence XML, notamment xPath qui est géré nativement par PHP (new DOMXpath($DOMDocument)).

Mais il existe aussi Simple HTML DOM Parser qui se rapproche beaucoup de phpQuery, mais en plus léger, et avec une syntaxe un peu différente de cette de phpQuery (ils n'ont pas imité jQuery sur la forme (syntaxe), mais au niveau des fonctionnalités ça se vaut).

Vous pouvez aussi jeter un oeil à Ganon, qui se positionne entre phpQuery et Simple HTML DOM Parser, le site officiel le présente comme plus performant que phpQuery et aussi riche en fonctionnalités (une sorte de SimpleXML pour du HTML). Je n'ai pas testé.

Fini de lire cette page ? allez faire un tour ici : matte painting, ça peut vous intéresser.

0 commentaire
facultatif
Facebook Twitter RSS Email
Forum Excel
Venez découvrir le nouveau forum excel question/réponse à la stackoverflow.com !
Forum Excel
hit parade n'en a rien a foutre du W3C Positionnement et Statistiques Gratuites Vincent Paré