搜尋
首頁後端開發php教程PHP5下的Error錯誤處理及問題定位的介紹(程式碼範例)

這篇文章帶給大家的內容是關於PHP5下的Error錯誤處理及問題定位的介紹(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

來說說當PHP出現E_ERROR等級致命的執行階段錯誤的問題定位方法。例如像Fatal error: Allowed memory size of記憶體溢出這種。當出現這種錯誤時會導致程式直接退出,PHP的error log中會記錄一條錯誤日誌說明報錯的具體檔案和程式碼行數,其它的任何資訊都沒有了。如果是PHP7的話還可以像捕獲異常一樣捕獲錯誤,PHP5的話就不行了。

一般想到的方法就是看看報錯的具體程式碼,如果報錯檔案是CommonReturn.class.php像下面這個樣子。

<?php /**
 * 公共返回封装
 * Class CommonReturn
 */
class CommonReturn
{

    /**
     * 打包函数
     * @param     $params
     * @param int $status
     *
     * @return mixed
     */
    static public function packData($params, $status = 0)
    {
        $res[&#39;status&#39;] = $status;
        $res[&#39;data&#39;] = json_encode($params);
        return $res;
    }

}

其中json_encode那一行報錯了,然後你查了下packData這個方法,有很多項目的類別中都有調用,這時要怎麼定位問題呢?

場景重現

好,首先我們是複現下場景。假如實際呼叫的程式bug.php如下

<?php require_once &#39;./CommonReturn.class.php&#39;;

$res = ini_set(&#39;memory_limit&#39;, &#39;1m&#39;);

$res = [];
$char = str_repeat(&#39;x&#39;, 999);
for ($i = 0; $i < 900 ; $i++) {
    $res[] = $char;
}

$get_pack = CommonReturn::packData($res);

// something else

運行bug.php PHP錯誤日誌中會記錄

[08-Jan-2019 11:22:52 Asia/Shanghai] PHP Fatal error:  Allowed memory size of 1048576 bytes exhausted (tried to allocate 525177 bytes) in /CommonReturn.class.php on line 20

復現成功,錯誤日誌中只是說明了報錯的檔案和哪行程式碼,無法知道程式的上下文堆疊訊息,不知道具體是哪塊業務邏輯呼叫的,這樣一來就無法定位修復錯誤。如果是偶爾出現,也沒有來自前端業務的回饋怎麼檢查呢。

解決想法

1、有人想到了修改memory_limit增加記憶體分配,但這種方法治標不治本。做開發肯定要找到問題的根源。

2、開啟core dump,如果產生code檔案可以進行偵錯,但發現code只有進程異常退出才會產生。像E_ERROR等級的錯誤不一定會產生code文件,記憶體溢出這種可能PHP內部自己就處理了。

3、使用register_shutdown_function註冊一個PHP終止時的回呼函數,再呼叫error_get_last如果獲取到了最後發生的錯誤,就透過debug_print_backtrace取得程式的堆疊訊息,我們試試看。

修改CommonReturn.class.php檔案如下

<?php /**
 * 公共返回封装
 * Class CommonReturn
 */
class CommonReturn
{

    /**
     * 打包函数
     * @param     $params
     * @param int $status
     *
     * @return mixed
     */
    static public function packData($params, $status = 0)
    {

        register_shutdown_function([&#39;CommonReturn&#39;, &#39;handleFatal&#39;]);

        $res[&#39;status&#39;] = $status;
        $res[&#39;data&#39;] = json_encode($params);
        return $res;
    }

    /**
     * 错误处理
     */
    static protected function handleFatal()
    {
        $err = error_get_last();
        if ($err[&#39;type&#39;]) {
            ob_start();
            debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5);
            $trace = ob_get_clean();
            $log_cont = &#39;time=%s&#39; . PHP_EOL . &#39;error_get_last:%s&#39; . PHP_EOL . &#39;trace:%s&#39; . PHP_EOL;
            @file_put_contents(&#39;/tmp/debug_&#39; . __FUNCTION__ . &#39;.log&#39;, sprintf($log_cont, date(&#39;Y-m-d H:i:s&#39;), var_export($err, 1), $trace), FILE_APPEND);
        }

    }

}

再次執行bug.php,日誌如下。

error_get_last:array (
  'type' => 1,
  'message' => 'Allowed memory size of 1048576 bytes exhausted (tried to allocate 525177 bytes)',
  'file' => '/CommonReturn.class.php',
  'line' => 23,
)
trace:#0  CommonReturn::handleFatal()

回溯訊息沒有來源,尷尬了。猜測因為backtrace資訊保存在記憶體中,當出現致命錯誤時會清空。沒辦法,把backtrace從外面傳進來試試。再次修改CommonReturn.class.php。

<?php /**
 * 公共返回封装
 * Class CommonReturn
 */
class CommonReturn
{

    /**
     * 打包函数
     * @param     $params
     * @param int $status
     *
     * @return mixed
     */
    static public function packData($params, $status = 0)
    {

        ob_start();
        debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5);
        $trace = ob_get_clean();
        register_shutdown_function([&#39;CommonReturn&#39;, &#39;handleFatal&#39;], $trace);

        $res[&#39;status&#39;] = $status;
        $res[&#39;data&#39;] = json_encode($params);
        return $res;
    }

    /**
     * 错误处理
     * @param $trace
     */
    static protected function handleFatal($trace)
    {
        $err = error_get_last();
        if ($err[&#39;type&#39;]) {
            $log_cont = &#39;time=%s&#39; . PHP_EOL . &#39;error_get_last:%s&#39; . PHP_EOL . &#39;trace:%s&#39; . PHP_EOL;
            @file_put_contents(&#39;/tmp/debug_&#39; . __FUNCTION__ . &#39;.log&#39;, sprintf($log_cont, date(&#39;Y-m-d H:i:s&#39;), var_export($err, 1), $trace), FILE_APPEND);
        }

    }

}

再次執行bug.php,日誌如下。

error_get_last:array (
  'type' => 1,
  'message' => 'Allowed memory size of 1048576 bytes exhausted (tried to allocate 525177 bytes)',
  'file' => '/CommonReturn.class.php',
  'line' => 26,
)
trace:#0  CommonReturn::packData() called at [/bug.php:13]

成功定位到了呼叫來源,在bug.php的13行。將最終的CommonReturn.class.php發佈到生產環境,再次出現錯誤時候看日誌就可以了。但是這樣的話所有呼叫packData的程式都會執行trace函數,一定也會影響效能的。

總結

  1. 對於其中使用到的register_shutdown_function函數需要注意,可以註冊多個不同的回調,但是如果某一個回呼函數中exit了,那麼後面註冊的回呼函數都不會執行。

  2. debug_print_backtrace這個取得回溯資訊函數第一個是否包含請求參數,第二個是回溯記錄層數,我們這裡是不回傳請求參數,可以節省些內存,而且如果請求參數巨大的話調這個函數可能就直接記憶體溢出了。

  1. 最好的方法就是升級PHP7,可以像例外一樣捕捉錯誤。


以上是PHP5下的Error錯誤處理及問題定位的介紹(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:segmentfault.。如有侵權,請聯絡admin@php.cn刪除
高流量網站的PHP性能調整高流量網站的PHP性能調整May 14, 2025 am 12:13 AM

TheSecretTokeEpingAphp-PowerEdwebSiterUnningSmoothlyShyunderHeavyLoadInVolvOLVOLVOLDEVERSALKEYSTRATICES:1)emplactopCodeCachingWithOpcachingWithOpCacheToreCescriptexecution Time,2)使用atabasequercachingCachingCachingWithRedataBasEndataBaseLeSendataBaseLoad,3)

PHP中的依賴注入:初學者的代碼示例PHP中的依賴注入:初學者的代碼示例May 14, 2025 am 12:08 AM

你應該關心DependencyInjection(DI),因為它能讓你的代碼更清晰、更易維護。 1)DI通過解耦類,使其更模塊化,2)提高了測試的便捷性和代碼的靈活性,3)使用DI容器可以管理複雜的依賴關係,但要注意性能影響和循環依賴問題,4)最佳實踐是依賴於抽象接口,實現鬆散耦合。

PHP性能:是否可以優化應用程序?PHP性能:是否可以優化應用程序?May 14, 2025 am 12:04 AM

是的,優化papplicationispossibleandessential.1)empartcachingingcachingusedapcutorediucedsatabaseload.2)優化的atabaseswithexing,高效Quereteries,and ConconnectionPooling.3)EnhanceCodeWithBuilt-unctions,避免使用,避免使用ingglobalalairaiables,並避免使用

PHP性能優化:最終指南PHP性能優化:最終指南May 14, 2025 am 12:02 AM

theKeyStrategiestosigantificallyBoostPhpaPplicationPerformenCeare:1)UseOpCodeCachingLikeLikeLikeLikeLikeCacheToreDuceExecutiontime,2)優化AtabaseInteractionswithPreparedStateTementStatementStatementAndProperIndexing,3)配置

PHP依賴注入容器:快速啟動PHP依賴注入容器:快速啟動May 13, 2025 am 12:11 AM

aphpdepentioncontiveContainerIsatoolThatManagesClassDeptions,增強codemodocultion,可驗證性和Maintainability.itactsasaceCentralHubForeatingingIndections,因此reducingTightCightTightCoupOulplingIndeSingantInting。

PHP中的依賴注入與服務定位器PHP中的依賴注入與服務定位器May 13, 2025 am 12:10 AM

選擇DependencyInjection(DI)用於大型應用,ServiceLocator適合小型項目或原型。 1)DI通過構造函數注入依賴,提高代碼的測試性和模塊化。 2)ServiceLocator通過中心註冊獲取服務,方便但可能導致代碼耦合度增加。

PHP性能優化策略。PHP性能優化策略。May 13, 2025 am 12:06 AM

phpapplicationscanbeoptimizedForsPeedAndeffificeby:1)啟用cacheInphp.ini,2)使用preparedStatatementSwithPdoforDatabasequesies,3)3)替換loopswitharray_filtaray_filteraray_maparray_mapfordataprocrocessing,4)conformentnginxasaseproxy,5)

PHP電子郵件驗證:確保正確發送電子郵件PHP電子郵件驗證:確保正確發送電子郵件May 13, 2025 am 12:06 AM

phpemailvalidation invoLvesthreesteps:1)格式化進行regulareXpressecthemailFormat; 2)dnsvalidationtoshethedomainhasavalidmxrecord; 3)

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!