Symfony2: nom de la route depuis un template Twig

Dans Symfony2, il est possible d’accéder aux propriétés de la requête actuelle à partir d’un template Twig grâce aux variables globales.

En l’occurrence, ça peut être utile pour connaître le nom de la route utilisée. Ainsi, avec la variable app.request, on peut avoir accès aux attributes, et donc à la route utilisée. En PHP, on aurions pu récupérer l’information comme ceci:

$request->attributes->get('_route');

Avec Twig, le code deviens ceci:

{{ app.request.attributes.get('_route') }}

Une fonctionnalité toute bête mais qui peut s’avérer très pratique!

Symfony 2 et PostgreSQL: Mots réservés

Symfony 2 propose une abstraction des entities très intéressante grâce à Doctrine. Je poste ce petit article car j’ai eu une erreur tout simple:

 $ php app/console doctrine:schema:update --force
Updating database schema...
 
[PDOException] SQLSTATE[42601]: Syntax error: 7 ERREUR:  erreur de syntaxe sur ou près de « User » 
LINE 1: CREATE TABLE User (id INT NOT NULL, username VARCHAR(255) NO...              
                       ^          

En fait, j’ai créé un bundle nommé User, et doctrine souhaite donc créer la table User. Le problème, c’est que user est un mot clé réservé dans PostgreSQL. Par conséquent, il faut donc forcer Doctrine à escaper le nom de la table. Pour se faire, il suffit d’ajouter une annotation Table en préfixant et suffixant le nom de la table par `.

Voici par exemple ma classe User avant la correction:

/**
 * @ORM\Entity
 */
class User extends BaseUser
{
    // ...
}

Il suffit donc de d’ajouter l’annotation @ORM\Table en spécifiant le nom de la table entouré de `. Le nouveau code est:

/**
 * @ORM\Entity
 * @ORM\Table(name="`User`")
 */
class User extends BaseUser
{
    // ...
}

Ainsi, Doctrine va générer ses requêtes en ajoutant des caractères d’échappement sur le nom de la table. Ainsi, vous n’aurez plus d’erreur! :)

Polygones de Thyssen: algorithme de Steven Forture en PHP

Pour des besoins professionnels, j’ai réécrit l’algorithme de Steven Fortune permettant d’obtenir un diagramme de Voronoï à partir de points connus, en transformant la librairie JavaScript de gorhill.

Vous pouvez trouver les fichiers sources (en PHP 5) sur ce dépôt GitHub:

Exemple d’utilisation

Voici un exemple d’utilisation, qui permet de générer un diagramme de Voronoï (ou autrement dit des polygones de Thyssen) à partir de points générés automatiquement:

<?php 
require_once '../library/Nurbs/Voronoi.php';
require_once '../library/Nurbs/Point.php';
 
$bbox = new stdClass();
$bbox->xl = 0;
$bbox->xr = 400;
$bbox->yt = 0;
$bbox->yb = 400;
 
$xo = 0;
$dx = $width = 400;
$yo = 0;
$dy = $height = 400;
$n = 20;
$sites = array();
 
// On créé l'image
$im = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($im, 255, 255, 255);
$red = imagecolorallocate($im, 255, 0, 0);
$green = imagecolorallocate($im, 0, 100, 0);
$black = imagecolorallocate($im, 0, 0, 0);
imagefill($im, 0, 0, $white);
//imageantialias($im, true);
 
// On créé des points aléatoires que l'on dessine
for ($i=0; $i < $n; $i++) {
	$point = new Nurbs_Point(rand($xo, $dx), rand($yo, $dy));
	$sites[] = $point;
 
	imagerectangle($im, $point->x - 2, $point->y - 2, $point->x + 2, $point->y + 2, $black);
}
 
$voronoi = new Voronoi();
$diagram = $voronoi->compute($sites, $bbox);
//var_dump($diagram);
 
//var_dump('sites', $sites, 'diagram', $diagram, 'cells', $diagram['cells']);//, 'voronoi', $voronoi);
$j = 0;
foreach ($diagram['cells'] as $cell) {
	// On va agreger les points du polygone.
	$points = array();
 
	if (count($cell->_halfedges) > 0) {
		$v = $cell->_halfedges[0]->getStartPoint();
		if ($v) {
			$points[] = $v->x;
			$points[] = $v->y;
		} else {
			var_dump($j.': no start point');
		}
 
		for ($i = 0; $i < count($cell->_halfedges); $i++) {
			$halfedge = $cell->_halfedges[$i];
			$edge = $halfedge->edge;
 
			if ($edge->va && $edge->vb) {
				imageline($im, $edge->va->x, $edge->va->y, $edge->vb->x, $edge->vb->y, $red);
			}
 
			$v = $halfedge->getEndPoint();
			if ($v) {
				$points[] = $v->x;
				$points[] = $v->y;
			} else {
				var_dump($j.': no end point #'.$i);
			}
		}
	}
 
	// On construit le polygone
	$color = imagecolorallocatealpha($im, rand(0, 255), rand(0, 255), rand(0, 255), 50);
	imagefilledpolygon($im, $points, count($points) / 2, $color);
	$j++;
}
 
// On affiche l'image
imagepng($im, 'voronoi.png');

Voici un exemple d’image:

Zend PHP 5.3 Developer Certified

Ça y est, je suis développeur PHP 5.3 certifié par Zend! :-)

Le principe du concours est très simple: vous avez 90 minutes pour répondre à 70 questions aléatoires concernant le fonctionnement de PHP ainsi que les différents domaines qui l’entour, à savoir le SQL, la sécurité en général, etc…

Je vous conseil de le passer, c’est sans aucun doutes un bon élément sur le CV. Si vous avez un quelconque question, n’hésitez pas!

Erreur PHP – require_once(): Unable to allocate memory for pool

Depuis peu, PHP me sort des erreurs assez bizarres, à savoir des “Unable to allocate memory for pool“. Ceci se passe notamment sur les fonctions require_once et include_once. Après quelques temps de recherche, il s’avère que c’est en fait APC qui créé cette erreur lorsqu’il n’a plus assez de place dans sa mémoire.

C’est pourquoi, pour éviter ce bug – voir ici le rapport de bug sur php.net – vous devez augmenter la mémoire allouée à APC avant d’attendre une mise à jour corrigeant ce problème.
Dans le fichier /etc/php.d/apc.ini (sous CentOS) éditez donc la ligne contenant la directive apc.shm_size en y ajoutant plusieurs mégas. Pour information, voici la configuration du serveur hébergeant D-Sites.com:

apc.shm_size=64M

Installation de PHP 5.3 avec Nginx en Fast-CGI sous CentOS

Nous allons installer Nginx et PHP 5.3 configurés pour communiquer en Fast-CGI sous CentOS (testé sous CentOS 5.5). L’avantage de Nginx est qu’il est beaucoup plus rapide qu’Apache, et très complet malgré tout. Dans l’ordre, nous allons installer les paquets pour Nginx et PHP, puis nous allons configurer la liaison Fast-CGI entre les deux.

Installation des dépôts EPEL

Avant tout, pour pouvoir avoir les dépôts EPEL et IUS, dans lequel il y a Nginx et PHP 5.3, nous allons installer deux paquets qui ajoutent ces dépôts:

# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm
# rpm -Uvh http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/ius-release-1.0-6.ius.el5.noarch.rpm

Installation de nginx

L’installation de nginx est très rapide grâce à yum, il vous suffit de lancer cette commande:

# yum install nginx

Installation de PHP 5.3

L’installation de PHP 5.3 se fait grâce aux paquets php53*, que nous pouvons également installer grâce à yum.

# yum install php53 php53u-pecl-apc php53u-gd php53u-mbstring php53u-devel php53u-snmp php53u-cli php53u-pdo

Note: vous pouvez installer d’autres paquets pour le support de MySQL – php53u-mysql -, ou de PostgreSQL – php53u-pgsql ou php53u-pgsql84 -. Listez les paquets pour PHP 5.3 grâce à la commande yum list | grep php53.

Continue reading

PHP Notice: Sorry, your PCRE extension does not support UTF8 which is needed for the I18N core (CentOS)

Lors d’une installation avec les paquets de PHP – ici sous CentOS – il arrive qu’il y ai des petits problèmes comme celui-là:

PHP Notice: Sorry, your PCRE extension does not support UTF8 which is needed for the I18N core

PHP nous dit que PCRE ne supporte pas l’UTF-8. Nous pouvons vérifier la configuration de PCRE grâce à la commande pcretest:

# pcretest -C
PCRE version 6.6 06-Feb-2006
Compiled with
UTF-8 support
No Unicode properties support
Newline character is LF
Internal link size = 2
POSIX malloc threshold = 10
Default match limit = 10000000
Default recursion depth limit = 10000000
Match recursion uses stack

Ici, on voit que PCRE supporte bien l’UTF-8. Si ce n’est pas le cas pour vous, il vous suffit de recompiler PCRE avec le support de l’UTF-8 comme vu plus bas pour l’Unicode. Seulement, si comme moi, il est bien compilé avec le support de l’UTF-8, il faut chercher plus loin: on voit que l’Unicode n’est pas supporté par PCRE (“No Unicode properties support”), il faut donc l’installer…

Continue reading

Installer HipHop sur CentOS 5

HipHop pour PHP est un programme développé par Facebook permettant de compiler des applications PHP en binaire. Cela permet une augmentation très importante des performances de celle-ci. Pour l’installer sur CentOS 5, il vous suffit d’ajouter quelques dépôts et d’utiliser yum.

Note: HipHop n’est pour l’instant supporté que sur les architectures 64 bits.

Installation des nouveaux dépôts

Pour installer les 3 nouveaux dépôts, il vous suffit de lancer ces 3 commandes:

# rpm -ivh http://epel.osuosl.org/5/x86_64/epel-release-5-4.noarch.rpm
# rpm -ivh http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/ius-release-1.0-6.ius.el5.noarch.rpm
# rpm -ivh http://pkg.tag1consulting.com/hphp/x86_64/hphp-release-1.0-2.el5.noarch.rpm

Installation de HipHop

Ensuite, il vous suffit de lancer yum pour installer HipHop via les nouveaux dépôts configurés:

# yum install hiphop-php

yum se chargera de l’installation de toutes les dépendances nécessaires et trouvées dans les dépôts.

Important: par défaut dans CentOS, la version de gcc est la version 4.1.2 alors que la version minimum pour HipHop est la version 4.4. N’oubliez pas de mettre à jour gcc, ainsi que g++.

Une fois l’installation terminée, le compileur hphp se trouve dans le /usr/bin, ainsi que dans le répertoire de HipHop, à savoir /usr/lib64/hphp/.

socket_stream_select: Attendre un flux (stream) et un socket en même temps

Avec PHP, on peut interagir avec l’extérieur (et l’intérieur) du serveur sur lequel est exécuté le PHP à l’aide de flux et de sockets. Pour PHP, les flux – ou streams – et les sockets sont différents, alors qu’au niveau système, ce sont en réalité tous les deux des sockets (différents des sockets tels que l’entend PHP).

L’on travaille sur les deux en utilisant des fonctions toutes distinctes:

Parmi celles-ci, il y a deux fonctions extrêmement utiles: stream_select et socket_select. Elles permettent d’attendre de nouvelles données respectivement depuis un flux et un socket.

Vous pouvez par exemple attendre deux flux de données en même temps avec stream_select. Si l’un des deux a de nouvelles informations, la fonction retourne un entier décrivant le nombre de flux qui ont eu de nouvelles notifications. Vous pouvez aussi ajouter un timeout, etc… De la même manière, vous pouvez attendre un ou plusieurs sockets avec socket_select.

Seulement, si vous travaillez à la fois avec des flux et des sockets… Comment faire?

  1. Vous pouvez très bien mettre des timeout à quelques dizaines de millisecondes, regarder pendant x ms le flux, x ms le socket, puis on recommence… C’est une solution comme une autre mais très peu propre, et qui ne sera jamais “instantanée”.
  2. Vous pouvez utiliser un système, auquel vous vous connecterez en socket, qui écoutera un flux et dès que le flux recevra des données, il vous l’enverra par le socket. Ainsi, vous aurez que des sockets, vous pouvez donc utiliser socket_select.
  3. Mais, pourquoi ne pas créer une fonction socket_stream_select, ou stream_socket_select, comme vous voulez, dans le coeur de PHP, qui transformera les flux et les sockets PHP en sockets systèmes pour les écouter avec la fonction C select ?

Continue reading

HipHop pour PHP, qu’est-ce que c’est ?

Le nouveau projet Open Source pour PHP du moment, c’est bien HipHop, développé pour PHP, qui consiste à transformer le code PHP en C++ puis de le compiler en utilisant g++. Présenté dans l’article précédent Facebook & PHP II: HipHop et HPHPi, voici de nouvelles informations, issues de la conférence de cette nuit.

Facebook qui utilise déjà HipHop sur 90% de ses serveurs a constaté:

  • Sur les serveurs Web: 50% de consommation CPU en moins pour un même trafic, par rapport à PHP 5.2 avec APC
  • Sur les serveurs API: 30% de consommation CPU en moins pour deux fois plus de trafic

HipHop transforme le code en C++ et le compile avec g++ mais l’utilisateur n’a pas besoin de compiler à la main son code PHP avec un outils, tout reste comme avant, avec l’édition de fichiers PHP à la volée.

Néanmoins, les fonctionnalités qui ne seront pas disponibles:

  • La fonction eval
  • La fonction create_function, qui est du même acabit que eval
  • La fonction preg_replace, avec le paramètre e, qui permet l’application de eval sur le résultat
  • De manière plus générale, l’ordre des objets ne peu pas être respecté, du fait d’une exécution non-linéaire du code. Ainsi, la fonction function_exists retourne la valeur vraie dans ce code:
    if (function_exists('foo')) {
     
        // Vrai avec HipHop
     
        // Faux avec PHP
     
    }
     
    function foo () {}
     
    ?&gt;

En plus de HipHop, l’équipe de Facebook a développé HPHPi, c’est un interpréteur PHP, il semblerait que ça soit grâce à lui qu’il ne sera pas nécessaire de compiler le code PHP. Il fait aussi des analyses du code pour y détecter des éventuelles erreurs dues à l’utilisation de HipHop et non de PHP.

HipHop embarque son propre serveur Web et n’est pas le moment pas compatible/prêt à fonctionner avec Apache ou un autre serveur. C’est pourquoi HipHop c’est un seul processus, contrairement à PHP mais qui utilise le principe de multi-thread, plus rapide que le multi-processus car créer un processus, c’est assez long par rapport aux threads. Comme HipHop utilise sont propre Web serveur allégé, il est plus rapide et permet de mieux gérer les ressources partagées entre les threads, il permet aussi de ne pas avoir de downtime, c’est-à-dire de temps d’inaccessibilité lors d’un redémarrage de HipHop.

HipHop est pour le moment basé sur PHP 5.2, et l’équipe de chez Facebook compte bien avancer encore plus sur ce projet et voici leur Roadmap, ou liste de choses à faire:

  • Apport des fonctionnalités de PHP 5.3
  • Utilisation possible avec Apache
  • …et plus généralement la réduction de l’écart entre HipHop et PHP

Le code source qui était sensé être mis en ligne cette nuit sera maintenant mis en ligne “soon” !