Метод Exception::getLine() в PHP: подробное руководство
Узнайте, как метод Exception::getLine() в PHP возвращает номер строки, где было создано исключение, и как применять его при отладке и логировании.
Когда в PHP что-то идёт не так, первое, что обычно нужно знать, — это где именно возникла ошибка. Метод Exception::getLine() даёт точный ответ: он возвращает номер строки, в которой был создан объект исключения. В сочетании с getMessage() и getFile() он даёт исчерпывающую картину «что и где» для любой перехваченной ошибки — а это основа полезного логирования и отладки.
На этой странице описаны сигнатура метода, что именно он измеряет, полный работающий пример и типичные ошибки, которых следует избегать.
Синтаксис
final public Exception::getLine(): intМетод не принимает аргументов и возвращает значение типа int. Он определён в базовом классе Exception, поэтому все встроенные исключения (RuntimeException, InvalidArgumentException, TypeError и другие), а также любые пользовательские исключения наследуют его. Поскольку метод объявлен как final, переопределить его в подклассе невозможно.
Что на самом деле означает «строка»
Это самое важное, что необходимо понять: getLine() возвращает строку, в которой объект исключения был создан (место вызова new Exception(...) / throw new ...), а не строку с источником проблемы и не строку, где исключение было перехвачено.
Таким образом, если ваш код вызывает функцию, которая внутри выбрасывает исключение, getLine() укажет на оператор throw внутри этой функции — а не на место вашего вызова. Чтобы отследить полный путь от вашего вызова до throw, используйте getTrace() или getTraceAsString().
Полный работающий пример
В примере ниже определяется функция, которая выбрасывает исключение при отсутствии файла; затем исключение перехватывается и выводится информация о месте ошибки:
<?php
function readFileContents(string $path): string
{
if (!file_exists($path)) {
throw new Exception("File not found: $path"); // this is line 6
}
return file_get_contents($path);
}
try {
echo readFileContents('/no/such/file.txt');
} catch (Exception $e) {
echo "Error on line " . $e->getLine() . ": " . $e->getMessage();
}Вывод:
Error on line 6: File not found: /no/such/file.txtОбратите внимание: сообщаемая строка — 6, то есть оператор throw внутри readFileContents(), — хотя вызов, запустивший исключение, находится на строке 13. Это и есть правило «место создания, а не место вызова» в действии.
Совместное использование getLine() и getFile()
Номер строки сам по себе неоднозначен в многофайловом проекте, поэтому в реальном коде его почти всегда выводят вместе с именем файла из getFile():
<?php
try {
$age = -5;
if ($age < 0) {
throw new InvalidArgumentException("Age cannot be negative");
}
} catch (Exception $e) {
printf(
"[%s] %s (line %d in %s)\n",
get_class($e),
$e->getMessage(),
$e->getLine(),
basename($e->getFile())
);
}Вывод (имя файла зависит от названия вашего скрипта):
[InvalidArgumentException] Age cannot be negative (line 5 in script.php)Здесь getLine() возвращает 5 — строку с оператором throw внутри блока try. Перехват через Exception работает для InvalidArgumentException, поскольку любой тип исключения в конечном счёте наследует Exception.
Когда использовать
- Логирование. Записывайте
getLine()иgetFile()в записи журнала, чтобы сообщение без трассировки стека оставалось отслеживаемым. - Пользовательские страницы ошибок. В среде разработки можно показывать номер строки разработчику; в продакшне — логировать его, а пользователю показывать общее сообщение.
- Повторное оборачивание исключений. Когда вы перехватываете низкоуровневое исключение и выбрасываете доменное, сохраняйте оригинальные
getLine()/getFile()(или используйте цепочку черезgetPrevious()), чтобы не потерять корневую причину.
Типичные ошибки
- Ожидание места вызова. Как показано выше,
getLine()указывает место выброса, а не место вызова выбрасывающего кода. Для полного пути используйте трассировку. - Вызов без перехвата.
getLine()— метод экземпляра, его можно вызвать только на объекте исключения, на который у вас есть ссылка, — как правило, это$eиз блокаcatch. - Путаница с
getCode().getCode()возвращает числовой код исключения — самостоятельное значение, которое вы задаёте при создании исключения; оно не имеет никакого отношения к номерам строк.
Заключение
Exception::getLine() возвращает целочисленный номер строки, в которой было создано исключение, — небольшой, но важный элемент отладочной информации. В сочетании с getMessage(), getFile() и полной трассировкой стека он позволяет точно определить и залогировать ошибки. Для более широкого понимания выброса и перехвата исключений см. руководство по исключениям PHP.