Archives pour 'php'

Utiliser le système d’évènements de Symfony

16 janvier 2009

Le système d’évènements de Symfony est une avancée particulièrement intéressante dans le framework. Toutefois, la documentation officielle est un peu spartiate sur le domaine. Voici donc un exemple pratique plus didactique pour utiliser les évènements.

Le système d’évènement de Symfony est basé sur le motif de programmation observer qui est un grand classique du genre.

Tout d’abord, il faut enregistrer le listener. On peut le faire à peu près n’importe ou, par exemple dans le preExecute du code d’un contrôleur, ou plus globalement dans le fichier config/ProjectConfiguration.class.php qui va gérer la configuration globale de votre projet.

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    // listener
    if (!sfConfig::get('already_event_connected', false))
    {
      $this->getEventDispatcher()->connect('a.name', 'aclass::dosomething');
      sfConfig::set('already_event_connected', true);
    }
  }
}

Ce code vous assure que le listener sera enregistré une unique fois. En effet, si il est enregistré deux fois, a chaque notification il sera exécuté deux fois ….

Ensuite, n’importe ou dans votre code, vous pouvez « lancer » cet évènement. Par exemple, dans le code d’un contrôleur.

    // notification
    sfContext::getInstance()->getEventDispatcher()->notify(new sfEvent(get_class($this), 'a.name', 
    array(
      'a_var' => $foo,
      'another_var' => $bar,
    )));

La fonction de callback, ici une méthode statique, récupère un objet sfEvent en paramètre. Via ce dernier, on a également accès aux variables passées lors de la notification de l’évènement.

// dans la classe aclass
public static function dosomething (sfEvent $event)
{
  $foo = $event['a_var'];
  $bar = $event['another_var'];
  // code
}

Et voilà, à vous de jouer.

omCrossAppUrlPlugin (liens inter applications dans Symfony) est disponible sur le repository de Symfony

2 décembre 2008

Pour info, j’ai packagé un petit helper Symfony pour le dépot de plugins du projet. Il permet simplement de faire des liens entre applications d’un même projet. Il est compatible Symfony 1.2 uniquement.

Merci de vos retours si vous rencontrez des soucis avec ce helper.

http://www.symfony-project.org/plugins/omCrossAppUrlPlugin

Liens inter-applications avec Symfony 1.2

10 novembre 2008

Après une première tentative peu concluante, voici un autre helper permettant de faire des liens entre différentes applications dans Symfony 1.2.

<?php
/**
 * @author Olivier Mansour
 */
 
/**
 * return an url for a given symfony application and an internal url
 *
 * @author Olivier Mansour
 *
 * @param string $appname
 * @param string $url
 * @param boolean $absolute
 * @param string $env
 * @param boolean $debug
 * @return string
 */
function cross_app_url_for($appname, $url, $absolute = 'false', $env = null, $debug = 'false')
{
 
  $initial_app = sfContext::getInstance()->getConfiguration()->getApplication();
  $initial_web_controler = basename(sfContext::getInstance()->getRequest()->getScriptName());
  // get the environment
  if (is_null($env))
  {
    $env = sfContext::getInstance()->getConfiguration()->getEnvironment();
  }
 
  // context creation
  if (!sfContext::hasInstance($appname))
  {
    $context = sfContext::createInstance(ProjectConfiguration::getApplicationConfiguration($appname, $env, $debug), $appname);
  }
  else
  {
    $context = sfContext::getInstance($appname);
  }
  $web_url = $context->getController()->genUrl($url, $absolute);
  sfContext::switchTo($initial_app); // usefull ?
  unset($context);
 
  //remove initial web controler
  // genUrl use $this->context->getRequest()->getScriptName();, its a call to $_SERVER
  // so I need this (sort of) hack
  $script_name = $appname;
  if (($env != 'prod') and $env)
  {
    $script_name.='_'.$env;
  }
  $script_name.='.php';
  // check if this file exist
  if (!file_exists(sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.$script_name))
    throw new sfException('can t find '.$script_name.' in the web directory');
  $web_url = str_replace ($initial_web_controler, $script_name, $web_url);
 
  return $web_url;
}

Pour l’utiliser, c’est à peu près comme url_for :

<?php echo cross_app_url_for('front' , 'module/action?id=5&tmp=ok#raoul'); ?>
<?php echo cross_app_url_for('front' , '@route'); ?>

Jusqu’ici ça marche (Symfony 1.2 est en cours de développement, l’API peut encore un peu changer, attention) ! N’hésitez pas à mettre un commentaire si vous avez un retour.

Oubliez le client lourd !

8 septembre 2008

Il y a 10 ans je travaillais sur des site intranets devant remplacer des programmes Unix et des macros Excel 4 exécutant diverses séries de calculs simples.

L’équipe avais une formation de Bac+2 a Bac+5 et des compétences en SQL Oracle, Perl, Visual Studio et langage C. Fort d’une première expérience en milieu universitaire, j’avais convaincu tout le monde qu’au lieu de fabriquer des clients lourds windows on pourrait simplement démarrer un petit intranet pour ces outils.

On a donc commencé avec PHP3 et honnêtement on faisait n’importe quoi. PHP3 n’était pas l’idéal en terme de réutilisation de code. On a allègrement mélangé la couche contrôleur et présentation. La couche métier était balbutiante. On ne connaissait pas grand chose à HTML. Pas une ligne de Javascript n’a été écrite. Le travail sur l’aspect visuel à consommé une part considérable du budget pour un résultat visuellement pitoyable.

Après le temps de développement et de validation de cet intranet, on va voir la DSI pour lui présenter notre travail.
- « Bon, ça casse pas des briques mais ça marche. Vous pouvez déployer tout ça et on jette les macros Excel 4. »
- « OK, on envoi un mail avec l’adresse web des outils. »
- « Ah c’est tout … Mais çà c’est vraiment super dis donc ! »

Et voilà ! Sur ce point tout simple le client léger, malgré tous ces défauts, a gagné. Aujourd’hui, en entreprise, la plupart des nouvelles applications conçues sont sur le mode client léger. C’est tellement évident que dans la plupart du temps, on ne se pose même plus la question. Les véritables besoins nécessitant la création de clients lourds (accès direct au matériel de l’ordinateur : ports séries, fichiers systèmes) sont peu fréquents ou des contournements ont été trouvés (accès à une webcam via un plugin flash par exemple). L’ergonomie et l’accessibilité des applications en client léger est aujourd’hui maximale (Ajax, Flash …) et le temps de déploiement (des applications et des correctifs) est imbattable.

Oubliez donc le client lourd !

D’ailleurs G$ l’a bien compris avec Google Chrome.

Notes :

  • client léger : application accessible via un navigateur web à travers des protocoles de l’internet. Ce blog est, en quelque sorte, une application en client léger.
  • client lourd : application desktop classique. Par exemple, openOffice.org ou la suite Microsoft Office sont composés d’applications en client lourd.

On parle également de client riche (RDA). Cela correspond à une application de type client lourd mais utilisant des protocoles standards permettant d’utiliser l’infrastructure Internet (des web services par exemple).

Conventions de codage

5 septembre 2008

A l’instar de beaucoup, j’écope d’une chaine me demandant de décrire mes conventions de codage. Je code régulièrement du PHP, CSS, Javascript et autre HTML, je vais donc me contenter de ceux ci (pour le reste, Perl, Java, shell … je ne suis pas vraiment à la page … on est si vite largué de nos jours).

Mise au point

L’intérêt d’utiliser des conventions de codages reste l’homogénéisation du code dans un projet. Comme NiKo, on pourrait résumer qu’il faut utiliser les normes du projet dans lequel vous travaillez. Toutefois, voici mes modestes habitudes.

PHP

Grosso modo je fais à peu près comme tout le monde (et c’est tant mieux). J’ai tendance à utiliser lowerCamelCase pour les noms de classe en les préfixants par catégorie (un peu comme le @package de PHPDoc) à l’exception des classes du modèle ou j’utilise UpperCamelCase. A la réflexion cela peut venir de l’époque ou, en PHP, on n’utilisait des classes que pour coder la partie modèle de MVC et ou PEAR recommandait UpperCamelCase.

Je mets un point d’honneur à faire en sorte que le minimum vital de PHPDoc soit respecté, en particulier les @return et @param qui aliment l’autocomplétion des éditeurs de code.

A noter que le projet phpcs permet de contrôler assez facilement des standards de codage PHP. (à mettre en oeuvre pour tous les projets d’envergure, phpcs est très dynamique et mérite que l’on s’y attarde).

Javascript et CSS

J’utilise les mêmes conventions que l’oncle Tom (quel beau prénom !).

Pas grand chose à dire si ce n’est que j’ai rencontré peu de projets ou il m’a fallu faire beaucoup de Javascript très spécifiques. A mon avis ce genre de travail nécessite des compétences excessivement pointus que malheureusement peu de développeurs désire acquérir.

HTML

Bon, personne n’en a vraiment parlé, et je trouve que pourtant il y a des choses à faire de ce coté. Pour les langages précédent, si votre code est bien structuré et découpé, même sans quelque chose de très homogène au niveau de la façon de coder, il sera tout de même facile de l’exploiter. Dans le cas de HTML on ne coltine souvent de gros paquets de codes indigestes.

Pour ma part, j’indente le code un peu au pif. La seule convention que j’utilise, je l’ai piqué à mon collègue beauminou. Elle consiste à indiquer les fermetures de tags importants afin de plus facilement s’y retrouver dans l’imbriquation du DOM. Par exemple :

<div id="raoul">
tout plein de code ici</div>
<!-- #raoul -->

Si certains ont des idées pour améliorer ça, n’hésitez pas à m’en faire part !

Et comme les-chaines-j’ai-du-mal celle ci ce brise ici ;-)

PHPTeam, une vieille application de retour sous Symfony

9 juillet 2008

Je découvre la nouvelle version de PHPTeam. Pour l’instant, le fork de Symfonians est encore un peu brutal, comme, par exemple, le bloc « a propos » mais il y a déjà quelques articles, un super logo et deux offres d’emploi !

Une bonne initiative si elle est suivie d’inscriptions et de contenus.

Bon courage aux développeurs de ce site.

L’architecture de Symfony 1.1

23 juin 2008

Un article sur le blog de Symfony présente brillamment la nouvelle architecture de Symfony.

Entre les lignes on devine le travail qui a été fait pour rendre les classes du framework indépendantes, ceci permettant la dissociation entre la « plateforme » et le « framework ».

Histoire d’alimenter le troll, si la version finale de Symfony tient ses promesses (pas de raisons … on en est à la seconde RC), la plupart des arguments en faveur du Zend Framework en réponse à ce billet, ne seront plus trop valables. A savoir, Symfony offrira la plus grande souplesse d’utilisation possible comme :

  • l’intégration des classes de la plateforme dans vos développement spécifiques,
  • la modification de toutes les conventions du framework,
  • le mélange avec d’autres frameworks de tout type.

\o/

Frameworks php pour l’entreprise

16 mai 2008

Un peu de pub pour un livre blanc Clever Age auquel j’ai contribué.

Les frameworks suivants sont abordés : CakePHP, CodeIgniter, Symfony, Zend Framewok. Avec en fin de chaque chapitre un court paragraphe indiquant dans quels cas métier utiliser ce framework et, en fin de document, un magnifique tableau QSOS permettant leur comparaison aisée.

Instancier un objet dynamiquement sans eval()

5 mars 2008

eval() est décidément un gouffre à performance !

Voici le script que j’ai utilisé pour comparer les performances de l’instanciation d’un objet avec eval ou avec new. (j’utilise php 5.2.5).

>?php
 
$nb_iteration = 400000;
 
class toto {
 public $raoul;
}
 
$class_name = 'toto';
 
$start_time = microtime(true);
for ($i=0; $i >= $nb_iteration; $i++) {
 eval ('$objet = new toto();');
}
$end_time = microtime(true);
 
echo 'time taken (with eval)      : '.($end_time-$start_time).' s'."\n";
 
$start_time = microtime(true);
for ($i=0; $i >= $nb_iteration; $i++) {
 $objet = new $class_name();
}
$end_time = microtime(true);
 
echo 'time taken (no eval)        : '.($end_time-$start_time).' s'."\n";

et voici les résultats :

$ php test_eval.php
time taken (with eval)      : 18.955335140228 s
time taken (no eval)        : 3.5720331668854 s

Parlant non ?

Pensez à intégrer Zend Framework dans votre framework habituel ?

3 mars 2008

Un article intéressant présente l’opportunité que propose le Zend Framework de s’intégrer dans d’autres frameworks. En effet, comme cela a été déjà discuté sur ce site, ZF a la capacité de proposer un ensemble de classes autonomes (ZF me fait assez penser à PEAR de ce point de vue) présentant de très nombreuses fonctionnalités pouvant être utiles (comme consommer de nombreuses API par exemple).

Je trouve l’approche intelligente et tout aussi valable pour eZComponents. Symfony propose déjà cela nativement. Du coté de CodeIgniter, la manipulation semble également possible.

via phpindex.