Live geek or die tryin'

PHP: Pagination Avec Symfony

Bienvenue,

Dans ce tutoriel je vais vous expliquer comment réaliser une pagination, avec Symfony 1.4 et Doctrine.

Tout d’abord, supposons qu’on a un module user dans l’application admin.

Avant la pagination, côté action.class.php

Pour récupérer la liste des utilisateur, il faut exécuter une requête $qUsers dans action.class.php:

$qUsers = Doctrine_Query::create()->from("User u");
$this->aUsers = $qUsers->fetchArray();

Du côté du template ça sera ça:

<table>
  <thead>
    <tr>
      <td><?= __("Nom") ?></td>
      <td><?= __("Prénom") ?></td>
      <td><?= __("Pseudo") ?></td>
      <td><?= __("E-mail") ?></td>
    </tr>
  </thead>
  <tbody>
<?
foreach($aUsers as $user) {
?>
    <tr>
      <td><?= $user["last_name"] ?></td>
      <td><?= $user["first_name"] ?></td>
      <td><?= $user["pseudo"] ?></td>
      <td><?= $user["email"] ?></td>
    </tr>
<?
}
?>
  </tbody>
</table>

Mise en place de la pagination

Dans actions.class.php, juste après notre requête, on doit:

Instancier un objet sfDoctrinePager

$this->pager = new sfDoctrinePager('user', 3);

Et lui donner deux paramètres: un nom, et le nombre de résultats à afficher par page.

Lui préciser la requête pour récupérer les résultats

Oui, l’objet sfDoctrinePager ne devinera pas ce dont on a besoin, on va donc lui donner notre requête, $qUsers dans notre cas:

$this->pager->setQuery($qUsers);

Lui demander d’afficher la première page par défaut:

$this->pager->setPage($this->getRequestParameter('page', 1));

Initialiser!

$this->pager->init();

Du côté du template

On commence par vérifier si on a besoin de la mise en page, au cas où le nombre des résultats est inférieur au nombre maximum d’éléments par page, 3 dans notre exemple.

if( $pager->haveToPaginate() ){
}

Ensuite, on crée un conteneur pour les numéros de pages, et on fait un lien pour aller à la première page, et un autre à la dernière.

<table>
  <tr>
    <td>
      <a href="<? url_for('user/index?page='.$pager->getFirstPage()) ?>"></a>
    </td>
    <td>
      <a href="<? url_for('user/index?page='.$pager->getLastPage()) ?>"></a>
    </td>
  </tr>
</table>

Ouais, les <table> c’est le mal, mais ce n’est qu’un exemple, et ça m’évite de faire du CSS. #jailaflemme

Maintenant, entre les deux liens, on fait un foreach pour parser les liens vers les autres pages.

Vous pouvez aussi mettre des liens pour la page précédente, et la page suivante, en utilisant respectivement les méthodes getPreviousPage() et getNextPage(). ;)

<? foreach ($pager->getLinks as $page) : ?>
<td>
  <?php echo ($page == $pager->getPage()) ? $page : "<a href='" . url_for('user/index?page='.$page); "'>". $page ."</a>" ?>
</td>
<? endforeach; ?>

Explications:

  • On récupére la liste des liens avec le foreach
  • Ensuite on commence à parser les liens
  • A quoi sert la vérification? Tout simplement à ne pas donner de lien au numéro de page sur laquelle on est!

Et voilà, c’est fini.

J’espère que cet article vous a été utile, n’hésitez pas à laisser des commentaire au cas où vous avez des remarques, suggestions, ou corrections. :)

Vous pouvez me suivre sur Twitter, des tutoriels comme celui ci y en aura encore tant que j’utilise Symfony.

Les Images Hébergées Sur Imageshack Ne S’affichent Plus

En visitant mon blog ce matin, j’ai remarqué que les images de celui ci ne s’affichaient pas, on voyait à la place une affreuse grenouille bloquée dans une glace.

Après une recherche, on dirait que Imageshack.us a changé sa politique, et oblige les utilisateurs a s’enregistrer et se logger, ou les propriétaires des sites à enregistrer leur domaine, pour voir les images.

Ce changement de politique soudain survient sans avertissement, et donc beaucoup de sites se transforment du jour au lendemain en une mare de grenouilles.

Pour enregistrer un domaine, il faut se rendre sur la page Register Domain, page qui est d’ailleurs très mal placée et difficile à trouver.
Il faut ensuite remplir le formulaire et attendre que le site soit validé par l’équipe de l’hébergeur.
Je ne sais pas combien de temps ça prend vu que je viens d’envoyer le formulaire, mais je vous tiendrais au courant.
[Edit: Mon domaine a été validé et les images apparaissent, ça a donc pris moins de 9 heures.]

Ce n’est pourtant pas la première fois que Imageshack me surprend, j’ai déjà été choqué de voir que toutes mes photos étaient publiques par défaut.

Je pense qu’il est temps de changer d’hébergeur ou d’héberger mes photos sur le même serveur que le blog.

PHP: Krumo, Une Alternative à Print_r() Et Var_dump()

Edit du 24/08/2012: var_dump() couplée à Xdebug s’avère plus pratique

En cherchant un moyen pour afficher print_r() avec une mise en page, je suis tombé sur Krumo, une classe PHP qu’on peut utiliser à la place, et qui offre une mise en page bien plus compréhensible par les humains que nous sommes.

Présentation

Krumo est un remplacement pour print() et var_dump(). Autrement dit, Krumo est un outil de débogage (initialement pour PHP4/PHP5, maintenant pour PHP5 seulement), qui affiche les informations d’une variable PHP de manière structurée.

Beaucoup de développeurs utilisent print_r() et var_dump() pour débugger. Bien que ces classes ont été crées pour présenter une varible de façon lisible par l’humain, ce n’est malheureusement pas le cas. Krumo est une alternative: elle fait le même travail, mais elle présent l’information plus esthétiquement en utilisant du CSS et du Javascript.

Krumo offre non seulement une présentation plus propre, mais aussi des fonctionnalités intéressantes qu’on verra plutard.

Téléchargement

Rendez vous sur le site officiel: Krumo on SourceForge.net.
Ou cliquez sur ce lien pour télécharger la dernière version (15/02/2011): krumo_0.2.1a_PHP5-Only.zip.

Installation

L’installation est simple et classique, il suffit d’extraire le dossier de Krumo sur votre serveur et de l’inclure dans votre script (ou bootstrap).
Exemple:

require_once(dirname(__FILE__) . '/krumo/class.krumo.php');

Notez que vous n’êtes pas obligés de mettre tous les fichiers dans le répertoire krumo/, seuls class.krumo.php, krumo.ini, krumo.js et le dossier skins/ sont nécessaires.

Paramétrage (facultatif)

Vous pouvez jeter un coup d’œil sur krumo.ini, pour:

Changer de skin

[ skin ]
    selected = "green"

La valeur de selected doit être le nom d’un sous-dossier du dossier skins/.

Indiquer le chemin du dossier où Krumo est installé.

url = "http://www.dinduks.com/Krumo/"

Et cela pour rendre les images des skins accessibles sur le Web.

Utilisation

Voici un exemple basique:

krumo(array('a1'=> 'A1', 3, 'rouge'));

Comme vous le remarquez, Krumo marche de la même manière que les classes qu’elle est censée remplacer.

Elle peut aussi afficher plusieurs variables:

krumo($_SERVER, $_ENV);

Et possède plusieurs méthodes statiques, par exemple:

// Équivalent à print_r(debug_backtrace());
krumo::backtrace();

// Affiche tous les fichiers inclus (ou requis)
krumo::includes();

// Affiche toutes les fonctions incluses
krumo::functions();

// Affiche toutes les classes déclarées
krumo::classes();

// Affiche toutes les constantes définies
krumo::defines();

Vous pouvez activer ou désactiver Krumo grâce aux méthodes suivantes:

krumo::enable();
krumo::disable();

Exemples

Vous pouvez voir des exemples d’utilisation sur le site officiel de Krumo.

Conclusion

Krumo permet non seulement de mieux présenter les tableaux PHP, mais aussi d’accéder à d’autres informations plus facilement, parfois méconnues par les développeurs.
Pour ma part, cette classe a mérité sa place dans mes dossiers lib/.

Je vous invite à le tester et vous faire une idée. ;)

Liens

Apprenez en plus sur le site et la doc officiels:

Wampee, La Version Portable De Wampserver

Alors qu’Internet regorge de versions portables de WAMP, telles que Mov’Amp ou encore XAMPP, Wampserver a récemment publié la deuxième bêta de la version portable de sa plate-forme Open Source, Wampee.

L’intérêt de celui-ci, et des WAMP portables en général, réside dans sa portabilité, ce qui veut dire qu’il ne requiert pas d’installation, et peut être utilisé à partir de n’importe quel support amovible: disque-dur externe, clé USB, ou encore Dropbox.

Vous pouvez télécharger Wampee sur Wampserver.com

PHP: Récupérer Le Contenu D’une Page Web Avec cURL

Bonjour,

Je vais à travers ce tutoriel, vous montrer comment utiliser concrètement cURL avec PHP, en récupérant une description à partir de Wikipedia.
Vous pouvez retrouver le code commenté en bas de l’article.

cURL (abréviation de Client URL Request Library) est une interface en ligne de commande destinée à récupérer le contenu d’une ressource accessible par un réseau informatique. (source: Wikipedia)

Installer cURL

Sous Linux il suffit d’installer le paquet php5-curl: sudo apt-get install php5-curl pour les distributions dérivées de Debian.
Et de redémarrer Apache: sudo /etc/init.d/apache2 restart.

Sous Windows cURL est disponible avec WAMP.
Il faut cependant l’activer en décommentant la ligne ;extension=php_curl.dll (enlever le point virgule (;) au début de ligne) dans le fichier php.ini.

Pour les hébergeur de sites, cURL est activé sur la plupart d’entre eux.

Récupérer la page

$wikipediaURL = 'http://fr.wikipedia.org/wiki/Megadeth';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $wikipediaURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, 'Le blog de Samy Dindane (www.dinduks.com)');
$resultat = curl_exec ($ch);
curl_close($ch);

Explications:

  • On initialise cURL avec curl_init();
  • Oui lui fourni l’url de la page à récupérer
  • On lui demande de ne retourner la page curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  • On fournit un User Agent avec une description de notre script, pour ne pas être identifié en tant que bot malicieux. (pas obligatoire dans tous les cas)
  • On exécute la requête qui nous retourne le contenu de la page dans un tableau.
  • Et finalement on ferme la connexion cURL.

Vous pouvez maintenant faire un echo $resultat; pour afficher le contenu récupéré.

Passer des cookies

Au cas où le site source demanderait des cookies, récupérez les (à partir des entêtes HTTP que vous envoie la page), et passez les de cette manière:

$cookies = "foo=bar";
curl_setopt($ch, CURLOPT_COOKIE, $cookies);

Jusque là notre variable $resultat contient le code HTML brut de la page. Il faut alors récupérer la section qui nous intéresse, et c’est la partie la plus intéressante de ce tutoriel. :)

Récupérer la description

On va utiliser pour cela la classe DOMDocument de PHP5. On instancie un objet DOMDocument et on charge le contenu de la variable $resultat dans cet objet:

$wikipediaPage = new DOMDocument();
$wikipediaPage->loadHTML($resultat);

On peut maintenant manipuler $wikipediaPage en tant que contenu DOM.
Il faut tracer notre chemin dans ce labyrinthe de balises, mais avant, jetons un coup d’œil sur le code de notre page Wikipedia.

On remarque que la description se trouve entre les premières balises <p> de <div id="bodyContent">
On va alors accéder à cette <div> avec un foreach:

foreach($wikipediaPage->getElementsByTagName('div') as $div){
    if($div->getAttribute('id') == "bodyContent"){
    }
}

Et on récupère le contenu de la fameuse <p> dans une variable:

$description = '<p>' . $div->getElementsByTagName('p')->item(0)->nodeValue. '</p>';

Une petite explication s’impose:

  • Avec foreach on parcours toutes les balises <div>
  • Si leur (attribut) id est bodyContent, on récupère le contenu (nodeValue) de la première (item(0)) balise <p>.

On enlève maintenant la syntaxe propre à Wikipedia, les ancres ([1], [2]) et les virgules qui les suivent par exemple.

$description = preg_replace('/\[[0-9]*\][,]|\[[0-9]*\]/', '', $description);

Je précise que cette expression régulière n’est pas définitive et qu’elle est sujette à l’amélioration.

Un echo $description; nous affiche la description et confirme que notre script a marché.
Ici on peut dire que le tutoriel est fini et qu’on a réussi à récupérer notre description. Mais.

Mais que faire s’il y a une <p> vide, ou un <p> dans la balise <table>, avant le <p> qui contient la description?
Il faut qu’on prenne nos précautions et prévoir les mauvaises surprises.

Prévoir les mauvaises surprises

Et cela en nettoyant $wikipediaPage (rappellez vous, notre object DOMDocument) du contenu indésirable.

Le code suivant doit être placé dans la condition avant la récupération de la description.

On va d’abord s’occuper des <p> vides:

$premierP = trim($div->getElementsByTagName('p')->item(0)->nodeValue);
while($premierP == '<br>' || $premierP == '<br></br>' || $premierP == ''){
    $div->removeChild($div->getElementsByTagName('p')->item(0));
    $premierP = trim($div->getElementsByTagName('p')->item(0)->nodeValue);
};
  • On travaille sur le contenu du premier <p>
  • trim() enlève les caractères invisibles du début et fin de la chaîne
  • Tant que son contenu est vide, ou égal à un retour à la ligne (exemple que j’ai personnellement rencontré)
  • On le supprime avec removeChild()
  • On passe au le <p> suivantet ainsi de suite

Au tour des tables qui m’ont posé problème, puisqu’on en a pas besoin dans cet exemple, on va tout simplement les purger.

try{
    foreach( $div->getElementsByTagName('table') as $table ){
        $div->removeChild($table);
    }
} catch(Exception $e){
}

La requête est simple, mais pourquoi un try/catch?
Parce que dans certains cas, l’élément <table> n’existe pas et PHP retourne une erreur, erreur dont on peut se passer volontiers.
(en plus c’est mon premier try/catch en php :D)

Ce guide est terminé et j’espère qu’il vous a été utile. N’oubliez pas que ce n’est qu’un exemple et qu’il faudra le modeler selon vos besoins.
Je vais de ma part l’améliorer au fur et à mesure que je découvre cURL.

Vous pouvez télécharger le code commenté ici: Pastebin.com

N’hésitez pas à laisser vos retours, suggestions ou corrections par commentaire. :)
Je vous dis à bientôt.