Optimiser Zend – Partie 1

Vendredi 12 février 2010, 17:50

Cela fait un moment que je ne vous ai pas refait de tutoriaux pour le Framework Zend. Aujourd’hui je vous propose une adaptation d’un tutoriel en anglais que l’on m’avait fait parvenir et qui m’a grandement aidé (malheureusement, il n’est plus sur la toile).

Vous savez comme moi que l’un des points faibles de Zend Framework, c’est la performance, il est beaucoup plus lent que du PHP objet de base du fait de la majeur partie des classes qui sont chargées lors du lancement d’une page. Je vais donc réaliser ce tutoriel en plusieurs parties.

Aujourd’hui, je vais juste vous expliquer comment diminuer les chargements inutiles et redéfinir le fichier d’amorçage (le fameux index.php). Vous vous souvenez tous comment est composé le fichier index.php ? Et bien voici un petit rappel pour ceux qui ne savent pas :
/**
* Fichier index.php permettant de lancer le bootstrap
*
*/

//Définition du chemin vers le dossier application
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH',
realpath(dirname(__FILE__) . '/../application'));

//Définition de la variable de d'application (utile pour les fichiers de configuration
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV',
(getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV')
: 'production'));

//Partie permettant d'inclure les différentes librairies
//du dossier library (en théorie).
//Nécessite un complément côté bootstrap.
set_include_path(implode(PATH_SEPARATOR, array(
dirname(dirname(__FILE__)) . '/library',
get_include_path(),
)));

/** Zend_Application */
require_once 'Zend/Application.php';

// Créer l'application, le bootstrap et démarre
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configurations/app.ini'
);
$application->bootstrap()
->run();

Nous allons juste ajouter une petite partie permettant d’inclure plus rapidement les classes de Zend en repassant par Zend_Autoloader et nous redéfinirons sa méthode d’inclusion. Voici donc le nouveau index.php qui vous parlera mieux que mes explications :
// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH',
realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV',
(getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV')
: 'production'));

// Typically, you will also want to add your library/ directory
// to the include_path, particularly if it contains your ZF install
set_include_path(implode(PATH_SEPARATOR, array(
dirname(dirname(__FILE__)) . '/library',
get_include_path(),
)));

//redéfinition de l'autoloader par défaut afin d'optimiser le chargement
require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setDefaultAutoloader(create_function('$class',
"include str_replace('_', '/', \$class) . '.php';"
));

/** Zend_Application */
//require_once 'Zend/Application.php';

// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configurations/app.ini'
);
$application->bootstrap()
->run();

Cette partie ne suffit pas, pour gagner encore du temps, je vous invite à suivre le conseil donné par l’équipe Zend en fin de documentation, à savoir, supprimer tous les require_once inutiles de la bibliothèque Zend. (je vous invite aussi à les enlever de vos controller, formulaires, …).

En effet, pour chaque require_once, le serveur va effectuer des accès disque et c’est ces accès disques qui ralentissent le serveur. La méthode est donc de les enlever et ensuite, notre redéfinition faite dans le index.php prendra le relais, elle effectuera tardivement le chargement de tous les fichiers nécessaires afin d’optimiser le chzrgement de nos classes. La documentation Zend explique mieux que moi cette partie:

Le chargement tardif (« lazy loading ») est une technique d’optimisation conçue pour repousser l’opération coûteuse de chargement d’une classe jusqu’au dernier moment possible – c’est-à-dire lors de l’instanciation d’un objet de cette classe, ou lors de l’utilisation d’une constante de classe ou d’une propriété statique. PHP supporte tout ceci via l’autoloading (ou « chargement automatique »), ce qui vous permet de définir un ou plusieurs callbacks à exécuter dans le but de faire correspondre un nom de classe à un fichier.

Cependant, la plupart des avantages que vous pourrez retirer de l’autoloading sont diminués si le code de votre librairie exécute toujours des appels à require_once – ce qui est précisément le cas de Zend Framework. La question est donc : comment éliminer ces déclarations require_once dans le but de maximiser les performances de l’autoloader.

Pour ce faire, il ne vous suffit que d’exécuter cette commande sous Linux (je rajouterai celle sous Windows et FreeBSD quand je les aurais retrouvé) :
% cd chemin/vers/la/librarie/ZendFramework
% find . -name '*.php' -not -wholename '*/Loader/Autoloader.php' \
-not -wholename '*/Application.php' -print0 | \
xargs -0 sed --regexp-extended --in-place 's/(require_once)/\/\/ \1/g'

Pour finir, nous définissons une nouvelle fonction dans notre Bootstrap principal afin que lui aussi tire parti de ces changements :
public static function autoload($class)
{
include str_replace('_', '/', $class) . '.php';
return $class;
}

Voilà, après ces quelques modifications, votre site devrait se charger un poil plus vite et consommer moins de mémoires.

Dans la seconde partie, je vous expliquerai comment créer une méthode qui mesure la charge mémoire de chacune de vos pages. Si vous avez des questions, des remarques, des critiques ou même des corrections, n’hésitez pas à me les faire parvenir.

Throrïn
A propos de l'auteur
Benjamin Besse

Je suis Analyste Développeur chez Goomeo et je suis passioné par tout ce qui touche aux technologies du Web. J'ai commencé par apprendre l'utilisation du Framework Zend et j'ai continué naturellement via Android. Le tout seulement avec les bases acquises en DUT et Licence professionnelle Informatique.

Laisser un commentaire

Commentaires

Bonjour, vos tuto sur Zend m’aide beaucoup, avez vous trouver la commande a effectuer sous console windows?svp
Merci d’avance :)

Bonjour, les commandes Zend sont identiques sur windows comme sur linux mais je préfère créer mes projets manuellement .

ah mais je ne parlais pas de la commandes zf mais de ce bout de code la :

% cd chemin/vers/la/librarie/ZendFramework
% find . -name ‘*.php’ -not -wholename ‘*/Loader/Autoloader.php’ \
-not -wholename ‘*/Application.php’ -print0 | \
xargs -0 sed –regexp-extended –in-place ‘s/(require_once)/\/\/ \1/g’

afin d’épurer le temps de chargement des pages zend :)

Désolé, je n’ai pas l’équivalent Windows pour cette commande. Je regarde si je la trouve et je vous la remettrai ici