СПОСОБЫ ОТЛАДКИ
ПРИ РАЗРАБОТКЕ ПОД MAGENTO


Павел Новицкий


Meet Magento Belarus 2012
Отладка кода вдвое сложнее,
чем его написание.

Так что если вы пишете код
настолько умно, насколько
можете, то вы по определению
недостаточно сообразительны,
чтобы его отлаживать.

Брайан Керниган
Magento в первую очередь — это PHP
Популярные практики при отладке PHP приложений.




                   1. Вывод ошибок
                   2. Значения переменной
                   3. Структурные данные
                   4. Отслеживание выполнения кода
                   5. Исследование объектов
                   6. Запросы к БД
Популярные практики при отладке PHP приложений.

 Вывод ошибок
 Значения переменной
 Структурные данные
 Отслеживание выполнения кода
 Исследование объектов
 Запросы к БД



                                Вывод ошибок

   Непосредственно в приложении:         В php.ini:

   ini_set('display_errors', 'On');      display_errors = On
   error_reporting(E_ALL | E_STRICT);    error_reporting = E_ALL | E_STRICT
Популярные практики при отладке PHP приложений.

 Вывод ошибок
 Значения переменной
 Структурные данные
 Отслеживание выполнения кода
 Исследование объектов
 Запросы к БД



                        Вывод значения переменной


                                     echo $myVar;

                                Практически бесполезно.

                   В большинстве случаев — потраченное зря время.
Популярные практики при отладке PHP приложений.

 Вывод ошибок
 Значения переменной
 Структурные данные
 Отслеживание выполнения кода
 Исследование объектов
 Запросы к БД



                                Вывод структурных данных


   echo '<pre>'.                             var_dump($myArray);
              print_r($myArray, true).
   '</pre>';



   Array
   (                                         array(2) { ["key1"]=> string(7) "value 1" ["key2"]=>
     [key1] => value 1                       string(7) "value 2" }
     [key2] => value 2
   )
Популярные практики при отладке PHP приложений.

 Вывод ошибок
 Значения переменной
 Структурные данные
 Отслеживание выполнения кода
 Исследование объектов
 Запросы к БД




                 Отслеживание выполнения кода


                     debug_backtrace() и print_debug_backtrace()
Популярные практики при отладке PHP приложений.

 Вывод ошибок
 Значения переменной
 Структурные данные
 Отслеживание выполнения кода
 Исследование объектов
 Запросы к БД




                      Что же у нас за объект?

                                get_class()

                                get_class_vars()

                                get_declared_classes()

                                method_exists()
Популярные практики при отладке PHP приложений.

 Вывод ошибок
 Значения переменной
 Структурные данные
 Отслеживание выполнения кода
 Исследование объектов
 Запросы к БД




                                  Запросы к БД


 a) echo $sql = "SELECT `some_field1` FROM `table` WHERE `some_field2` = '$var'";


 b) $res = mysql_query($sql) or die(mysql_error());
Для большинства приложений этого достаточно.


             А как же Magento?
Применение стандартных практик в Magento




                          Вывод ошибок

         error_reporting(E_ALL | E_STRICT);
         ini_set('display_errors', 1);



         if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) {
             Mage::setIsDeveloperMode(true);
         }

         в .htaccess добавить
         SetEnv MAGE_IS_DEVELOPER_MODE “true”
Применение стандартных практик в Magento




                  Вывод значения переменной


          Только для проверки какой-то промежуточной переменной.

                         Точно также бесполезно.
Применение стандартных практик в Magento




                  Вывод структурных данных



          $customer = Mage::getModel('customer/customer')->load(1);


          print_r($customer);
Применение стандартных практик в Magento




                                  Вывод структурных данных


Mage_Customer_Model_Customer Object ( [_eventPrefix:protected] => customer [_eventObject:protected] => customer [_errors:protected] =>
Array ( ) [_attributes:protected] => [_addresses:protected] => [_addressesCollection:protected] => [_isDeleteable:protected] => 1 [
_isReadonly:protected] => [_resourceName:protected] => customer/customer [_resource:protected] => [_resourceCollectionName:protected] =>
customer/customer_collection [_cacheTag:protected] => [_dataSaveAllowed:protected] => 1 [_isObjectNew:protected] => [_data:protected] =>
Array ( [entity_id] => 1 [entity_type_id] => 1 [attribute_set_id] => 0 [website_id] => 1 [email] => john.doe@example.com [group_id] => 1 [
increment_id] => 000000001 [store_id] => 1 [created_at] => 2007-08-30 23:23:13 [updated_at] => 2008-08-08 12:28:24 [is_active] => 1 [
firstname] => John [lastname] => Doe [password_hash] => 2049484a4020ed15d0e4238db22977d5:eg [prefix] => [middlename] => [suffix] =>
[taxvat] => [default_billing] => 274 [default_shipping] => 274 ) [_hasDataChanges:protected] => [_origData:protected] => Array ( [entity_id] =>
1 [entity_type_id] => 1 [attribute_set_id] => 0 [website_id] => 1 [email] => john.doe@example.com [group_id] => 1 [increment_id] =>
000000001 [store_id] => 1 [created_at] => 2007-08-30 23:23:13 [updated_at] => 2008-08-08 12:28:24 [is_active] => 1 [firstname] => John
[lastname] => Doe [password_hash] => 2049484a4020ed15d0e4238db22977d5:eg [prefix] => [middlename] => [suffix] => [taxvat] => [
default_billing] => 274 [default_shipping] => 274 ) [_idFieldName:protected] => entity_id [_isDeleted:protected] => [_oldFieldsMap:protected] =>
Array ( ) [_syncFieldsMap:protected] => Array ( ) )
Применение стандартных практик в Magento




                        Снова бесполезно?
Применение стандартных практик в Magento




                                           Varien_Object::getData()


                                           Varien_Object::debug()
Применение стандартных практик в Magento




                  Вывод структурных данных



          $customer = Mage::getModel('customer/customer')->load(1);


          echo '<pre>'.print_r($customer->debug(), true);
Применение стандартных практик в Magento


                 Вывод структурных данных
                         [entity_id] => 1
                         [entity_type_id] => 1
                         [attribute_set_id] => 0
                         [website_id] => 1
                         [email] => john.doe@example.com
                         [group_id] => 1
                         [increment_id] => 000000001
                         [store_id] => 1
                         [created_at] => 2007-08-30 23:23:13
                         [updated_at] => 2008-08-08 12:28:24
                         [is_active] => 1
                         [firstname] => John
                         [lastname] => Doe
                         [password_hash] => 2049484a4020ed15d0e4238db22977d5:eg
                         [prefix] =>
                         [middlename] =>
                         [suffix] =>
                         [taxvat] =>
                         [default_billing] => 274
                         [default_shipping] => 274
Применение стандартных практик в Magento




                 Отслеживание выполнения кода


         debug_backtrace()
                                           Varien_Debug::backtrace()
      print_debug_backtrace()
Применение стандартных практик в Magento




                       Изучение объекта

                             get_class()

                             get_class_vars()

                             get_declared_classes()

                             method_exists()



                   Используется повсеместно в Magento
Применение стандартных практик в Magento



                       Запросы к базе данных



                            echo $sql = "SELECT `some_field1` FROM `table`”;


                            $res = mysql_query($sql) or die(mysql_error());
Применение стандартных практик в Magento



                       Запросы к базе данных


                         Вывести запрос:

                         $myCollection->load(true);



                         Записать запрос в системный лог:

                         $myCollection->load(false, true);
Применение стандартных практик в Magento



                           Запросы к базе данных

         Mage::getModel('catalog/product')->getCollection()->load(true);




         $model = Mage::getModel('catalog/product')->getCollection();
         $sql = $model->getSelect()->__toString();
         echo $sql;




             SELECT `e`.* FROM `catalog_product_entity` AS `e`
Применение стандартных практик в Magento



                         Запросы к базе данных

           Записываем все запросы в var/debug/pdo_mysql.log




                lib/Varien/Db/Adapter/Pdo/Mysql.php:


                  protected $_debug        = true;
                  protected $_logAllQueries= true;
Что ещѐ?
Логирование
Экспериментируем

<?php

error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);

$mageFilename = 'app/Mage.php';
require_once $mageFilename;

Mage::setIsDeveloperMode(true);
umask(0);

Mage::app();

// … наш код …
— швейцарский нож разработчика



 ОТЛАДКА и ПРОФАЙЛИНГ
xDebug


                 Установка
         http://xdebug.org/download.php


                 Настройка
         xdebug.profiler_enable_trigger=on
         xdebug.remote_autostart=off
         xdebug.remote_enable=1
         xdebug.remote_host="127.0.0.1"
         xdebug.remote_port=9000
         xdebug.remote_handler="dbgp"
         xdebug.idekey="netbeans"
         xdebug.collect_vars=on
         xdebug.collect_params=4
         xdebug.show_local_vars=on
         xdebug.var_display_max_depth=5
         xdebug.show_exception_trace=on

         zend_extension=/usr/lib/php5/20090626+lfs/xdebug.so

         ; zend_extension_ts="c:phpextphp_xdebug-2.0.1-5.2.1.dll"
xDebug


         Настройка NetBeans IDE
xDebug


                    И что же нам это даѐт?
         http://example.com/index.php?XDEBUG_SESSION_START=netbeans
xDebug




         http://example.com/index.php?XDEBUG_SESSION_START=netbeans




                      Xdebug helper http://bit.ly/KuCo2c




                      easy Xdebug http://bit.ly/LKpvjC
xDebug




          Профайлинг



         xdebug.profiler_enable=1
xDebug — профайлинг


                      Визуализация логов


                Webgrind               http://bit.ly/LXMGFJ

                Kcachegrind            http://bit.ly/KGzyAw

                WinCacheGrind          http://bit.ly/Nh4iPY

                Xdebugtoolkit          http://bit.ly/LmB4t9

                MacCallGrind           http://bit.ly/LlerGS

                CachegrindVisualizer   http://bit.ly/OD6dLy
К нам пришѐл клиент…
<disable_local_modules>true</disable_local_modules>
<config>
    <modules>
        <Some_Module>
           <active>false</active>
        <Some_Module>
    </modules>
</config>
Magento Connect — developer tools



         Commerce Bug http://bit.ly/M8ggqh
Magento Connect — developer tools



         Developer Toolbar for Magento http://bit.ly/LnSW8s
Magento Connect — developer tools



         Advanced Developer Tools http://bit.ly/Lo1Vqa




                            Только для версий ниже 1.6.1
Magento Connect — developer tools




             Developer Toolbar http://bit.ly/LnD1Hk
Magento Connect — developer tools



                          Magento FirePHP http://bit.ly/LnYGyX

       Mage::helper('firephp')->send('Lorem ipsum sit amet ..');
       Mage::helper('firephp')->debug(Mage::getModel('catalog/product')->load(54));
Magento Connect — developer tools




                 Developer Helper http://bit.ly/OLauwz
СПАСИБО ЗА ВНИМАНИЕ



     pavel@belvg.com

Meet Magento Belarus debug Pavel Novitsky (rus)

  • 1.
    СПОСОБЫ ОТЛАДКИ ПРИ РАЗРАБОТКЕПОД MAGENTO Павел Новицкий Meet Magento Belarus 2012
  • 2.
    Отладка кода вдвоесложнее, чем его написание. Так что если вы пишете код настолько умно, насколько можете, то вы по определению недостаточно сообразительны, чтобы его отлаживать. Брайан Керниган
  • 3.
    Magento в первуюочередь — это PHP
  • 4.
    Популярные практики приотладке PHP приложений. 1. Вывод ошибок 2. Значения переменной 3. Структурные данные 4. Отслеживание выполнения кода 5. Исследование объектов 6. Запросы к БД
  • 5.
    Популярные практики приотладке PHP приложений. Вывод ошибок Значения переменной Структурные данные Отслеживание выполнения кода Исследование объектов Запросы к БД Вывод ошибок Непосредственно в приложении: В php.ini: ini_set('display_errors', 'On'); display_errors = On error_reporting(E_ALL | E_STRICT); error_reporting = E_ALL | E_STRICT
  • 6.
    Популярные практики приотладке PHP приложений. Вывод ошибок Значения переменной Структурные данные Отслеживание выполнения кода Исследование объектов Запросы к БД Вывод значения переменной echo $myVar; Практически бесполезно. В большинстве случаев — потраченное зря время.
  • 7.
    Популярные практики приотладке PHP приложений. Вывод ошибок Значения переменной Структурные данные Отслеживание выполнения кода Исследование объектов Запросы к БД Вывод структурных данных echo '<pre>'. var_dump($myArray); print_r($myArray, true). '</pre>'; Array ( array(2) { ["key1"]=> string(7) "value 1" ["key2"]=> [key1] => value 1 string(7) "value 2" } [key2] => value 2 )
  • 8.
    Популярные практики приотладке PHP приложений. Вывод ошибок Значения переменной Структурные данные Отслеживание выполнения кода Исследование объектов Запросы к БД Отслеживание выполнения кода debug_backtrace() и print_debug_backtrace()
  • 9.
    Популярные практики приотладке PHP приложений. Вывод ошибок Значения переменной Структурные данные Отслеживание выполнения кода Исследование объектов Запросы к БД Что же у нас за объект? get_class() get_class_vars() get_declared_classes() method_exists()
  • 10.
    Популярные практики приотладке PHP приложений. Вывод ошибок Значения переменной Структурные данные Отслеживание выполнения кода Исследование объектов Запросы к БД Запросы к БД a) echo $sql = "SELECT `some_field1` FROM `table` WHERE `some_field2` = '$var'"; b) $res = mysql_query($sql) or die(mysql_error());
  • 11.
    Для большинства приложенийэтого достаточно. А как же Magento?
  • 12.
    Применение стандартных практикв Magento Вывод ошибок error_reporting(E_ALL | E_STRICT); ini_set('display_errors', 1); if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) { Mage::setIsDeveloperMode(true); } в .htaccess добавить SetEnv MAGE_IS_DEVELOPER_MODE “true”
  • 13.
    Применение стандартных практикв Magento Вывод значения переменной Только для проверки какой-то промежуточной переменной. Точно также бесполезно.
  • 14.
    Применение стандартных практикв Magento Вывод структурных данных $customer = Mage::getModel('customer/customer')->load(1); print_r($customer);
  • 15.
    Применение стандартных практикв Magento Вывод структурных данных Mage_Customer_Model_Customer Object ( [_eventPrefix:protected] => customer [_eventObject:protected] => customer [_errors:protected] => Array ( ) [_attributes:protected] => [_addresses:protected] => [_addressesCollection:protected] => [_isDeleteable:protected] => 1 [ _isReadonly:protected] => [_resourceName:protected] => customer/customer [_resource:protected] => [_resourceCollectionName:protected] => customer/customer_collection [_cacheTag:protected] => [_dataSaveAllowed:protected] => 1 [_isObjectNew:protected] => [_data:protected] => Array ( [entity_id] => 1 [entity_type_id] => 1 [attribute_set_id] => 0 [website_id] => 1 [email] => john.doe@example.com [group_id] => 1 [ increment_id] => 000000001 [store_id] => 1 [created_at] => 2007-08-30 23:23:13 [updated_at] => 2008-08-08 12:28:24 [is_active] => 1 [ firstname] => John [lastname] => Doe [password_hash] => 2049484a4020ed15d0e4238db22977d5:eg [prefix] => [middlename] => [suffix] => [taxvat] => [default_billing] => 274 [default_shipping] => 274 ) [_hasDataChanges:protected] => [_origData:protected] => Array ( [entity_id] => 1 [entity_type_id] => 1 [attribute_set_id] => 0 [website_id] => 1 [email] => john.doe@example.com [group_id] => 1 [increment_id] => 000000001 [store_id] => 1 [created_at] => 2007-08-30 23:23:13 [updated_at] => 2008-08-08 12:28:24 [is_active] => 1 [firstname] => John [lastname] => Doe [password_hash] => 2049484a4020ed15d0e4238db22977d5:eg [prefix] => [middlename] => [suffix] => [taxvat] => [ default_billing] => 274 [default_shipping] => 274 ) [_idFieldName:protected] => entity_id [_isDeleted:protected] => [_oldFieldsMap:protected] => Array ( ) [_syncFieldsMap:protected] => Array ( ) )
  • 16.
    Применение стандартных практикв Magento Снова бесполезно?
  • 17.
    Применение стандартных практикв Magento Varien_Object::getData() Varien_Object::debug()
  • 18.
    Применение стандартных практикв Magento Вывод структурных данных $customer = Mage::getModel('customer/customer')->load(1); echo '<pre>'.print_r($customer->debug(), true);
  • 19.
    Применение стандартных практикв Magento Вывод структурных данных [entity_id] => 1 [entity_type_id] => 1 [attribute_set_id] => 0 [website_id] => 1 [email] => john.doe@example.com [group_id] => 1 [increment_id] => 000000001 [store_id] => 1 [created_at] => 2007-08-30 23:23:13 [updated_at] => 2008-08-08 12:28:24 [is_active] => 1 [firstname] => John [lastname] => Doe [password_hash] => 2049484a4020ed15d0e4238db22977d5:eg [prefix] => [middlename] => [suffix] => [taxvat] => [default_billing] => 274 [default_shipping] => 274
  • 20.
    Применение стандартных практикв Magento Отслеживание выполнения кода debug_backtrace() Varien_Debug::backtrace() print_debug_backtrace()
  • 21.
    Применение стандартных практикв Magento Изучение объекта get_class() get_class_vars() get_declared_classes() method_exists() Используется повсеместно в Magento
  • 22.
    Применение стандартных практикв Magento Запросы к базе данных echo $sql = "SELECT `some_field1` FROM `table`”; $res = mysql_query($sql) or die(mysql_error());
  • 23.
    Применение стандартных практикв Magento Запросы к базе данных Вывести запрос: $myCollection->load(true); Записать запрос в системный лог: $myCollection->load(false, true);
  • 24.
    Применение стандартных практикв Magento Запросы к базе данных Mage::getModel('catalog/product')->getCollection()->load(true); $model = Mage::getModel('catalog/product')->getCollection(); $sql = $model->getSelect()->__toString(); echo $sql; SELECT `e`.* FROM `catalog_product_entity` AS `e`
  • 25.
    Применение стандартных практикв Magento Запросы к базе данных Записываем все запросы в var/debug/pdo_mysql.log lib/Varien/Db/Adapter/Pdo/Mysql.php: protected $_debug = true; protected $_logAllQueries= true;
  • 26.
  • 27.
  • 28.
    Экспериментируем <?php error_reporting(E_ALL | E_STRICT); ini_set('display_errors',1); $mageFilename = 'app/Mage.php'; require_once $mageFilename; Mage::setIsDeveloperMode(true); umask(0); Mage::app(); // … наш код …
  • 29.
    — швейцарский ножразработчика ОТЛАДКА и ПРОФАЙЛИНГ
  • 30.
    xDebug Установка http://xdebug.org/download.php Настройка xdebug.profiler_enable_trigger=on xdebug.remote_autostart=off xdebug.remote_enable=1 xdebug.remote_host="127.0.0.1" xdebug.remote_port=9000 xdebug.remote_handler="dbgp" xdebug.idekey="netbeans" xdebug.collect_vars=on xdebug.collect_params=4 xdebug.show_local_vars=on xdebug.var_display_max_depth=5 xdebug.show_exception_trace=on zend_extension=/usr/lib/php5/20090626+lfs/xdebug.so ; zend_extension_ts="c:phpextphp_xdebug-2.0.1-5.2.1.dll"
  • 31.
    xDebug Настройка NetBeans IDE
  • 32.
    xDebug И что же нам это даѐт? http://example.com/index.php?XDEBUG_SESSION_START=netbeans
  • 33.
    xDebug http://example.com/index.php?XDEBUG_SESSION_START=netbeans Xdebug helper http://bit.ly/KuCo2c easy Xdebug http://bit.ly/LKpvjC
  • 34.
    xDebug Профайлинг xdebug.profiler_enable=1
  • 35.
    xDebug — профайлинг Визуализация логов Webgrind http://bit.ly/LXMGFJ Kcachegrind http://bit.ly/KGzyAw WinCacheGrind http://bit.ly/Nh4iPY Xdebugtoolkit http://bit.ly/LmB4t9 MacCallGrind http://bit.ly/LlerGS CachegrindVisualizer http://bit.ly/OD6dLy
  • 36.
    К нам пришѐлклиент…
  • 37.
  • 38.
    <config> <modules> <Some_Module> <active>false</active> <Some_Module> </modules> </config>
  • 40.
    Magento Connect —developer tools Commerce Bug http://bit.ly/M8ggqh
  • 41.
    Magento Connect —developer tools Developer Toolbar for Magento http://bit.ly/LnSW8s
  • 42.
    Magento Connect —developer tools Advanced Developer Tools http://bit.ly/Lo1Vqa Только для версий ниже 1.6.1
  • 43.
    Magento Connect —developer tools Developer Toolbar http://bit.ly/LnD1Hk
  • 44.
    Magento Connect —developer tools Magento FirePHP http://bit.ly/LnYGyX Mage::helper('firephp')->send('Lorem ipsum sit amet ..'); Mage::helper('firephp')->debug(Mage::getModel('catalog/product')->load(54));
  • 45.
    Magento Connect —developer tools Developer Helper http://bit.ly/OLauwz
  • 46.