Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Отладка PHP в 1С-Битрикс

Отладка PHP в 1С-Битрикс

Evgeny E. Neverov

December 06, 2022
Tweet

More Decks by Evgeny E. Neverov

Other Decks in Education

Transcript

  1. Какие проблемы • Логика работы настроек 1С-Битрикс; • Причина изменения

    элементов инфоблока, заказов; • Удаление цен при обмене с 1С; • Редирект; • Скорость ответа сервера; • Зависание скрипта.
  2. Инструменты 1. Вывод значения и трассировка 2. Вывод ошибок 3.

    Лог ошибок 1С-Битрикс 4. Логирование 5. События 6. Исходный код 7. Reflection 8. Вывод sql 9. Xdebug 10. Xhprof 11. PhpSpy 12. disable_functions (^php8.0)
  3. Вывод значения и трассировка Вывод состояния переменной в браузер или

    терминал. Можно применять, когда известен участок кода, в котором происходит действие. Встроенные функции: • print_r($var) - значение переменной в удобочитаемом виде; • var_dump($var) - значение переменной с указанием типов; • var_export($var) - значение переменной в виде PHP-кода; • debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) - трассировка скрипта. Пользовательские функции: • pr($var) - print_r с оформлением. Не рекомендуется выполнять на боевой копии в публичной части сайта и оставлять в коммите. https://git.t-dir.com/support/techdir.stuff/-/tree/master/manuals/debug/print_r
  4. Пример: понять откуда подключается скрипт На тестовом сервере в файл

    ./bitrix/modules/main/lib/page/asset.php добавляем код вывода трассировки в метод addCss, addJs или addString. if (mb_stripos($path, 'jquery') !== false) { echo '<pre>'; print_r(func_get_args()); debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); echo '</pre>'; } Не забываем удалить после отладки. Выполнять только на тестовой копии.
  5. Вывод ошибок Настройки php: • error_reporting - уровень ошибок для

    обработки. error_reporting(E_ALL & ~E_NOTICE); • display_errors - выводить ошибки. ini_set(‘display_errors’, 1); • log_errors - логировать ошибки. ini_set(‘log_errors’, 1); • error_log - путь к файлу лога. ini_set(‘error_log’, __DIR__ . ‘/log.txt’); Собственный обработчик ошибок - set_error_handler Можно изменять в php.ini и во время выполнения. https://git.t-dir.com/support/techdir.stuff/-/tree/master/manuals/debug/display_error s
  6. Пример: вывод предупреждений при ssl-соединении $level = error_reporting(E_ALL); // $level

    теперь содержит предыдущий уровень ошибок ini_set('display_errors', 1); ini_set('log_errors', 0); $handler = set_error_handler(function($errno, $errstr, $errfile, $errline) { print_r([$errno, $errstr, $errfile, $errline]); }); // --- START $socket = fsockopen('ssl://your.domain', 443, $errno, $errstr, 5); var_dump($socket); // --- FINISH error_reporting($level); set_error_handler($handler);
  7. Fatal error: Allowed memory size of 268435456 bytes exhausted (tried

    to allocate 24576 bytes) Подключаем xdebug с xdebug.mode=develop, он выведет трассировку
  8. Логирование ошибок в 1С-Битрикс В 1С-Битрикс присутствует встроенный класс для

    логирования php-ошибок. В .settings.php достаточно добавить элемент массива exception_handling. Когда применять — всегда. Необходимо при разработке, после публикации задачи, при обращениях пользователя. • Уровень логирования при разработке включает warning (E_ALL & ~E_NOTICE & ~E_STRICT & ~E_USER_WARNING & ~E_USER_NOTICE & ~E_DEPRECATED) • Уровень логирования для поиска исключения (E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_USER_WARNING & ~E_USER_NOTICE & ~E_COMPILE_WARNING & ~E_DEPRECATED) * * - недостаток свободного места не всегда исключение, операции с файлами - E_WARNING. https://git.t-dir.com/support/techdir.stuff/-/tree/master/manuals/debug/exception_handling
  9. Пример: лог фатальных ошибок 'exception_handling' => array ( 'value' =>

    array ( 'debug' => false, 'handled_errors_types' => E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_USER_WARNING & ~E_USER_NOTICE & ~E_COMPILE_WARNING & ~E_DEPRECATED, 'exception_errors_types' => E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_USER_WARNING & ~E_USER_NOTICE & ~E_COMPILE_WARNING & ~E_DEPRECATED, 'ignore_silence' => false, 'assertion_throws_exception' => true, 'assertion_error_type' => 256, 'log' => array ( 'settings' => array ( 'file' => 'bitrix/modules/error.log', 'log_size' => 1000000, ), ), ), 'readonly' => false, ),
  10. Логирование ошибок в 1С-Битрикс: Sentry Для записи ошибок на боевых

    проектах рекомендуем использовать techdir.sentry. Позволяет группировать ошибки, сохранять предыдущие запросы пользователя и дополнительную информацию об окружении. Процесс подключения: 1. Отправить свой логин на sentry.io и запросить DSN для проекта у Неверова или Мишакова 2. Установить модуль и внести значения на странице настроек модуля
  11. Логирование Встроенные в PHP: • file_put_contents($fileName, $string, FILE_APPEND); Встроенные в

    1С-Битрикс: • \Bitrix\Main\Diag\FileLogger; • AddMessage2Log; • SendError. Модуль логирования techdir.extendedlog Когда применять — сохранять состояние в момент события. https://git.t-dir.com/support/techdir.stuff/-/tree/master/manuals/debug/manual_log
  12. Пример: логирование в файл use Bitrix\Main\Diag; $path = $_SERVER['DOCUMENT_ROOT'] .

    '/bitrix/php_interface/mylog.txt'; $message = (new Diag\LogFormatter())->format("{text}\n{trace}\n{delimiter}\n", [ 'text' => 'My text', 'trace' => Diag\Helper::getBackTrace(20, DEBUG_BACKTRACE_IGNORE_ARGS, 2), ]); (new Diag\FileLogger($path))->error($message);
  13. События События — способ изменения поведения и внедрения в стандартный

    процесс выполнения скрипта 1С-Битрикс. Когда применять: • Уточнить причину вызова функции (редирект, изменение заказа, элемента); • Логирование состояния. https://git.t-dir.com/support/techdir.stuff/-/tree/master/manuals/debug/events
  14. $eventManager = \Bitrix\Main\EventManager::getInstance(); $eventManager->addEventHandler('main', 'OnBeforeLocalRedirect', function(&$url) { debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); print_r(func_get_args()); die();

    }); LocalRedirect('/'); https://dev.1c-bitrix.ru/api_help/main/functions/other/localredirect.php События: Остановка при выполнении редиректа
  15. События: Логирование создания заказа use Bitrix\Main\Diag; use Bitrix\Main\EventManager; use Bitrix\Main\Event;

    use Bitrix\Sale; $eventManager = EventManager::getInstance(); $eventManager->addEventHandler('sale', 'OnSaleOrderSaved', function(Event $event) { /** @var Sale\Order $order */ $order = $event->getParameter('ENTITY'); if (!$order->isNew()) { return; } $path = __DIR__ . '/log-order.txt'; $message = (new Diag\LogFormatter())->format("{text}\n{trace}\n{delimiter}\n", [ 'text' => 'Order #' . $order->getId(), 'trace' => Diag\Helper::getBackTrace(20, DEBUG_BACKTRACE_IGNORE_ARGS, 2), ]); (new Diag\FileLogger($path))->info($message); }); https://dev.1c-bitrix.ru/api_d7/bitrix/sale/events/sale_setfields.php
  16. События: ORM use Bitrix\Main\Diag; use Bitrix\Main\EventManager; use Bitrix\Main\Entity; $eventManager =

    EventManager::getInstance(); $eventManager->addEventHandler('catalog', '\Bitrix\Catalog\Product::OnAfterUpdate', function(Entity\Event $event) { $path = __DIR__ . '/log-orm.txt'; $message = (new Diag\LogFormatter())->format("{text}\n{trace}\n{delimiter}\n", [ 'text' => print_r($event->getParameter('fields'), true), 'trace' => Diag\Helper::getBackTrace(20, DEBUG_BACKTRACE_IGNORE_ARGS, 2), ]); (new Diag\FileLogger($path))->info($message); }); https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=43&LESSON_ID=2244#events
  17. Исходный код (PhpStorm) Статический анализ, навигация по коду и поиск

    по подстроке. Когда применять: • Текст ошибки в коде — находим по подстроке lang-файл, по коду сообщения находим функцию; • Опции модуля — берем название инпута на странице, находим использование в коде; • Откуда функция может быть вызвана — ctrl+click по названию в определении функции; • Исходный код метода — ctrl+click по названию в коде вызова; • Алгоритм работы функции 1С-Битрикс — подключаем ядро 1С-Битрикс или скачиваем с тестовой копии, переходим к определению функции. https://git.t-dir.com/support/techdir.stuff/-/tree/master/manuals/debug/source_code
  18. Reflection PHP включает в себя полноценный Reflection API, который предоставляет

    возможность проводить интроспекцию классов, интерфейсов, функций, методов и модулей. Кроме того, Reflection API позволяет получать doc-блоки комментариев функций, классов и методов. Назначение: • Место определения класса или функции; • Анализ состояния приватных переменных. Документация https://git.t-dir.com/support/techdir.stuff/-/tree/master/manuals/debug/reflection
  19. Xdebug Расширение php, позволяющее выполнять пошаговую отладку. В каких случаях

    применять: • Нужно понять процесс выполнения скрипта, вставлять print_r на каждой строке сложно; • Проверка работы скрипта. Инструкция по настройке в Техдиректор и PhpStorm. Запросы, не поддерживающие cookie, можно отлаживать, добавив get-параметр XDEBUG_SESSION_START=XXXX, где XXXX - код вашей сессии. https://git.t-dir.com/support/techdir.stuff/-/tree/manual_debug/manuals/debug/xdeb ug
  20. Xhprof Профайлер выполнения скрипта, в котором можно найти статистику по

    потреблению памяти и времени выполнения функции. Когда применять: скрипт выполняется долго, известно, каким образом воспроизвести проблему. Примеры задач: • Время ответа сервера; • Генерация файла выгрузки; • Долгое обновление элемента инфоблока. https://git.t-dir.com/support/techdir.stuff/-/tree/manual_debug/manuals/debug/xhpr of
  21. Xhprof: сбор отчета Для сбора отчета необходимо подключить расширение xhprof.so

    на тестовом сервере с помощью систменого администратора. Скачать библиотеку xhprof в корень сайта и распаковать. Обернуть проблемный код в вызов xhprof_enable и xhprof_disable, записать данные в отчет с помощью библиотеки.
  22. Xhprof: сбор отчета xhprof_enable(XHPROF_FLAGS_MEMORY | XHPROF_FLAGS_CPU); // your code register_shutdown_function(function

    () { $data = xhprof_disable(); require_once $_SERVER['DOCUMENT_ROOT'] . '/xhprof/xhprof_lib/utils/xhprof_lib.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/xhprof/xhprof_lib/utils/xhprof_runs.php'; $xhprof_runs = new XHProfRuns_Default(); $xhprof_runs->save_run($data, "REPLACE_ME"); }); где X.X.X - версия библиотеки в корне сайта, REPLACE_ME - метка вашего профайла.
  23. Phpspy Получение трассировки текущего состояния процесса. Когда применять: скрипт зависает,

    непонятна причина. Как запустить: • Запускается от имени root • На тестовом собран, для запуска обратиться к системному администратору (/var/www/vhosts/tdstore.t-dir.dev/phpspy/phpspy). На бою склонировать git • Пример запуска ./phpspy -P httpd, смотреть в документации git https://git.t-dir.com/support/techdir.stuff/-/tree/manual_debug/manuals/debug/phps py
  24. Disable_functions (php ^8.0) В php больше 8.0 есть возможность переопределить

    встроенные функции php (например, header). Когда применять: 1. Редирект выполняется через функцию header.
  25. Disable_functions (php ^8.0) Переключаем php на 8.0 или выше, добавляем

    в php.ini (с помощью администратора через plesk) disable_functions=header Определяем функцию header в init.php function header(string $header, bool $replace = true, int $response_code = 0) { echo '<pre>'; echo $header; echo PHP_EOL; debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); echo '</pre>'; }