Messages étiquettés Php

How to avoid memory leaks with Doctrine?

Fatal error: Allowed memory size of X bytes exhausted (tried to allocate Y bytes)...

I hate this message, in fact it says « You suck, you don’t even know what you’re doing with your objects ». It happened recently when I was writing a script which retrieves old data from an old database, computes it and inserts new values in an other database. I used Doctrine because it was a part of a Symfony project, and I discovered many things :

  • Doctrine objects take a LOT of memory space
  • PHP 5.2.11 does not garbage collects Doctrine (or any other ORM) objects at the end of the scope

Why? Because before PHP 5.3 the garbage collector can’t collect objects that have circular references, and that is the case of Doctrine objects. So they aren’t freed at the end of the scope, resulting in memory leakage.

So in order to process thousands/millions records with a database ORM, you need to handle memory freeing. Doctrine hopefully provides a free() method which, combined with unset(), can solve your problem.

// ...
$my_object = new MyDoctrineClass() ;

// your data processing...

$my_object->free() ;
unset($my_object) ;
// ...

Étiquettes: , , , ,

Symfony 1.2 sur une Debian Etch

Symfony 1.2 (et versions supérieures) nécessitent au minimum PHP 5.2.4, version qui n’est notamment pas disponible dans les dépôts de Debian Etch. Ce petit tuto montre comment compiler une version de PHP compatible avec les versions actuelles de Symfony (jusqu’à 1.4) tout en gardant une précédente version de PHP déjà installée.

Compilation de PHP

Il faut commencer par installer certaines librairies nécessaires pour la compilation de PHP :

apt-get install libgd-dev libpng12-dev libxml2-dev libmysql++-dev libxslt1-dev zlib1g-dev libldap2-dev libcurl3-dev libpq-dev

Ensuite on va récupérer les sources de la version de PHP qui nous intéresse (ici 5.2.11) et les mettre dans un répertoire temporaire :

mkdir /usr/local/tmp
cd /usr/local/tmp
wget http://fr2.php.net/get/php-5.2.11.tar.gz/from/this/mirror
tar xzf php-5.2.11.tar.gz
cd php-5.2.11

Vient ensuite la compilation. Ici le chemin d’installation choisit pour tout le tuto est /usr/local/php5211, il faudra modifier toutes ses occurences si on veut l’installer ailleurs :

./configure --enable-fastcgi --with-gd --with-mysql --prefix=/usr/local/php5211 --with-xsl --enable-soap --with-zlib --with-config-file-path=/usr/local/php5211 --with-curl --with-pdo-mysql --with-pgsql --with-pdo-pgsql --with-ldap
make
make install

Il faut enfin mettre le fichier php.ini-recommended là où on a dit qu’on le trouverait (avec l’option –with-config-file-path) :

mv php.ini-recommended ../../php5211/lib/php.ini

Définition du VirtualHost

Il faut maintenant modifier le httpd.conf pour ajouter la prise en charge des applications Symfony par la nouvelle installation PHP. Si on garde le même répertoire d’installation qu’au dessus (/usr/local/php5211) ça donne :

# httpd.conf
LoadModule actions_module /usr/lib/apache2/modules/mod_actions.so # important, à ne pas oublier

NameVirtualHost 127.0.0.1:8080
Listen 127.0.0.1:8080

<VirtualHost 127.0.0.1:8080>
DocumentRoot "/var/www/mon_appli_symfo"
DirectoryIndex index.php

<Directory "/var/www/mon_appli_symfo">
AllowOverride All
Allow from All
</Directory>

ScriptAlias /php5211-cgi /usr/local/php5211/bin/php-cgi
Action php5211-cgi /php5211-cgi
AddHandler php5211-cgi .php

</VirtualHost>

Il reste plus qu’à activer le module apache rewrite (c’est probablement déjà fait) :

a2enmod rewrite

Normalement tout marche ; il vaut mieux ne pas supprimer les sources de PHP au cas où il manque une option et qu’il faille un jour le recompiler.

Étiquettes: , , , ,