3.2. Zend_Db_Profiler

3.2.1. Introduction

Zend_Db_Profiler peut être activé pour permettre le profilage de requêtes. Les profils incluent les requête exécutées par l'adapteur, ainsi que leur temps d'exécution, permettant l'inspection des requêtes qui ont été exécutées sans avoir besoin de rajouter du code spécifique au débuggage aux classes. L'utilisation avancé permet aussi au developpeur de filtrer quelles requêtes il souhaite profiler.

Le profileur s'active soir en passant une directive au constructeur de l'adapteur, soit en spécifiant à l'adapteur de l'activer plus tard.

<?php
require_once 'Zend/Db.php';

$params = array (
    'host'     => '127.0.0.1',
    'username' => 'malory',
    'password' => '******',
    'dbname'   => 'camelot',
    'profiler' => true  // turn on profiler; set to false to disable (default)
);

$db = Zend_Db::factory('PDO_MYSQL', $params);

// coupe le profileur:
$db->getProfiler()->setEnabled(false);

// active le profileur:
$db->getProfiler()->setEnabled(true);
?>

3.2.2. Utiliser le profileur

Vous pouvez récupérer le profileur en utilisant la méthode getProfiler() de l'adapteur:

<?php
$profileur = $db->getProfiler();
?>

Ceci retourne une instance de Zend_Db_Profiler. Avec cette instance, le développeur peut examiner les requêtes en utilisant un éventail de méthodes :

  • getTotalNumQueries() retourne le nombre total de requêtes profilées.
  • getTotalElapsedSeconds() retourne le nombre totale de secondes écoulées pour chaque requête profilée.
  • getQueryProfiles() retourne un tableau de tous les profils de requêtes.
  • getLastQueryProfile() retourne le plus récent profil de requête, peut importe si la requête à fini de s'exécuter ou pas (si l'exécution n'est pas finie, le temps de fin sera null).
  • clear() nettoie tous les anciens profils de la pile.

La valeur de retour de getLastQueryProfile() et les élements individuels de getQueryProfiles() sont des objets de type Zend_Db_Profiler_Query qui permettent d'inspecter les requêtes:

  • getQuery() retourne le SQL de la requête sous forme de texte.
  • getElapsedSecs() retourn le nombre de seconde d'exécution de la requête.

L'information que Zend_Db_Profiler founie est utile pour profiler des goulets d'étranglement dans les applications, ainsi que pour débugger les requêtes qui viennent d'être exécutées. Pour le moment, pour voir la dernière requête qui vient de s'exécuter:

<?php
$query = $profileur->getLastQueryProfile();

echo $query->getQuery();
?>

Si une page se génère lentement, utilisez le profileur pour déterminer le nombre total de requêtes, et ensuite passer d'une requête à l'autre pour voir laquelle a été la plus longue:

<?php
$tempsTotal       = $profileur->gettotalElapsedSeconds();
$nombreRequetes   = $profileur->getTotalNumQueries();
$tempsLePlusLong  = 0;
$requeteLaPlusLongue = null;

foreach ($profileur->getQueryProfiles() as $query) {
    if ($query->getElapsedSecs() > $tempsLePlusLong) {
        $tempsLePlusLong  = $query->getElapsedSecs();
        $requeteLaPlusLongue = $query->getQuery();
    }
}

echo 'Executé ' . $nombreRequetes . ' requêtes en ' . $tempsTotal . ' secondes' . "\n";
echo 'Temps moyen : ' . $nombreRequetes / $tempsTotal . ' secondes' . "\n";
echo 'Requête la plus lente : ' . $tempsLePlusLong . "\n";
echo "Requête la plus longue : \n" . $requeteLaPlusLongue . "\n";
?>

3.2.3. Utilisation avancée du profileur

En plus de l'inspection de requête, le profileur permet aussi au développeur de filtrer quelles requêtes il veut profiler. Les méthodes suivantes fonctionnent avec une instance de Zend_Db_Profiler :

3.2.3.1. Filtrer par temps d'exécution

setFilterElapsedSecs() permet au développeur de définir un temps minimum d'exécution de la requête avant que celle-ci soit profilée. Pour retirer le filtre, passez une valeur null à la méthode.

<?php
// Seules les requêtes qui durent au moins 5 secondes sont profilées:
$profileur->setFilterElapsedSecs(5);

// Profil de toutes les requête, peu importe leur longueur:
$profileur->setFilterElapsedSecs(null);
?>

3.2.3.2. Filtrer par type de requête

setFilterQueryType() permet au développeur de définir quel type de requêtes doivent être profilées; to profile multiple types, logical OR them. Les types de requêtes sont définis sous forme de constantes de Zend_Db_Profiler :

  • Zend_Db_Profiler::CONNECT : opérations de connexion ou de sélection de base de données.
  • Zend_Db_Profiler::QUERY : requête générale qui ne correspond pas aux autres types.
  • Zend_Db_Profiler::INSERT : toute requête qui ajoute des données dans la base de données, généralement INSERT.
  • Zend_Db_Profiler::UPDATE : toute requête qui met à jour des données, généralement UPDATE.
  • Zend_Db_Profiler::DELETE : toute requête qui efface des données, généralement DELETE.
  • Zend_Db_Profiler::SELECT : toute requête qui récupère des données, généralement SELECT.
  • Zend_Db_Profiler::TRANSACTION : toute requête qui concerne des opérations de transaction, comme start transaction, commit, ou rollback.

Comme avec setFilterElapsedSecs(), vous pouvez retirer tous les filtres en passant null comme unique argument.

<?php
// profile uniquement les requêtes SELECT
$profileur->setFilterQueryType(Zend_Db_Profiler::SELECT);

// profile les requêtes SELECT, INSERT, et UPDATE
$profileur->setFilterQueryType(Zend_Db_Profiler::SELECT | Zend_Db_Profiler::INSERT | Zend_Db_Profiler::UPDATE);

// profile les requêtes DELETE
$profileur->setFilterQueryType(Zend_Db_Profiler::DELETE);

// Efface tous les filtres
$profileur->setFilterQueryType(null);
?>

3.2.3.3. Récupérer les profils par type de requête

Utiliser setFilterQueryType() peut réduire les profils générés. Cependant il est parfois utile de garder tous les profils et voit uniquement ceux dont on a besoin, à un moment donné. Une autre possibilité de getQueryProfiles() est qu'il est possible de filtrer à la volée, en passant un type de requête (ou une combinaison logique de types de requête) comme premier argument; voir Section 3.2.3.2, « Filtrer par type de requête » pour une liste des constantes de types de requête.

            <?php
// Récupère uniquement les profils des requêtes SELECT
$profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT);

// Récupère uniquement les profils des requêtes SELECT, INSERT, et UPDATE
$profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::SELECT | Zend_Db_Profiler::INSERT | Zend_Db_Profiler::UPDATE);

// Récupère uniquement les profils des requêtes DELETE (on peut donc comprendre pourquoi les données
// disparaissent)
$profiles = $profiler->getQueryProfiles(Zend_Db_Profiler::DELETE);
?>