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

Janvier 2007 – tigrou/pwet.fr: À lire à droite, à gauche

Janvier 2007 – tigrou/pwet.fr: PHP4 (mod_php) et PHP5 (fastcgi) avec Apache sous Ubuntu

J'ai finalement choisi Ubuntu comme système sur ma dedibox fraîchement livrée . Du coup, j'ai un système à configurer car j'ai plusieurs projets pour cette machine. Le premier étant d'héberger pwet.fr et de pouvoir à côté tester / développer des applications en PHP5. J'ai donc besoin de faire cohabiter ces deux versions. Sachant que ce site utilise eZ publish , je préfère avoir PHP4 en module (a priori plus performant), PHP5 en FastCGI (plus rapide qu'en CGI) le tout avec Apache 1.3 pour la stabilité. La première chose à faire est évidemment d'installer tout le nécessaire (il faut activer le dépôt Universe ) :

tigrou@dedipwet:~$ sudo apt-get install apache libapache-mod-php4 php4-domxml php4-pear php4-pear-log php5-cgi php5-mysqli php5-xsl php5-gd php5-pear libapache-mod-fastcgi libapache-mod-actions

Une fois tout cela installé, il faut activer les modules nécessaires, le plus simple étant d'utiliser apache-modconf puis de redémarrer apache :

tigrou@dedipwet:~$ sudo apache-modconf apache enable mod_php4
tigrou@dedipwet:~$ sudo apache-modconf apache enable mod_fastcgi
tigrou@dedipwet:~$ sudo apache-modconf apache enable mod_actions
tigrou@dedipwet:~$ sudo /etc/init.d/apache restart

À partir de là, PHP4 devrait déjà fonctionner sur les fichiers terminant par .php, pour vérifier il suffit de créer un virtual host et d'y mettre un phpinfo . Ainsi tout à la fin de /etc/apache/httpd.conf, il suffit d'y mettre :

NameVirtualHost __IP__:80
<VirtualHost __IP__:80>
    ServerAdmin __EMAIL__
    DocumentRoot /var/www/votresite.fr
    ServerName votresite.fr
    ErrorLog /var/log/apache/errors-votresite.fr.log
    CustomLog /var/log/apache/access-votresite.fr.log common
</VirtualHost>

En remplaçant évidemment __IP__, __EMAIL__ et votresite.fr par les valeurs nécessaires ;) Il suffit alors de créer un fichier info.php et d'y placer un appel à la fonction PHP phpinfo et de l'appeler dans votre navigateur via http://votresite.fr/info.php pour obtenir le fameux PHPInfo.

Reste maintenant à configurer Apache pour interprèter les fichiers .php5 avec la version CGI de php5 via le module FastCGI. Pour cela, il faut modifier le fichier /etc/apache/conf.d/fastcgi.conf comme suit :

<IfModule mod_fastcgi.c>
  AddHandler fastcgi-script .fcgi
  FastCgiIpcDir /var/lib/apache/fastcgi
  FastCgiServer /var/www/votresite.fr/php5-wrapper.fcgi -processes 1 -idle-timeout 180 -socket /tmp/fastcgi.socket
  AddHandler php5-fastcgi .php5
  Action php5-fastcgi /php5-wrapper.fcgi
</IfModule>

Il reste alors à créer le fichier /var/www/votresite.fr/php5-wrapper.fcgi qui est en fait un simple script shell faisant appel à la version CGI de PHP5 :

#!/bin/sh 
PHP_FCGI_CHILDREN=4
export PHP_FCGI_CHILDREN
PHP_FCGI_MAX_REQUESTS=1000
export PHP_FCGI_MAX_REQUESTS
exec /usr/bin/php5-cgi

Il reste plus qu'à tester en copiant le fichier info.php en info.php5 et en l'appelant http://votresite.fr/info.php5, qui affichera normalement les informations sur l'installation de PHP5.

Janvier 2007 – sahid.funraill.org: http://pastebin.funraill.org

Un outils de déboggage collaborative

Pastebin.funraill.org, sert d’aide au développement d’application multiutilisateur, le principe est assez simple, vous disposez d’un formulaire avec choix de la coloration syntaxique pour le langage utilisé. Vous postez votre code source, il sera hebergé sous le serveur, et vous pouvez ainsi utiliser le lien pour des forums, listes de diffusion ou encore canaux IRC.

l’outil est encore en phase de développement, mais utilisable.

Janvier 2007 – Dur Comme Faire: Conférence sur la sécurité

La sécurité est un point crucial pour les applications web en général et PHP en particulier. Avec son statut de langage dominant sur le Web, PHP est une cible de choix pour les pirates. Damien Séguy, membre du PHP Group, co-fondateur de Nexen.net et rédacteur en chef de Direction|PHP,...

Janvier 2007 – sahid.funraill.org: Modele MVC en PHP - La classe View en PHP5

Une classe pour la vue de votre application OOP en PHP

Avant propos

Depuis PHP5 et sa couche objet refaite neuf, les applications PHP ont plus qu’evolué, et on ne parle plus de PHP comme un simple langage script pour le web, mais comme un véritable langage orienté objet digne de Java ou C++, mais alors pourquoi ne pas utiliser les grands principes d’un langage de programmation objet ? …
Nous allons dans ce petit article mettre en place une classe “view” permettant la séparation du code métier (PHP codé en dur) et de la partie graphique (code HTML)

Les méthodes magiques

PHP5 admet les méthodes __set() et __get() (il y en existe d’autre …), la premiÚre permet de récupérer une variable passée la volée notre objet view et admet deux paramÚtres, le premier étant la clef et le second la valeur de cette clef, la méthode __get() elle admet un paramÚtre qui sera la clef et permet donc, de retourner la valeur issue d’une clé …(erf, pas de panique c’est trÚs simple, sauf que j’explique trÚs mal !)

Un petit exemple

Admettons qu’on crée un objet qui admet comme méthode __get() et __set().

  1. $view = new view();

On passe un autre objet $view, une variable de cette maniÚre

  1. $view->newVar = “Hello Wolrd”;

Dans cette exemple, la méthode magique __set() de PHP5 se remplit automatiquement avec en clef “newVar” et en valeur “Hello Wolrd” …(c’est déj plus clair avec un exemple), mais continuons

  1. echo $view->newVar;

Cette fois-ci c’est la méthode magique __get() de PHP5 qui se remplit automatique avec en clef “newVar”.

Le rendu de nos pages

Pour le rendu de nos pages, nous allons utiliser le systÚme de cache de PHP, avec ob_start(), et ob_get_clean(). Le principe est en fait assez simple, on lance la fonction ob_start() qui commence la mise en tampon des infomations de sortie, ensuite avec un include() on récupÚre notre fichier template pour le placer dans notre tampon, cela nous permet donc d’utiliser dans notre template, des variables déclarées dans notre code métier …(pas mal l’abeille !) …la fonction ob_get_clean() nous retourne le tout qu’on aura plus qu’a afficher avec un simple echo().

  1.                 include ($content);
  2.                
  3.                 return ob_get_clean();

Un exemple d’utilisation

La classe complÚte est disponible ici
On dispose d’un fichier template de cette forme

  1.     <body>
  2.         <h1>< ?=$this->bonjour;</h1>
  3.     </body>
  4. </html>

un extrait de notre code métier

  1. $view = new View (“/tpl”);
  2.  
  3. $view->bonjour = “Hello Wolrd!”;
  4. $view->render (“template.php”);

Conclusion

En utilisant les methodes magiques de PHP5, on dispose d’une classe View trÚs simple mettre en oeuvre et assez modulable, je l’utilise dans plusieurs de mes projets.

Janvier 2007 – tigrou/pwet.fr: Que faire le dimanche ?

Janvier 2007 – tigrou/pwet.fr: PDO_MySQL sous Ubuntu, au bord de la crise nerfs...

Voila presque une semaine que je me bats avec PDO_MySQL pour arriver à enfin tester le composant PersistentObject d'eZ components ... Après pas mal de recherches, beaucoup de prises de tête, je voyais la défenestration arrivée à grand pas ;-) en m'apercevant que finalement le problème venait du module PDO_MySQL fraîchement compilé sur ma Dapper Drake grâce au tuto trouvé sur BlogNote . Je pensais alors à un problème dû au hack pobomékimarche du tuto, mais le problème était identique sur ma Dedibox et sa Edgy Eft toute propre... J'ai aussi posté un message sur le forum Ubuntu-fr avec un succès comment dire... relatif, 17 affichages et aucune réponse au moment où j'écris ces lignes...

Les symptômes étaient simples, les deux bouts code suivants devraient affichés la même chose, mais celui avec le bindValue() échoue et ne renvoie rien :

<?php
$db = new PDO('mysql:host=localhost;dbname=sew', 'sew', 'sew');
// Code simple de référence
$stmt = $db->prepare('select * from `sew_sites` where `id`=1');
$stmt->execute();
$row = $stmt->fetchAll( PDO::FETCH_ASSOC );
var_dump($row);
$stmt->closeCursor();
// Ne renvoie rien si compilé avec libmysqlclient14 ou 15
$stmt = $db->prepare('select * from `sew_sites` where `id`=:id');
$stmt->bindValue(':id', 1);
$stmt->execute();
$row = $stmt->fetchAll( PDO::FETCH_ASSOC );
var_dump($row);
$stmt->closeCursor();
?>

En fait, visiblement, la compilation de ce module avec libmysqlclient14 ou libmysqlclient15 correspondant respectivement à MySQL 4.1 et MySQL 5.0 d'après apt-cache , pose problème. Pour que ça fonctionne chez moi, il a fallu que j'installe libmysqlclient12 et libmysqlclient12-dev pour compiler PDO_MySQL... Ce qui est d'autant plus surprenant que libmysqlclient12 correspond à MySQL 4.0 et que la deuxième ligne de la documentation sur PDO_MySQL indique :

PDO_MYSQL prendra avantage des requêtes natives préparées présentes dans MySQL 4.1 et supérieur.

Et là, je me dis, mais bon sang, pourquoi n'y a t il pas de paquet officiels php5-pdo-mysql surtout que la documentation PHP indique que PDO est livré en standard avec PHP depuis la version 5.1 et qu'il s'agit d'une fonctionnalité majeure de cette version de PHP.

Janvier 2007 – Digital Fashion: Interfaces et Classes Abstraites

Les concepts de classes abstraites et d'interfaces sont souvents assez flous quand on débute dans la programmation objet, et on se fourvoie assez souvent sur leur utilisation et leur but. Voila une petite explication qui j'espère sera 1) juste et 2) assez claire pour tout le monde. Si vous pensez que je me fourvoie sur ces 2 concepts de base de la POO, n'hésitez pas à me le faire savoir !

Commençons par le commencement: l'Interface. Une Interface définit une API (Application Programming Interface), dont le seul et unique but est de décrire les méthodes disponibles pour un objet donné. Une Interface ne contient pas de code fonctionnel, seulement des synopsis de méthodes et d'attributs. Par exemple, l'utilisation du mot clé "instanceof" permet de déterminer si un objet donné implémente ou non une interface donnée, et d'adapter le comportement de l'application selon la réponse. Le "type hinting" permet également ce genre de choses:

<?php

interface Bar_Interface {
      public function doSomething();
}

class Bar implements Bar_Interface {
      public function doSomething() {
            echo "something was done.";
      }
}

class Foo {
      public function doSomething(Bar_Interface $bar) {
            $bar->doSomething();
      }
}

?>

Dans cet exemple, quand Foo::doSomething() est executée, on est certain que l'objet $bar dispose de la méthode doSomething car il implémente l'Interface Bar_Interface.

Vient ensuite la classe abstraite. La classe abstraite, "abstract class" en V.O., se comporte comme un squelette d'objet. Elle est utile dans le cas où on utilise une série d'objets d'une même famille qui partagent du code commun, mais qui comportent tous leurs particularités propres. Dans ce cas de figure, on commence par implémenter le code commun dans la classe abstraite, dont hériteront les autres objets, dans lesquels le code spécifique pourra à son tour être implémenté. C'est très utile pour certains Design Pattern, comme par exemple "Adapter" ou "Proxy", qui ont tous deux pour but de permettre des stratégies différentes pour une même situation, situation qui présente le plus souvent des points similaires quelque soit la stratégie adoptée.

En règle générale, une classe abstraite implémente une interface (et un exemple d'Adapter en cadeau bonux):

<?php

interface Bar_Adapter_Interface {
      public function doSomething();
}

class Bar {
      public function __construct(Bar_Adapter_Interface $adapter) {
            $this->_adapter = $adapter;
      }

      public function doSomething() {
            return $this->_adapter->doSomething();
      }

      static public function factory($adapter) {
            $className = "Bar_Adapter_".$adapter;
            if (!class_exists($className)) {
                  throw new Exception('Adapter not available: '.$adapter);
            } else {
                  return new Bar(new $className);
            }
      }
}

abstract class Bar_Adapter_Abstract implements Bar_Adapter_Interface {
      protected function getSomething() {
            return "la méthode pour accéder a ce truc est la même pour tout le monde";
      }
}

class Bar_Adapter_Explode extends Bar_Adapter_Abstract {
      public function doSomething() {
            return explode(' ', $this->getSomething());
      }
}

class Bar_Adapter_PregSplit extends Bar_Adapter_Abstract {
      public function doSomething() {
            return preg_split('/ /', $this->getSomething());
      }
}

$bar = Bar::factory('Explode');
print_r($bar->doSomething());

?>

Ici, l'objet Bar offre la méthode doSomething, qui présentement retourne une chaine explosée, et on propose deux adapteurs pour se faire, l'un utilisant explode(), l'autre preg_split(). Bien sur, cet exemple est complètement trivial :-)