來自:網易博客
就目前我的了解,在兩種情況下,PHP會報 Exception thrown without a stack frame in Unknown on line 0這種錯誤:
1)異常捕捉用了set_exception_handler導向,Exception裡面執行另一個Exception
如下面這段代碼,就會出現這種問題:
http://de.php.net/manual/de/function.set-exception-handler.php#88082
function error_handler($code, $message, $file, $line) { if (0 == error_reporting()) return; throw new ErrorException($message, 0, $code, $file, $line); } function exception_handler($e) { // ... normal exception stuff goes here print $undefined; // This is the underlying problem } set_error_handler("error_handler"); set_exception_handler("exception_handler"); throw new Exception("Just invoking the exception handler");
exception_handler函數內print $undefined;這行本身會拋出一個異常,而他又去調用set_exception_handler的exception_handler函數,死循環了。
解決辦法:不要在一個Exception裡面執行另一個Exception
上面的問題可以用try ... catch的方式,如exception_handler改成下面這樣:
function exception_handler($e) { try { // ... normal exception stuff goes here print $undefined; // This is the underlying problem } catch (Exception $e) { print get_class($e)." thrown within the exception handler. Message: ".$e->getMessage()." on line ".$e->getLine(); } }
2) 在析構函數拋出異常
參考這個bug:http://bugs.php.net/bug.php?id=33598
下面的代碼就會報這個錯誤:
class test { function __construct() { echo "Construct\n"; } function greet() { echo "Hello World\n"; } function __destruct() { echo "Destruct\n"; throw new Exception( 'test' ); } } $test = new test(); $test->greet();
目前的解決辦法:
1.不要在析構函數中拋出異常.
2.由於析構函數是在退出時執行的,所以要手動unset這種類,並catch該異常。
比如上面的例子,在最後加一行unset($test),這時程序就會報throw new Exception( 'test' ); 這行有錯誤,再catch這個異常就行了。
上面兩種情況在php 5.2.11版本上都會出現,至於原因我認為PHP可能就是這樣處理的,php bug 33598 2005年就報上去了,bug Status為Closed,說明官方並不認為這是一個bug,或不當一個bug處理了。
如果這個文件不是被另一個文件包含調用的話。。你可以試試下面的做法。
文件不要用 UTF-8 編碼。。
把你下面的代碼移到上面去。。反正你包含的 PHP 文件裡面也沒有 HTML 碼。
檢查你的 php.ini 注意 SESSION 臨時文件保存的路徑,是否可以被 PHP 訪問。
編碼不同,有的是utf-8,有的是Unicode,所以會出現為亂碼,插入數據庫的時候設置成utf-8,讀取出來也用utf-8就行了。