Con questo articolo vorrei condividere la mia esperienza nell’utilizzo di varie tecniche che permettono di fare debug in un e-commerce sviluppato con Magento.

Stampare a video le variabili php

Dato che Magento si basa su Zend Framework, è possibile sfruttare una delle sue funzioni che ha proprio lo scopo di fare debug del nostro codice php. L’istruzione con cui possiamo utilizzarla è Zend_Debug::dump($var), dove $var è la variabile di cui vogliamo visualizzare il contenuto.

Questo metodo utilizza la funzione php var_dump() per visualizzare il tipo e il contenuto della variabile, e utilizza degli accorgimenti per aiutarci a leggere tali informazioni nella pagina web in cui stiamo effettuando il debug, come per esempio includere l’output nei tag html <pre> e convertire i caratteri speciali con le html entities.

Se si effettuano più dump nella stessa pagina, può tornare utile il secondo parametro della funzione che permette di specificare una label per riconoscere qual’è il dump che stiamo visualizzando.

Farò un esempio per dare un idea di quale possa essere l’utilizzo di questa funzione. Se scriviamo la seguente istruzione nella vista della scheda prodotto

Zend_Debug::dump($_product->getData(), 'Debug prodotto numero 1')

quello che vedremo visitando una scheda prodotto lato frontend è questo:

Debug prodotto numero 1 array(57) {
  ["store_id"] => "1" string(1) 
  ["entity_id"] => "1" string(1)
  ["entity_type_id"] => "4" string(1)
  ["attribute_set_id"] => "4" string(1)
  ["type_id"] => "simple" string(6)
  ["sku"] => "test-product" string(12)
  ["has_options"] => "0" string(1)
  ["required_options"] => "0" string(1)
  ["created_at"] => "2012-05-03 15:24:35" string(19)
  ["updated_at"] => "2013-02-04 15:28:43" string(19)
  ["name"] => "test product" string(12)
  ["meta_title"] => NULL
  ["meta_description"] => NULL
  ...

Se si vuole approfondire, sono disponibili le specifiche della funzione a questo link.

Utilizzare i log di Magento

Se dobbiamo effettuare un debug di una grande quantità di dati, oppure stiamo facendo dei test su un sito online di cui non possiamo compromettere la visualizzazione, è sicuramente più indicato stampare il dump di una variabile all’interno di un file servendoci della funzione Mage::log() di Magento. Per utilizzare questa funzione dobbiamo prima assicurarci che siano attivati i log di Magento collegandoci nell’area amministrativa in Sistema > Configurazione > Sviluppa > Impostazioni log > Abilitato: Sì.

I due utilizzi più frequenti sono i seguenti:

Mage::log($var);
Mage::log($var, null, 'nome_file.log');

dove $var è la variabile di cui vogliamo stampare il contenuto.

Nel primo caso l’output verrà stampato nel file var/log/system.log insieme ad altri log presenti nel codice di Magento, mentre nel secondo caso troveremo l’output nel file di cui abbiamo specificato il nome nel terzo parametro (nel caso specifico in var/log/nome_file.log). Il secondo parametro è necessario specificarlo solo in casi particolari ed indica il livello di priorità che si vuole dare al log. Se si vuole approfondire questo aspetto è disponibile la documentazione della casse Zend_Log sulla quale si basa la funzione.

A differenza della funzione Zend_Debug::dump(), questa funzione accetta in input solamente le variabili, e non il risultato di un’operazione. In questo caso quindi l’esempio di prima andrebbe replicato in questo modo:

$var_log = $_product->getData();
Mage::log($var_log);

Logging delle variabili javascript

Per fare debug nel codice javascript si può utilizzare la funzione console.log(var) visualizzandone l’output nella console di un qualsiasi strumento per sviluppatori offerto dal browser che si sta utilizzando (es: FireBug per Firefox, Developer Tools per Chrome).

Se non si riuscissero a visualizzare gli output in alcuni browser, si consiglia di commentare la seguente porzione di codice nel file js/varien/js.js che in alcuni casi compromette il corretto funzionamento di questa funzione (in Magento 1.7 si trova alla riga 638).

if (!("console" in window) || !("firebug" in console))
{
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

    window.console = {};
    for (var i = 0; i < names.length; ++i)
        window.console[names[i]] = function() {}
}
[/code]

<h2>Logging delle query sql</h2>
Infine, per fare debug delle query sql che vengono eseguite sul nostro database, dobbiamo agire sulla classe <em>Varien_Db_Adapter_Pdo_Mysql</em> che si trova in <em>lib/Varien/Db/Adapter/Pdo/Mysql.php</em>.

Nella definizione delle variabili si trovano le seguenti:

[code type="php"]
    /**
     * Write SQL debug data to file
     *
     * @var bool
     */
    protected $_debug               = false;

    /**
     * Minimum query duration time to be logged
     *
     * @var float
     */
    protected $_logQueryTime        = 0.05;

    /**
     * Log all queries (ignored minimum query duration time)
     *
     * @var bool
     */
    protected $_logAllQueries       = false;

    /**
     * Add to log call stack data (backtrace)
     *
     * @var bool
     */
    protected $_logCallStack        = false;

    /**
     * Path to SQL debug data log
     *
     * @var string
     */
    protected $_debugFile           = 'var/debug/pdo_mysql.log';

Prima di tutto dobbiamo portare a true la variabile $_debug per attivare il log delle query. Da questo momento verranno stampate nel file specificato nella variabile $_debugFile tutte quelle query che hanno una durata maggiore o uguale al tempo specificato nella variabile $_logQueryTime.

Se si vuole stampare tutte le query ignorando il limite sulla durata, impostare a true la variabile $_logAllQueries, mentre se si vuole stampare il backtrace che ha portato all’esecuzione della singola query, assegnare il valore true alla variabile $_logCallStack.

Nel caso in cui si stia facendo debug in ambiente di produzione, è consigliabile limitare i log solamente per gli accessi provenienti dal proprio indirizzo IP, in modo da stampare solamente le query causate dai test che si stanno eseguendo e non dagli accessi degli utenti. Ad esempio, è possibile agire sul metodo _debugStat() della stessa classe, e sostituire

if (!$this->_debug) {
    return $this;
}

con

if (!$this->_debug || $_SERVER['REMOTE_ADDR'] != 'xx.xx.xx.xx') {
    return $this;
}

dove xx.xx.xx.xx va ovviamente sostituito con il proprio indirizzo IP.