PHP Conference Japan 2024

Exception::getTraceAsString

(PHP 5, PHP 7, PHP 8)

Exception::getTraceAsString以字串形式取得堆疊追蹤

描述

final public Exception::getTraceAsString(): string

以字串形式回傳 Exception 堆疊追蹤。

參數

此函式沒有參數。

回傳值

以字串形式回傳 Exception 堆疊追蹤。

範例

範例 #1 Exception::getTraceAsString() 範例

<?php
function test() {
throw new
Exception;
}

try {
test();
} catch(
Exception $e) {
echo
$e->getTraceAsString();
}
?>

以上範例將會輸出類似以下的內容

#0 /home/bjori/tmp/ex.php(7): test()
#1 {main}

參見

新增註解

使用者貢獻的註解 2 註解

ernest at vogelsinger dot at
10 年前
老實說,Exception::getTraceAsString() 實在很糟糕,只列出被呼叫的方法(例如,在下面範例中,第 89 行呼叫了函式 fail2(),但沒有資訊說明呼叫者是 fail1())。事實上,在以下範例中,例外在第 78 行被拋出,這完全從追蹤中省略了,僅在例外中提供。也不支援鏈結例外。

範例
#0 /var/htdocs/websites/sbdevel/public/index.php(70): seabird\test\C->exc()
#1 /var/htdocs/websites/sbdevel/public/index.php(85): seabird\test\C->doexc()
#2 /var/htdocs/websites/sbdevel/public/index.php(89): seabird\test\fail2()
#3 /var/htdocs/websites/sbdevel/public/index.php(93): seabird\test\fail1()
#4 {main}

jTraceEx() 提供更像 Java 的堆疊追蹤,包含對鏈結例外的支援
Exception: 從類別 C 拋出
at seabird.test.C.exc(index.php:78)
at seabird.test.C.doexc(index.php:70)
at seabird.test.fail2(index.php:85)
at seabird.test.fail1(index.php:89)
at (main)(index.php:93)
Caused by: Exception: 從類別 B 拋出
at seabird.test.B.exc(index.php:64)
at seabird.test.C.exc(index.php:75)
... 還有 4 個
Caused by: Exception: 從類別 A 拋出
at seabird.test.A.exc(index.php:46)
at seabird.test.B.exc(index.php:61)
... 還有 5 個

(範例程式碼請見結尾)

<?php
/**
* jTraceEx() - 提供 Java 風格的例外追蹤
* @param $exception
* @param $seen - 傳遞給遞迴呼叫的陣列,用來累積已檢視過的追蹤行
* 呼叫此函式時,請保留為 NULL
* @return 字串陣列,每行追蹤為一個項目
*/
function jTraceEx($e, $seen=null) {
$starter = $seen ? '原因:' : '';
$result = array();
if (!
$seen) $seen = array();
$trace = $e->getTrace();
$prev = $e->getPrevious();
$result[] = sprintf('%s%s: %s', $starter, get_class($e), $e->getMessage());
$file = $e->getFile();
$line = $e->getLine();
while (
true) {
$current = "$file:$line";
if (
is_array($seen) && in_array($current, $seen)) {
$result[] = sprintf(' ... 還有 %d 個', count($trace)+1);
break;
}
$result[] = sprintf(' 在 %s%s%s(%s%s%s)',
count($trace) && array_key_exists('class', $trace[0]) ? str_replace('\\', '.', $trace[0]['class']) : '',
count($trace) && array_key_exists('class', $trace[0]) && array_key_exists('function', $trace[0]) ? '.' : '',
count($trace) && array_key_exists('function', $trace[0]) ? str_replace('\\', '.', $trace[0]['function']) : '(main)',
$line === null ? $file : basename($file),
$line === null ? '' : ':',
$line === null ? '' : $line);
if (
is_array($seen))
$seen[] = "$file:$line";
if (!
count($trace))
break;
$file = array_key_exists('file', $trace[0]) ? $trace[0]['file'] : 'Unknown Source';
$line = array_key_exists('file', $trace[0]) && array_key_exists('line', $trace[0]) && $trace[0]['line'] ? $trace[0]['line'] : null;
array_shift($trace);
}
$result = join("\n", $result);
if (
$prev)
$result .= "\n" . jTraceEx($prev, $seen);

return
$result;
}
?>

這裡是範例程式碼
<?php
class A {
public function
exc() {
throw new
\Exception('從類別 A 拋出'); // <-- 第 46 行
}
}

class
B {
public function
exc() {
try {
$a = new A;
$a->exc(); // <-- 第 61 行
}
catch(
\Exception $e1) {
throw new
\Exception('從類別 B 拋出', 0, $e1); // <-- 第 64 行
}
}
}
class
C {
public function
doexc() {
$this->exc(); // <-- 第 70 行
}
public function
exc() {
try {
$b = new B;
$b->exc(); // <-- 第 75 行
}
catch(
\Exception $e1) {
throw new
\Exception('從類別 C 拋出', 0, $e1); // <-- 第 78 行
}
}
}

function
fail2() {
$c = new C;
$c->doexc(); // <-- 第 85 行
}

function
fail1() {
fail2(); // <-- 第 89 行
}

try {
fail1(); // <-- 第 93 行
}
catch(
\Exception $e) {
echo
jTraceEx($e);
}
?>
cottton at i-stats dot net
9 年前
這個方法使用 \n 作為換行符號 (我預期是 PHP_EOL,但算了...)。
如果你想將字串記錄為單行,請使用類似以下的方法
<?php
$separator
= ', ';
$one_line = str_replace("\n", $separator, $e->getTraceAsString());
?>
To Top