Archives pour 'php5'

Utilisation des filtres avec Symfony

30 janvier 2008

Voila encore une fonctionnalité peu connu qui me fait aimer ce framework.

Dans Symfony, quand le système reçoit une requête il exécute une série de filtre permettant un découpage logique efficace des actions à traiter. Ce qui est intéressant, c’est que l’on peut facilement intégrer ses propres filtres afin de modifier des comportements du framework.

Par exemple, si vous voulez logguer chaque accès sur toutes les pages de votre application (c’est un exemple … ok ?), rien de plus facile.

C’est une simple classe à mettre sous le dossier lib par exemple.

<?php
 
class accesslogFilter extends sfFilter
 
{
 
  public function execute($filterChain)
  {
    if ($this->isFirstCall())
        // on ne logue que le premier appel à une action
    {
 
      /*
      ici, on a accès à tous les objets de symfony
      $request = $this->getContext()->getRequest();
      etc ... permettant de tracer la requête,
      de savoir quel module on utilise ...
      */
 
      /*
      à vous de créer votre log (j'vais pas tout faire)
      */
    }
    $filterChain->execute();
  }
}

Il faut ensuite simplement activer votre filtre en ajoutant au fichier apps/myapps/config/filters.yml les lignes suivantes :

accesslog:
  class: accesslogFilter

Juste après le filtre de sécurité(security).

Simple non ?

Installer xdebug et KCachegrind sous Leopard

18 janvier 2008

Cet article fait suite au deux premiers écrits au sujet de l’installation de PHP5 et MySQL5 sous Léopard.

L’idée est de faire du profiling d’application PHP en utilisant xdebug et KCachegrind.

Installation de xdebug

Si vous avez correctement installé PHP aucun problème pour xdebug :
# sudo pecl install xdebug

Ajouter « zend_extension=/usr/local/php5/lib/php/extensions/no-debug-non-zts-20060613/xdebug.so »
à la fin du fichier php.ini suffira à activer l’extension. (attention, le chemin de xdebug.so peut être un peu différent mais il sera sous /usr/local/php5/lib/).

Vous pouvez d’ores et déjà utiliser xdebug comme décrit dans cet article chez Zend. Avec symfony, les traces de xdebug seront automagiquement intégrées dans les infos de débogages.

debogage symfony xdebug

installation de KCachegrind avec fink

Xdebug va permettre de faire du profiling d’application PHP. Mais afin d’exploiter les résultats obtenus, il nous faut un logiciel bien spécifique faisant partie de KDE : KCachegrind.

Pour installer KCachegrind, il faut d’abord installer fink (qui, par ailleurs vous permettra d’installer plein de logiciels open-source disponibles sous Linux). Le projet fink fournit un installeur qui fonctionne tout seul.

Pour le faire fonctionner avec le shell que j’utilise (bash, qui n’est pas le shell par défaut sous osx) j’ai dû ajouter cette ligne dans le fichier .profile à la racine de mon compte utilisateur :

. /sw/bin/init.csh

KCachegrind n’est pas disponible dans la version stable des paquets fournis, il faut passer en unstable.

Pour cela, il faut éditer le fichier /sw/etc/fink.conf et remplacer la ligne commençant par ‘Trees:’ par :

Trees: local/main stable/main stable/crypto unstable/crypto unstable/main

Il faut ensuite mettre à jour la base locale de fink en tapant les commandes suivantes :

# sudo fink selfupdate
# sudo fink index
# sudo fink scanpackages

La commande selfupdate va durer un certain temps et sollicitera votre connexion internet. Le programme vous posera des questions sur les miroirs à utiliser, si cela ne vous parle pas, choisissez les options par défaut.

Il faut enfin lancer l’installation de KCachegrind via la commande :

sudo apt-get install kcachegrind

Vous verrez apparaitre un message de ce type :

The following package will be installed or updated:
kcachegrind
The following 164 additional packages will be installed:
....

Ici, vous pouvez allez vous coucher et revenir le lendemain … il y en a en général pour plusieurs heures (il faut télécharger KDE notamment).

Et voila, vous pouvez maintenant lancer KCachegrind depuis le terminal (celui-ci ouvrira X11 automatiquement) :

# kcachegrind

installation de KCachegrind via les binaires de KDE

Une distribution complète de KDE4 pour mac os x est disponible ici. Le plus simple est de télécharger le torrent everything. Un peu de patience et beaucoup de place sur votre disque dur sont également nécessaires pour cette phase.

Une fois l’image téléchargée, montez la et lancer l’installeur kde.mpkg

Il va installer la base de KDE ainsi qu’une version de QT compilée pour os x puis l’ensemble de KDE.

Pour lancer KCachegring il faut aller chercher le .app dans /opt/kde4/bin ce que vous pouvez faire depuis le finder en tapant ce chemin après le raccourci clavier Pomme+Shift+V.

Et voilà !

Personnellement je préfère cette dernière méthode car elle permet de se passer de X11. Par contre, le paquet est un peu instable (il plante parfois aléatoirement sur l’ouverture des fichiers). Il faudra retourner sur la page du mainteneur pour obtenir les mises à jour.

Le seul souci restant est que KCachegrind ne trouve pas l’utilitaire dot pour générer les graphiques d’appels. Pour remédier à cela, si vous avez fink, il y a une solution (un peu rapide certes) :

# sudo apt-get install graphviz
# cd /bin
# sudo ln -s /sw/bin/dot .

paramétrage de xdebug

L’objectif est de paramétrer xdebug pour qu’à chaque page php demandée, il produise une trace permettant de faire notre profiling.

Il faut tout simplement ajouter les lignes suivantes à la fin du php.ini :

xdebug.profiler_enable=1
xdebug.profiler_output_dir=
/Users/olivier/tmp

et bien sur créer le répertoire /Users/olivier/tmp

# mkdir /Users/olivier/tmp
# chmod 777 /
Users/olivier/tmp

A chaque hit sur votre serveur, un fichier sera crée dans ce répertoire. Vous pourrez l’ouvrir avec KCachegrind.

Un futur article expliquera comment exploiter les résultats obtenus et parlera de profiling d’applications php en général.

Pourquoi utiliser Zend Framework quand on peut utiliser Symfony ?

12 janvier 2008

Connaisseur averti de Symfony (que j’ai pratiqué sur de nombreux projets) je m’intéresse vivement aux frameworks PHP. J’ai utilisé d’autres frameworks ; par exemple, Code Igniter qui est quand même pas mal, (surtout si on est coincé avec PHP4) mais qui reste pour moi valable uniquement pour des petits projets (pub gratuite : un joli site réalisé avec ce framework par un de mes amis).

En ce moment, tout le monde s’excite beaucoup autour de Zend Framework. Je suis donc allez y jeter un coup d’œil ; Zend avait annoncé des livraisons importantes et mon dernier avis sur la question datait un peu.

Là, je dois vous dire chers lecteurs, que je suis vraiment désappointé. Franchement, vous lui trouvez quoi au Zend Framework ? (c’est une vraie question – un peu provocatrice oui – mais tout de même une question).

  • La documentation est vraiment aride,
  • il manque des bouts de MVC comme la vue !? (bien que visiblement le composant soit disponible, il n’est pas documenté !?),
  • que viennent faire les classes de connections aux services d’Amazon, de Flickr etc … pour moi c’est hors périmètre d’un framework (enfin ça ce n’est pas grave),
  • on doit fabriquer le cache à la main,
  • pas de système de plugin (c’est dommage car ce système séduit les utilisateurs comme on peut l’observer pour CakePHP ou Symfony),
  • pas de gestion d’environnements (dev, test, prod …), rien pour vous aider à instancier / déployer vos applications,
  • rien pour les formulaires :-( (si il y a un composant de validation), pas de helpers pour faire de l’Ajax,
  • pas de scaffolding

Mon impression est que ZF a été développé de manière un peu brouillonne et désordonnée. Quelque chose de satisfaisant du point de vue d’une librairie mais pas d’un framework (comme PEAR par exemple). Je ne dis pas que le travail fait autour de ZF est mauvais (je trouve, par exemple, certaines classes très bien faites comme Zend_Memory ou Zend_PDF) mais tout ça manque de liant et de finition pour faire un bon framework.

Je pense toutefois qu’un défaut d’approfondissement dans mes recherches est la cause de tout ces manques affichés – je creuse. Si vous avez des arguments pour me faire changer d’avis, je serais ravi de vous lire dans les commentaires. Pour l’instant je continue avec Symfony.

Non cet article n’est pas un troll. Ceci oui :

troll

Installer la librairie GD pour php5 sous Léopard, 2eme essai !

30 décembre 2007

Ma première tentative a bien fonctionnée mais pose un problème assez important.

Il semble que la version de php5 fournie par Apple soit incapable de charger un module dynamiquement depuis la ligne de commande. C’est ainsi que j’interprètre l’erreur systématique que l’on a lorsque l’on lance php via le terminal après avoir suivi mon premier tutorial :

# php
dyld: NSLinkModule() error
dyld: Symbol not found: _php_sig_gif
Referenced from: /usr/lib/php/extensions/no-debug-non-zts-20060613/gd.so
Expected in: flat namespace
Trace/BPT trap

GASP !

Je me suis donc rabattu sur une solution finalement plus simple et j’espère ne pas avoir de mauvaise surprise !

J’ai simplement installé un php5 compilé par les bon soins de Marc Liyanage (fort connu dans le monde mac). Ce paquet contient la plupart des extensions utiles (dont GD) et supporte la compilation et l’ajout d’autres extensions.

Installation de PHP5 via le binaire d’entropy.ch

Il faut télécharger cette archive :
http://www2.entropy.ch/download/php5-5.2.5.leopard.release1.tar.gz.

Mise à jour : Marc Liyanage travaille actuellement à différentes releases de php5 pour Leopard. Pour trouver le dernier paquet, le plus simple est de suivre le forum d’entropy.ch.

Re mise à jour : php5 est maintenant disponible à cette adresse : http://www.entropy.ch/software/macosx/php/.

Une fois celle ci décompressée, rendez vous dans le répertoire de téléchargement via le terminal :

# sudo su
# mv php5 /usr/local/
# exit

et voilà !

Configuration d’apache et de PHP5

Là aussi c’est assez simple.

# sudo su
# cp /usr/local/php5/lib/php.ini-recommended /usr/local/php5/lib/php.ini
# exit

Il faut ensuite remplacer

LoadModule php5_module libexec/apache2/libphp5.so

par

LoadModule php5_module /usr/local/php5/libphp5.so

dans le fichier /etc/apache2/httpd.conf.

Enfin, les binaires utiles sont maintenant situés dans /usr/local/php5/bin. Pour pouvoir les utiliser facilement j’ai ajouter ces lignes suivantes dans le fichier .profile à la racine de mon répertoire :

PATH=/usr/local/php5/bin:$PATH
export PATH

J’utilise bash ; pour changer de shell par défaut – qui est tcsh sous os x – il suffit d’ouvrir le terminal et d’entrer /bin/bash dans le champs commande des préférences de l’application.

Cerise sur le gâteau !

tentez donc un :

# sudo pecl install apc

dingue non ? PEAR et PECL répondent à l’appel.

Voici le phpinfo obtenu. (1,5 Mo)

La suite dans le prochain numéro !

Installer la librairie GD pour php5 sous Léopard

29 décembre 2007

Attention, cette recette ne donne pas tout à fait satisfaction (casse le binaire php lancé en ligne de commande). Consultez plutôt cet article pour quelque chose d’efficace.


Suite à un commentaire pertinent de Niko je me lance dans l’opération consistant à l’installation de la librairie GD pour la version de php5 livré avec Léopard.

En gros, j’ai pioché dans différent tutoriels trouvés sur internet, pour la plupart destinés à os x serveur, afin de réussir l’installation sur ma configuration :

  • un iMac 20 pouces, 2 GHz Intel Core Duo et 2 Go de SDRAM
  • Léopard installé normalement avec les XCodeTools et X11 installés (disponible sur le dvd d’installation de Léopard)
  • PHP5 activé en éditant le fichier de configuration d’Apache et en décommentant la ligne correspondant à php5 (/etc/apache2/httpd.con)

Installer GD

Télécharger la librairie directement sur le site du projet. Décompresser l’archive dans un répertoire temporaire. Dans ce répertoire, taper ces commandes via le terminal mac os x ou l’excellent iTerm :

# cp /usr/share/libtool/config.sub .
# cp /usr/share/libtool/config.guess .
# ./configure --enable-shared
# make
# sudo su
# mkdir -p /usr/local/include
# mkdir -p /usr/local/bin
# mkdir -p /usr/local/lib
# mkdir -p /usr/local/man/man1
# make install
# exit

Installer l’extension pour php5

L’astuce consiste a récupérer les sources de la version de php fournie avec Léopard et de ne compiler que l’extension GD. Ici on parle donc de la version 5.2.4, dont j’ai pu télécharger les sources sur php.net. Une fois l’archive décompressée, taper ces commandes :

# cd php-5.2.4/ext/gd
# phpize
# ./configure --with-zlib-dir=/usr --with-jpeg-dir=/usr/local/lib --with-png-dir=/usr/X11R6 --with-freetype-dir=/usr/X11R6 --with-xpm-dir=/usr/X11R6
# make
# sudo su
# make install
# exit

Configurer PHP

# sudo su
# cp /etc/php.ini.default /etc/php.ini

Dans le fichier php.ini, ajouter la ligne :

extension=gd.so

et, afin que php utilise le chemin par défaut pour les extensions, supprimer la ligne suivante :

extension_dir = "./"

Une fois Apache redémarré via les préférences systèmes, GD est bien configurée avec php5 !

Voici le phpinfo obtenu. (1,2 Mo)

Léopard est livré avec php5

26 décembre 2007

Quelle bonne surprise de fin d’année ! En fait, je m’y attendais un peu. Ce qui est sympa c’est la version relativement à jour de php qui est fournie :

Les fichiers de configuration sont standards (a ceci près qu’il faut renommer le fichier /etc/php.ini.default en /etc/php.ini si vous voulez changer des valeurs de configuration) ; dès que l’on a compris que pour démarrer Apache il faut aller dans : Préférences Systèmes -> Partage -> Partage Web, tout roule !

Voici le phpinfo fourni en standard (1,2 Mo).

Au passage, Léopard est superbe. Je trouve même qu’après la mise à jour, le système est plus rapide !!!!

Astuce symfony : ne pas charger une colonne lors de « l’hydratation » d’un objet

9 décembre 2007

En fait c’est plutôt une astuce Propel ;-).

Quand vous chargez des données depuis la base (avec doSelect ou retrieveByPk) vous récupérez des objets complètement « hydratés ». C’est à dire que chaque objet représente une ligne de votre base de donnée avec autant de variables membres que de colonnes. Un problème évident peut survenir si votre table contient des champs lourds à charger comme des binaires (BLOB) si vous voulez stocker des images, ou des chaines très longues (CLOB) pour du XML par exemple. C’est autant de données qu’il faudra extraire et charger dans vos objets ; autant vous dire que ce n’est pas forcément anodin en terme de performance (et je parle d’expérience).

Une solution simple existe pour contourner ce soucis. Dans le fichier décrivant vos données (schema.yml) ajouter simplement lazyLoad: true dans la description de la colonne que vous ne désirez pas charger.

matable:
  id:
    type: INTEGER
    required: true
    autoIncrement: true
    primaryKey: true
  smallcol:
    type: VARCHAR
    size: 255
  bigcol:
    type: CLOB
    lazyLoad: true

Avec cette configuration, si je fais : MatablePeer::retrieveByPk(1), j’aurais un objet contenant uniquement les champs id et smallcol. Par contre, quand, sur mon objet, je ferais un ->getBigCol(), Propel lancera une requête (en fait un doSelectRS sur le champs en question) et récupèrera notre donnée.

Astucieux non ?

Astuce symfony : mesurer le temps d’exécution d’un bout de code

6 décembre 2007

Voici le code permettant d’ajouter une entrée dans la liste des timers de Symfony. On peut écrire ce code dans une libraire, une classe de modèle etc ….

$timer = sfTimerManager::getTimer('hardwork !!!!');
myClass::workHardPlease();
$timer->addTime();

Les développeurs , en utilisant la barre de débogage de symfony, verront alors le temps consommé lors de l’exécution de myClass::workHardPlease et pourront, si nécessaire, passer un peu de temps à l’optimiser. (par défaut, Symfony nous montre le temps consommé pour parser les fichiers de configurations, jouer les requêtes sql, rendre les templates etc.)

ps : c’est une « astuce ». Si vous avez de vrai problèmes de performances un profiling plus complet avec un outils spécialisé (comme xdebug) sera vraisemblablement nécessaire.

Utilisation de eval() avec PHP5

10 novembre 2007

La fonction eval() permet d’évaluer une chaine de caractère comme du code PHP. Elle peut être utile dans certains cas mais pose des problèmes :

  • le code est plus dur à maintenir et à déboguer,
  • l’execution de cette fonction ralenti votre script.

C’est particulièrement vrai pour les eval appelés dans une boucle ; c’est le temps de compilation que vous multipliez dans ce cas là. Si vous devez faire ça, il vaut mieux alors carrément inclure la boucle dans le code à évaluer.

Ce petit script le montre par l’exemple.

$nb_iteration = 400000;
 
$start_time = microtime(true);
// boucle de référence
for ($i=0; $i >= $nb_iteration; $i++)
{
	$r = $i;
}
 
$end_time = microtime(true);
 
echo 'time taken (no eval)        : '.($end_time-$start_time).' s'."\n";
 
$start_time = microtime(true);
// éval a chaque itération
for ($i=0; $i >= $nb_iteration; $i++)
{
	eval('$r = $i;');
}
 
$end_time = microtime(true);
 
echo 'time taken (with eval)      : '.($end_time-$start_time).' s'."\n";
 
$start_time = microtime(true);
// eval autour de la boucle
eval (
  'for ($i=0; $i >= $nb_iteration; $i++)
  {
    $r = $i;
  }');
 
$end_time = microtime(true);
 
echo 'time taken (with loop eval) : '.($end_time-$start_time).' s'."\n";

Il donne les résultats suivants :

$ php eval_speed.php
time taken (no eval)        : 0.248116016388 s
time taken (with eval)      : 6.24511909485 s
time taken (with loop eval) : 0.314826011658 s

Parlant non ?

Programmer un démon en PHP

5 novembre 2007

Un démon (ou daemon en anglais) est un programme fonctionnant en permanence en arrière plan et qui n’est pas contrôlé par l’utilisateur.

PHP étant un langage de script, on ne peut pas lancer des tâches de fond depuis les requêtes faites sur le serveur http. Quand un processus nécessite des traitements nombreux et n’a pas besoin, ou ne peux pas, être réalisé immédiatement, on peut facilement renseigner cette tâche dans une pile (dans une base de donnée ou un fichier) qu’un démon se chargera de réaliser.

Voyons comment réaliser ce démon.

Lire la suite »