Skip to content
Caution: You are browsing the legacy symfony 1.x part of this website.

Mejorando la barra de depuración web

Language

por Ryan Weaver

La barra de depuración web de Symfony incluye por defecto una gran variedad de utilidades que facilitan la depuración y la mejora de rendimiento de las aplicaciones. La barra de depuración web está formada por varias herramientas llamadas paneles de depuración web y que están relacionadas con la cache, la configuración, los archivos de log, el uso de memoria, la versión de Symfony y el tiempo de procesamiento. Además, Symfony 1.3 ha introducido dos nuevos paneles de depuración web con información sobre la vista y los emails enviados.

Barra de depuración web

Desde Symfony 1.2 los programadores pueden crear sus propios paneles de depuración web y añadirlos a la barra de depuración web. Este capítulo muestra cómo crear un nuevo panel de depuración web y después se explican todas sus opciones y posibles configuraciones. Además, el plugin ac2009WebDebugPlugin contiene diversos paneles de depuración muy útiles y que utilizan algunas de las técnicas mostradas en este capítulo.

Creando un nuevo panel de depuración web

Los elementos que forman la barra de depuración web se denominan paneles de depuración web y son unas clases especiales que heredan de la clase sfWebDebugPanel class. En realidad, crear un nuevo panel es muy sencillo. Crea un nuevo archivo llamado sfWebDebugPanelDocumentation.class.php en el directorio lib/debug/ de tu proyecto (el directorio no existe y por tanto tienes que crearlo):

// lib/debug/sfWebDebugPanelDocumentation.class.php
class acWebDebugPanelDocumentation extends sfWebDebugPanel
{
  public function getTitle()
  {
    return '<img src="/legacy/images/documentation.png" alt="Documentation Shortcuts" height="16" width="16" /> docs';
  }
 
  public function getPanelTitle()
  {
    return 'Documentation';
  }
 
  public function getPanelContent()
  {
    $content = 'Placeholder Panel Content';
 
    return $content;
  }
}

Como mínimo todos los paneles deben implementar los métodos getTitle(), getPanelTitle() y getPanelContent().

  • sfWebDebugPanel::getTitle(): determina cómo se muestra inicialmente el panel en la barra de depuración web. Al igual que la mayoría de paneles, el panel que estamos creando se va a mostrar mediante un pequeño icono y un nombre corto.

  • sfWebDebugPanel::getPanelTitle(): su valor se muestra en la parte superior del contenido del panel mediante una etiqueta <h1>. También se utiliza como valor del atributo title del enlace que encierra el icono de la barra, por lo que no puede incluir ningún tipo de código HTML.

  • sfWebDebugPanel::getPanelContent(): genera el contenido HTML que se muestra al pulsar sobre el icono del panel.

El último paso que falta consiste en notificar a la aplicación que se quiere incluir un nuevo panel en la barra. Para ello, añade un nuevo listener para el evento debug.web.load_panels, que se notifica cuando la barra de depuración obtiene los paneles que se van a mostrar. En primer lugar, modificar el archivo config/ProjectConfiguration.class.php para escuchar ese evento:

// config/ProjectConfiguration.class.php
public function setup()
{
  // ...
 
  $this->dispatcher->connect('debug.web.load_panels', array(
    'acWebDebugPanelDocumentation',
    'listenToLoadDebugWebPanelEvent'
  ));
}

A continuación, añade la función listenToLoadDebugWebPanelEvent() del listener a la clase acWebDebugPanelDocumentation.class.php para incluir el panel en la barra:

// lib/debug/sfWebDebugPanelDocumentation.class.php
public static function listenToLoadDebugWebPanelEvent(sfEvent $event)
{
  $event->getSubject()->setPanel(
    'documentation',
    new self($event->getSubject())
  );
}

¡Y eso es todo! Refresca la página para ver el resultado de forma inmediata.

Barra de depuración web

tip

Desde Symfony 1.3, es posible utilizar en la URL un parámetro llamado sfWebDebugPanel para mostrar desplegado un determinado panel web al cargar la página. Si por ejemplo se añade ?sfWebDebugPanel=documentation al final de la URL, se abrirá automáticamente el panel que se acaba de crear. Esta característica puede ser muy útil cuando se crean paneles propios.

Los tres tipos de paneles de depuración web

Internamente existen tres tipos diferentes de paneles de depuración web.

El tipo sólo icono

El tipo más básico de panel es aquel que solamente muestra un icono y un texto en la barra. El ejemplo clásico es el del panel memory, que muestra la cantidad de memoria utilizada para generar la página y que no hace nada cuando se pincha sobre el. Para crear un panel de tipo sólo icono, simplemente haz que el método getPanelContent() devuelva una cadena vacía. La única información del panel la genera el método getTitle():

public function getTitle()
{
  $totalMemory = sprintf('%.1f', (memory_get_peak_usage(true) / 1024));
 
  return '<img src="'.$this->webDebug->getOption('image_root_path').'/memory.png" alt="Memory" /> '.$totalMemory.' KB';
}
 
public function getPanelContent()
{
  return;
}

El tipo enlace

Al igual que el panel sólo icono, un panel de tipo enlace consiste en un panel sin contenido. A diferencia del panel sólo icono, cuando se pincha sobre un panel de tipo enlace, el navegador carga la URL especificada por el método getTitleUrl() del panel. Para crear un panel de tipo enlace, haz que el método getPanelContent() devuelva una cadena vacía y añade en la clase un método llamado getTitleUrl().

public function getTitleUrl()
{
  // enlace a una URI externa
  return '/api/1_3/';
 
  // enlace a una ruta en tu aplicación
  return url_for('homepage');
}
 
public function getPanelContent()
{
  return;
}

El tipo contenido

Se trata del tipo más popular con mucha diferencia. Estos paneles tienen un contenido HTML que se muestra cuando se pincha sobre el nombre del panel en la barra de depuración web. Para crear este tipo de panel, simplemente haz que el método getPanelContent() no devuelva una cadena vacía.

Personalizando el contenido del panel

Una vez creado e incluido el panel de depuración web a la barra, su contenido se puede añadir fácilmente mediante el método getPanelContent(). Symfony proporciona varios métodos para facilitar la creación de contenido avanzado y usable.

sfWebDebugPanel::setStatus()

Por defecto todos los paneles de la barra de depuración web muestran un color de fondo gris. Si se quiere llamar la atención sobre algún contenido del panel, su fondo se puede mostrar de color naranja o rojo.

Barra de depuración con error

Para modificar el color de fondo del panel se emplea el método setStatus(). Este método acepta cualquier constante de prioridad definida por la clase sfLogger. En concreto se han definido tres niveles de estado diferentes que se corresponden con los tres colores de fondo de los paneles (gris, naranja y rojo). Normalmente el método setStatus() se invoca desde el método getPanelContent() cuando se cumple alguna condición que merece una atención especial.

public function getPanelContent()
{
  // ...
 
  // mostrar el fondo gris (valor por defecto)
  $this->setStatus(sfLogger::INFO);
 
  // mostrar el fondo naranja
  $this->setStatus(sfLogger::WARNING);
 
  // mostrar el fondo rojo
  $this->setStatus(sfLogger::ERR);
}

sfWebDebugPanel::getToggler()

Uno de los elementos más comunes de los paneles de depuración web existentes es el toggler o alternador, un pequeño elemento con forma de flecha que muestra u oculta alternativamente cierto contenido cuando se pincha sobre él.

Alternador

Esta funcionalidad se puede incluir fácilmente en un panel propio mediante la función getToggler(). Si por ejemplo se quiere alternar en el panel el contenido de una lista:

public function getPanelContent()
{
  $contenidoLista = '<ul id="debug_documentation_list" style="display: none;">
    <li>Elemento 1</li>
    <li>Elemento 2</li>
  </ul>';
 
  $toggler = $this->getToggler('debug_documentation_list', 'Muestra/oculta lista');
 
  return sprintf('<h3>Elementos de la lista %s</h3>%s',  $toggler, $contenidoLista);
}

El método getToggler requiere dos argumentos: el valor del atributo id del elemento DOM que se va a alternar y el título que se va a incluir como valor del atributo title del enlace asociado con el toggler. Obviamente debes crear el elemento DOM con ese atributo id y también tienes que crear todo el contenido que se va a mostrar/ocultar con el alternador.

sfWebDebugPanel::getToggleableDebugStack()

Este método es similar a getToggler(), ya que muestra una pequeña flecha que muestra u oculta alternativamente cierto contenido. En este caso, el contenido es el de una traza de depuración. Una de sus principales utilidades es la de mostrar los mensajes de log de una clase propia. Si suponemos que una clase llamada myCustomClass genera mensajes de log propios:

class myCustomClass
{
  public function doSomething()
  {
    $dispatcher = sfApplicationConfiguration::getActive()
      ->getEventDispatcher();
 
    $dispatcher->notify(new sfEvent($this, 'application.log', array(
      'priority' => sfLogger::INFO,
      'Begin execution of myCustomClass::doSomething()',
    )));
  }
}

El siguiente ejemplo muestra la lista de todos los mensajes de log de la clase myCustomClass junto con la traza de depuración de cada uno.

public function getPanelContent()
{
  // obtiene todos los mensajes de log de la petición actual
  $logs = $this->webDebug->getLogger()->getLogs();
 
  $listadoLogs = '';
  foreach ($logs as $log)
  {
    if ($log['type'] == 'myCustomClass')
    {
      $listadoLogs .= sprintf('<li>%s %s</li>',
        $log['message'],
        $this->getToggleableDebugStack($log['debug_backtrace'])
      );
    }
  }
 
  return sprintf('<ul>%s</ul>', $listadoLogs);
}

Información de depuración en la barra

note

Aunque no se cree un panel propio, los mensajes de log de la clase myCustomClass se pueden ver en el panel de mensajes de log. La ventaja de esta técnica es que se puede mostrar solamente un subconjunto pequeño de los mensajes de log y además controlar la forma en la que se muestran.

sfWebDebugPanel::formatFileLink()

Una de las novedades de Symfony 1.3 es que se puede pinchar sobre el nombre de un archivo en la barra de depuración web para abrirlo con nuestro editor de texto favorito. Puedes obtener más información en el artículo "What's new" de Symfony 1.3.

Para hacer uso de esta característica para cualquier archivo, se emplea el método formatFileLink(). Además del propio archivo, se puede enlazar a una línea concreta. El código del siguiente ejemplo crea un enlace que abre el archivo config/ProjectConfiguration.class.php y posiciona el editor de texto en la línea 15:

public function getPanelContent()
{
  $contenido = '';
 
  // ...
 
  $ruta = sfConfig::get('sf_config_dir') . '/ProjectConfiguration.class.php';
  $contenido .= $this->formatFileLink($path, 15, 'Configuración del proyecto');
 
  return $contenido;
}

Tanto el segundo argumento (número de línea) como el tercero (el texto del enlace) son opcionales. Si no se indica el tercer argumento, el texto del enlace es la propia ruta del archivo.

note

Antes de probar el ejemplo anterior, asegúrate de haber configurado la nueva opción de enlazar archivos. Esta opción se configura mediante la clave sf_file_link_format del archivo de configuración settings.yml o mediante la opción file_link_format de xdebug. La última forma asegura que el proyecto no sea dependiente de un IDE específico.

Otros trucos de la barra de depuración web

Normalmente lo mejor de tu panel de depuración web será el contenido que muestres y la forma en la que lo hagas. No obstante, existen algunos otros trucos interesantes.

Eliminar los paneles por defecto

Por defecto Symfony muestra varios paneles en la barra de depuración web. Si no quieres mostrar alguno de ellos, debes hacer uso del evento debug.web.load_panels. Utiliza la misma función listener de las secciones anteriores, elimina todo su contenido y añade la siguiente función removePanel(). El código del siguiente ejemplo hace que no se muestre el panel con la información sobre la memoria:

public static function listenToLoadDebugWebPanelEvent(sfEvent $event)
{
  $event->getSubject()->removePanel('memory');
}

Obteniendo parámetros de la petición en un panel

Una de las cosas que más utilizan los paneles de depuración web son los parámetros de la petición. El siguiente código muestra cómo obtener el parámetro event_id para realizar una consulta a la base de datos y así poder mostrar la información de un determinado objeto:

$parametros = $this->webDebug->getOption('request_parameters');
if (isset($parametros['event_id']))
{
  $objeto = Doctrine::getTable('Event')->find($parametros['event_id']);
}

Ocultar un panel cuando no sea necesario

En determinadas ocasiones, los paneles no tienen ningún tipo de información relevante que mostrar para la petición actual. En estos casos es mejor ocultar directamente el panel. Supongamos que en el ejemplo anterior el panel no muestra información útil a menos que exista un parámetro de la petición llamado event_id. Para ocultar ese panel cuando no exista ese parámetro, simplemente no se devuelve ningún contenido en el método getTitle():

public function getTitle()
{
  $parametros = $this->webDebug->getOption('request_parameters');
  if (!isset($parametros['event_id']))
  {
    return;
  }
 
  return '<img src="/acWebDebugPlugin/legacy/images/documentation.png" alt="Documentation Shortcuts" height="16" width="16" /> docs';
}

Últimas reflexiones

La barra de depuración web facilita enormemente el trabajo de los programadores, pero es mucho más que una herramienta para mostrar información. La posibilidad de añadir paneles de depuración propios a la barra hace que su potencial sólo esté limitado por la imaginación de los programadores. El plugin ac2009WebDebugPlugin incluye solamente algunos de los muchos paneles que se pueden crear, así que no dudes en crear tus propios paneles.

This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.