Узнать PHP код, выполняемый на странице

Раздел: Разработка на PHP -> Отладка

Методы просмотра исходного кода PHP страницы при отладке

Как с помощью встроенных функций PHP вывести исходный код файла с подсветкой синтаксиса?

Основной метод - использование функции highlight_file() (или её алиаса show_source()). Эта функция принимает путь к файлу и выводит его содержимое с подсветкой синтаксиса. Пример:

<?php
highlight_file('index.php');
?>

Если файл не существует, функция вернёт false и вызовет предупреждение. Для проверки:

<?php
if (file_exists('config.php')) {
    highlight_file('config.php');
} else {
    echo 'Файл не найден.';
}
?>

Возможные проблемы: Функция выводит результат непосредственно в буфер, что не позволяет сохранить его в переменную. Для этого используйте file_get_contents и highlight_string с параметром true:

<?php
$source = file_get_contents('index.php');
$highlighted = highlight_string($source, true);
echo $highlighted;
?>

Другая проблема - риск утечки кода. Разрешайте эти функции только в среде разработки.

Как отследить все файлы, подключённые при выполнении скрипта?

Функция get_included_files() возвращает массив путей ко всем включённым файлам. Пример:

<?php
$files = get_included_files();
echo '<pre>';
print_r($files);
echo '</pre>';
?>

Также debug_backtrace() даёт стек вызовов с файлами и строками.

Динамически подключаемые файлы (через eval или переменные) могут не отражаться. Для точной трассировки используйте Xdebug.

Как использовать Xdebug для просмотра кода в реальном времени?

Xdebug - мощный отладчик. Настройка в php.ini:

zend_extension=xdebug.so
xdebug.remote_enable=1
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.idekey=PHPSTORM

После настройки IDE (например, PhpStorm) можно ставить точки останова. При выполнении скрипта отобразится текущая строка кода.

Типичные ошибки: неправильный порт, версии, замедление работы. Включайте Xdebug только в разработке.

Как посмотреть код без комментариев и лишних пробелов?

Функция php_strip_whitespace() удаляет комментарии и лишние пробелы. Пример:

<?php
echo '<pre>' . php_strip_whitespace('index.php') . '</pre>';
?>

Результат - компактный код.

Удаляются документация и подсказки. Не подходит для отладки, когда нужно видеть все строки.

Как разобрать PHP код на токены для анализа?

Функция token_get_all() разбивает код на лексические токены. Пример:

<?php
$tokens = token_get_all(file_get_contents('index.php'));
foreach ($tokens as $token) {
    if (is_array($token)) {
        echo token_name($token[0]) . ': ' . htmlspecialchars($token[1]) . ' (строка ' . $token[2] . ')<br>';
    } else {
        echo 'Простой символ: ' . htmlspecialchars($token) . '<br>';
    }
}
?>

Вывод показывает каждый токен с его типом, значением и номером строки.

Массив токенов может содержать и массивы, и строки. Обработка требует внимания. Также проблемы с кодировкой.

Как автоматически показывать строку ошибки с её кодом?

С помощью set_error_handler() и чтения файла:

<?php
function customErrorHandler($severity, $message, $file, $line) {
    if (file_exists($file)) {
        $lines = file($file);
        $code = $lines[$line - 1] ?? 'Неизвестная строка';
        echo 'Ошибка в $file на строке $line: $message<br>';
        echo 'Код: ' . htmlspecialchars($code);
    }
    return true;
}
set_error_handler('customErrorHandler');
// пример ошибки:
echo $undefinedVariable;
?>

При ошибке выводится строка кода.

Фатальные ошибки (E_ERROR) не перехватываются. Используйте register_shutdown_function для них. Остерегайтесь вывода чувствительных данных.

Расширенные примеры работы с исходным кодом PHP

Пример 1: Изменение стилей подсветки с помощью захвата вывода

Пример
<?php
ob_start();
highlight_file('index.php');
$highlighted = ob_get_clean();
$custom = str_replace('<code>', '<code style=\"background:#f5f5f5; padding:5px;\">', $highlighted);
echo $custom;
?>
Выводит исходный код с подсветкой и дополнительным стилем.

Пример 2: Построение карты вызовов с помощью debug_backtrace

Пример
<?php
function logCall($function, $file, $line) {
    echo \"$function вызвана в $file на строке $line\n\";
}
function a() { logCall(__FUNCTION__, __FILE__, __LINE__); b(); }
function b() { logCall(__FUNCTION__, __FILE__, __LINE__); c(); }
function c() { logCall(__FUNCTION__, __FILE__, __LINE__); }
a();
?>
a вызвана в /var/www/test.php на строке 6
b вызвана в /var/www/test.php на строке 7
c вызвана в /var/www/test.php на строке 8

Пример 3: Построчное выделение фрагмента кода из файла

Пример
<?php
function showCodeSnippet($file, $startLine, $linesAround = 3) {
    if (!file_exists($file)) return;
    $allLines = file($file);
    $from = max(0, $startLine - $linesAround - 1);
    $to = min(count($allLines), $startLine + $linesAround);
    for ($i = $from; $i < $to; $i++) {
        $num = $i + 1;
        $class = ($num == $startLine) ? ' style=\"background:yellow;\"' : '';
        echo \"<div$class>{$num}: \" . htmlspecialchars($allLines[$i]) . \"</div>\n\";
    }
}
showCodeSnippet('index.php', 15);
?>
Выводит строки вокруг 15-й с подсветкой самой строки.

Пример 4: Извлечение всех объявленных функций через token_get_all

Пример
<?php
$source = file_get_contents('index.php');
$tokens = token_get_all($source);
$functions = [];
foreach ($tokens as $i => $token) {
    if (is_array($token) && $token[0] == T_STRING && $tokens[$i-1][0] == T_FUNCTION) {
        $functions[] = $token[1];
    }
}
print_r(array_unique($functions));
?>
Array ( [0] => myFunc [1] => anotherFunc )

Исходный код PHP страницы - comments

En
Source php page (php)