W3docs

getTraceAsString()

Метод PHP getTraceAsString(): как он возвращает стек вызовов исключения в виде строки, как читать вывод и как его логировать или отображать.

Что делает getTraceAsString()

getTraceAsString() — метод, доступный для каждого PHP-исключения (любого класса, реализующего ThrowableException, Error и их подклассов). Он возвращает стек вызовов — цепочку функций и методов, активных в момент выброса исключения — в виде единой читаемой строки.

Стек вызовов отвечает на вопрос «как выполнение добралось сюда?» Когда что-то выбрасывается глубоко внутри кода, одно лишь сообщение (getMessage()) говорит вам что пошло не так, а трассировка показывает точный путь вызовов, который к этому привёл. Именно поэтому она является наиболее ценным инструментом при отладке ошибки, которую сложно воспроизвести.

getTraceAsString() — строковая версия getTrace(), возвращающей те же данные в виде структурированного массива. Используйте getTrace(), когда нужно программно анализировать отдельные кадры; используйте getTraceAsString(), когда требуется просто записать или вывести трассировку.

Синтаксис

public Throwable::getTraceAsString(): string

Метод не принимает аргументов и объявлен final в базовых классах Exception и Error, поэтому всегда возвращает стандартный формат трассировки PHP. Вызывается на объекте пойманного исключения внутри блока catch:

<?php

try {
    // Code that may throw an exception
} catch (Throwable $e) {
    $trace = $e->getTraceAsString();
}

Перехват Throwable (а не только Exception) позволяет также обрабатывать объекты Error, такие как TypeError и DivisionByZeroError. Полную иерархию см. в главе Exception.

Полный запускаемый пример

Следующий скрипт выбрасывает исключение на два уровня вглубь, чтобы наглядно показать, как выглядит строка трассировки:

<?php

function loadUser(int $id): array
{
    throw new InvalidArgumentException("No user with id $id");
}

function handleRequest(): void
{
    loadUser(42);
}

try {
    handleRequest();
} catch (Throwable $e) {
    echo $e->getTraceAsString();
}

Вывод:

#0 /app/index.php(10): loadUser(42)
#1 /app/index.php(14): handleRequest()
#2 {main}

Чтение вывода

Каждая строка — это один кадр в стеке вызовов, перечисленный начиная с самого внутреннего:

  • #0, #1, … — номер кадра. #0 — вызов, выполнявшийся в момент выброса исключения; более высокие номера — вызывающие функции выше по стеку.
  • /app/index.php(10) — файл и номер строки места вызова.
  • loadUser(42) — вызванная функция или метод с аргументами. Длинные строковые аргументы обрезаются (например, '/etc/app/missin...') для сохранения читаемости трассировки.
  • #2 {main} — специальный последний кадр, обозначающий скрипт верхнего уровня (глобальную область видимости).

Место выброса (точный файл и строка, где был выполнен throw) не включается в эту строку — оно хранится в getFile() и getLine().

Примеры

Пример 1: Запись трассировки в файл

В продакшене вы редко хотите показывать трассировку пользователю — вы записываете её для последующего анализа. Объедините сообщение, файл и строку с трассировкой для получения полной записи:

<?php

try {
    // Code that may throw an exception
} catch (Throwable $e) {
    $entry = sprintf(
        "[%s] %s in %s:%d\n%s\n\n",
        date('Y-m-d H:i:s'),
        $e->getMessage(),
        $e->getFile(),
        $e->getLine(),
        $e->getTraceAsString()
    );

    file_put_contents('/path/to/app.log', $entry, FILE_APPEND | LOCK_EX);
}

LOCK_EX предотвращает перемешивание записей в журнале при одновременных запросах. Для реальных приложений предпочтительнее библиотека логирования, такая как Monolog, однако базовые данные — та же строка, что вы получаете здесь.

Пример 2: Отображение трассировки в браузере (только для разработки)

При локальной разработке бывает удобно вывести трассировку прямо на страницу. Оберните её в <pre>, чтобы сохранить переносы строк, и экранируйте, чтобы содержимое трассировки не могло внедрить HTML:

<?php

try {
    // Code that may throw an exception
} catch (Throwable $e) {
    echo '<pre>' . htmlspecialchars($e->getTraceAsString()) . '</pre>';
}

Никогда не показывайте трассировки конечным пользователям в продакшене — они раскрывают пути к файлам, структуру кода и иногда значения аргументов, которые могут помочь злоумышленникам. Защитите это проверкой среды окружения.

Пример 3: Сохранение трассировки при повторном выбросе

Когда вы перехватываете низкоуровневое исключение и выбрасываете более информативное, передайте оригинальное как предыдущее исключение, чтобы его трассировка не была потеряна:

<?php

try {
    // some database call that throws PDOException
} catch (PDOException $e) {
    throw new RuntimeException('Could not load the report', 0, $e);
}

Новое RuntimeException имеет собственную трассировку, а getPrevious() возвращает оригинальное исключение (и его getTraceAsString()). Стандартный обработчик непойманных исключений в PHP выводит оба, в цепочке.

Распространённые ловушки

  • Трассировка описывает место выброса, а не место перехвата. Она фиксируется в момент создания исключения, поэтому вызов getTraceAsString() позже всё равно показывает, где возникло исключение, а не где вы его обработали.
  • Аргументы могут быть усечены или скрыты. Длинные строки сокращаются; при включённой настройке INI zend.exception_ignore_args (по умолчанию в многих продакшн-конфигурациях) значения аргументов полностью опускаются из соображений безопасности.
  • Метод возвращает строку, а не null. Даже для исключения, выброшенного на верхнем уровне, вы получите как минимум кадр #0 {main}.

Связанные методы

  • getTrace() — те же данные в виде структурированного массива.
  • getMessage() — читаемое сообщение об ошибке.
  • getCode() — числовой код исключения.
  • getPrevious() — связанное предыдущее исключение.
  • set-exception-handler() — глобальная обработка непойманных исключений.

Заключение

getTraceAsString() преобразует стек вызовов исключения в компактную, пригодную для логирования строку, что делает его одним из наиболее ценных инструментов диагностики ошибок в PHP. Используйте его вместе с getMessage(), getFile() и getLine() для полной картины каждого сбоя, записывайте в лог вместо отображения пользователям в продакшене и сохраняйте цепочку с помощью getPrevious() при повторном выбросе.

Практика

Практика
Что делает функция 'getTraceAsString()' в PHP?
Что делает функция 'getTraceAsString()' в PHP?
Was this page helpful?