Мой вариант диагностической функции для битрикс-разработчиков

Когда только начинал работать - выводил просто var_dump() и все. Далее узнал о функции print_r() - стал чередовать эти 2 функции.

Потом, когда начались работы по доработкам на боевых сайтах - потребовалась проверка того, чтобы диагностические сообщения были доступны только админам - конструкция обросла еще и проверкой того, что пользователь админ (с периодической заменой проверки на админа, на проверку на конкретный ID-пользователя).

И вот, уже больше года пользуюсь своей собственной функцией:

     function pre($var,$stop=false,$inconsole = false, $UID = false){
         $bt = debug_backtrace();
         $bt = $bt[0];
         $dRoot = $_SERVER["DOCUMENT_ROOT"];
         $dRoot = str_replace("/", "\\", $dRoot);
         $bt["file"] = str_replace($dRoot, "", $bt["file"]);
         $dRoot = str_replace("\\", "/", $dRoot);
         $bt["file"] = str_replace($dRoot, "", $bt["file"]);
         if ($GLOBALS['USER']->IsAdmin()){
             if($UID && intval($UID)!==$GLOBALS['USER']->GetID()) return;
             if($inconsole){
                 echo "<script>console.log('File: ".$bt['file']." [".$bt['line']."]');console.log(".json_encode($var).");</script>";
             }
             else{
                 echo '<div style="padding:3px 5px; background:#99CCFF; font-weight:bold;">File: '.$bt["file"].' ['.$bt["line"].']</div>';
                 echo '<pre>';
                 ((is_array($var) || is_object($var)) ? print_r($var) : var_dump($var));
                 echo '</pre>';
             }
             if($stop) exit(0);
         }
     }

$var - переменная для анализа; $stop - флаг, который при необходимости останавливает выполненеи дальнейших операций после данной функции; $inconsole - при истинном значении вывод осуществляется не в окно пользователю, а в консоль браузера; $UID - используется для вывода диагностического сообщения только пользователю с заданным ID. 

Функция эта уже давным давно не актуальна, давно уже использую для этих целей полноценный Debug-класс. Вот модифицированная данная функция:

Дебаг-функция в пределах дебаг-класса

Подключаем класс в init.php:

CModule::AddAutoloadClasses('', ['\Pai\CDev' => '/local/php_interface/include/classes/CDev.php',]);

И по указанному пути размещаем сам файл с классом "CDev":

namespace Pai;
use ReflectionClass;
class CDev
{
...
/**
     * Улучшенная debug-функция с поддержкой eval()
     *
     * @param mixed $var     Переменная для отладки
     * @param array $options Дополнительные опции:
     *                       - 'depth' => int Глубина вложенности (по умолчанию 3)
     *                       - 'showHidden' => bool Показывать скрытые свойства (по умолчанию false)
     *                       - 'stop' => bool Остановить выполнение после вывода (по умолчанию false)
     *                       - 'toConsole' => bool Выводить в консоль браузера (по умолчанию false)
     *                       - 'onlyForUser' => int|false Показывать только для пользователя с указанным ID (по
     *                       умолчанию false - для всех)
     *                       - 'rawOutput' => bool Выводить как raw HTML (по умолчанию false, автоматически
     *                       определяется)
     */
    public static function debug($var, array $options = [])
    {
        // Настройки по умолчанию
        $defaults = [
            'depth'       => 3,
            'showHidden'  => false,
            'stop'        => false,
            'toConsole'   => false,
            'onlyForUser' => false,
            'rawOutput'   => null, // Автоматическое определение
        ];

        $options = array_merge($defaults, $options);

        // Автоматическое определение rawOutput
        if ($options['rawOutput'] === null) {
            // Определяем контекст выполнения
            $isHttp = isset($_SERVER['HTTP_HOST']) || isset($_SERVER['REQUEST_URI']);
            $isCli = php_sapi_name() === 'cli' || defined('STDIN');
            $isEval = false;

            // Проверяем, выполняется ли код через eval()
            $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5);
            foreach ($backtrace as $trace) {
                if (isset($trace['function']) && $trace['function'] === 'eval') {
                    $isEval = true;
                    break;
                }
            }

            // Логика определения формата вывода
            $options['rawOutput'] = ($isHttp && !$isCli && !$isEval);
        }

        if ($options['toJson']) {
            header('Content-Type: application/json');
            echo json_encode(['debug' => $var, 'trace' => $backtrace], JSON_PRETTY_PRINT);
            exit;
        }

        // Проверка прав доступа
        global $USER;
        if ($options['onlyForUser'] !== false &&
            (!$USER->IsAuthorized() || $USER->GetID() != $options['onlyForUser'])) {
            return;
        }

        // Получаем информацию о месте вызова
        $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0];
        $file = str_replace($_SERVER['DOCUMENT_ROOT'], '', $backtrace['file']);
        $line = $backtrace['line'];

        // Формируем заголовок с информацией о месте вызова
        $header = sprintf(
            'Debug: %s [Line: %d] [Type: %s]',
            $file,
            $line,
            is_object($var) ? get_class($var) : gettype($var)
        );

        // Если вывод в консоль браузера
        if ($options['toConsole']) {
            $output = [
                'header'    => $header,
                'data'      => $var,
                'backtrace' => $backtrace
            ];
            echo '';

            if ($options['stop']) {
                die();
            }
            return;
        }

        // Подготовка вывода
        ob_start();

        if ($options['rawOutput']) {
            // Вывод как HTML
            echo '
'; echo '
' . $header . '
'; echo '
'; self::printDebugVariable($var, $options['depth'], $options['showHidden'], 0, true); echo '
'; // JavaScript для переключения видимости echo ''; } else { // Вывод как текст (для eval и CLI) echo "=== DEBUG ===\n"; echo $header . "\n"; self::printDebugVariable($var, $options['depth'], $options['showHidden'], 0, false); echo "\n=============\n"; } $output = ob_get_clean(); // Для AJAX-запросов устанавливаем правильный Content-Type if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { header('Content-Type: ' . ($options['rawOutput'] ? 'text/html' : 'text/plain') . '; charset=utf-8'); } echo $output; if ($options['stop']) { die(); } } /** * Рекурсивная функция для вывода переменной */ protected static function printDebugVariable($var, $depth = 3, $showHidden = false, $level = 0, $isHtml = true) { if ($depth <= 0) { if ($isHtml) { echo '[max depth reached]'; } else { echo '[max depth reached]'; } return; } $type = gettype($var); if ($isHtml) { // HTML-вывод switch ($type) { case 'string': echo '"' . htmlspecialchars($var) . '"'; echo ' (string, length: ' . strlen($var) . ')'; break; case 'integer': echo '' . $var . ''; echo ' (integer)'; break; case 'double': echo '' . $var . ''; echo ' (float)'; break; case 'boolean': echo '' . ($var ? 'true' : 'false') . ''; echo ' (boolean)'; break; case 'NULL': echo 'null'; echo ' (null)'; break; case 'array': echo 'array (count: ' . count($var) . ')'; if (!empty($var)) { $id = uniqid('array_'); echo ''; echo ''; } break; case 'object': $class = get_class($var); echo 'object(' . $class . ')'; $id = uniqid('object_'); echo ''; echo ''; break; default: echo '' . print_r($var, true) . ''; echo ' (' . $type . ')'; } } else { // Текстовый вывод (для eval и CLI) switch ($type) { case 'string': echo '"' . $var . '" (string, length: ' . strlen($var) . ')'; break; case 'integer': echo $var . ' (integer)'; break; case 'double': echo $var . ' (float)'; break; case 'boolean': echo ($var ? 'true' : 'false') . ' (boolean)'; break; case 'NULL': echo 'null (null)'; break; case 'array': echo 'array (count: ' . count($var) . ')'; if (!empty($var)) { echo "\n"; foreach ($var as $key => $value) { echo str_repeat(' ', $level + 1) . '[' . $key . '] => '; self::printDebugVariable($value, $depth - 1, $showHidden, $level + 1, $isHtml); echo "\n"; } } break; case 'object': $class = get_class($var); echo 'object(' . $class . ')'; echo "\n"; // Выводим свойства объекта $reflection = new ReflectionClass($var); $properties = $reflection->getProperties(); foreach ($properties as $property) { $property->setAccessible(true); if (!$showHidden && $property->isPrivate()) { continue; } echo str_repeat(' ', $level + 1); echo $property->isPrivate() ? 'private ' : ($property->isProtected() ? 'protected ' : 'public '); echo '$' . $property->getName() . ' = '; self::printDebugVariable( $property->getValue($var), $depth - 1, $showHidden, $level + 1, $isHtml ); echo "\n"; } break; default: echo print_r($var, true) . ' (' . $type . ')'; } } } ... }

Обращение к функции идет в таком виде:

// В обычном веб-контексте (HTML)
Pai\CDev::debug($variable);

// В eval() или CLI (текстовый вывод)
Pai\CDev::debug($variable, ['rawOutput' => false]);

// С максимальной глубиной 5
Pai\CDev::debug($variable, ['depth' => 5]);

// С выводом скрытых свойств
Pai\CDev::debug($variable, ['showHidden' => true]);
Количество показов: 2940
23.06.2015


Реклама: ООО 'КвикСофт'. ИНН 7734706120. ERID: CQH36pWzJqCRJ4UXKvMNSFqMsX7dYBaPEMRX5odpmNzefp
Реклама: ИП Попович А.И. ИНН: 231537677964. ERID: CQH36pWzJqCRJ4UXZAPx4DUtAuR68f7j7SEtAw8y5oHN14

Разработка сайта

Подайте заявку на разработку сайта на базе готового решения от компании 1С-Битрикс или одного из партнеров компании. Максимально подробно опишите, чему будет посвящен сайт, если это интернет-магазин - что он будет продавать, нужна ли мультиязычность, будут ли разные типы цен (розница, опт, крупный опт), будет ли интеграция с 1С, будет ли выгрузка товаров на различные торговые площадки...

Сопровождение сайта

Вы можете подать заявку на сопровождение вашего сайта на базе 1С-Битрикс. Сопровождение включает в себя: проверка актуальности обновлений сайта, проверка актуальности резервной копии, консультации по сайту. Опишите в заявке, какие еще объемы планируются на сопровождении и на какой срок вы планируете заключить договор на сопровождение - мы подберем подходящий вам бюджет на сопровождение

Работы по сайту

Вы можете подать заявку на выполнение определенного объема работ по сайту. Опишите в заявке объем работ. Это может быть разработка какого-то нового функционала, доработки по имеющемуся функционалу, доработки под требования сео-специалистов. На основании заявки вам будет сформирован бюджет работ, а также названы сроки на выполнение тех или иных работ.