簡體   English   中英

使用 file_get_contents 進行良好的錯誤處理

[英]Good error handling with file_get_contents

我正在使用具有此功能的simplehtmldom

// get html dom form file
function file_get_html() {
    $dom = new simple_html_dom;
    $args = func_get_args();
    $dom->load(call_user_func_array('file_get_contents', $args), true);
    return $dom;
}

我像這樣使用它:

$html3 = file_get_html(urlencode(trim("$link")));

有時,一個 URL 可能無效,我想處理這個問題。 我以為我可以使用 try 和 catch ,但這沒有用,因為它沒有拋出異常,它只是給出了這樣的 php 警告:

[06-Aug-2010 19:59:42] PHP Warning:  file_get_contents(http://new.mysite.com/ghs 1/) [<a href='function.file-get-contents'>function.file-get-contents</a>]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found  in /home/example/public_html/other/simple_html_dom.php on line 39

第 39 行在上面的代碼中。

我如何正確處理這個錯誤,我可以只使用一個簡單的if條件,它看起來不像返回一個布爾值。

感謝大家的幫助

更新

這是一個很好的解決方案嗎?

if(fopen(urlencode(trim("$next_url")), 'r')){

    $html3 = file_get_html(urlencode(trim("$next_url")));

}else{
    //do other stuff, error_logging
    return false;

}

這是一個想法:

function fget_contents() {
    $args = func_get_args();
    // the @ can be removed if you lower error_reporting level
    $contents = @call_user_func_array('file_get_contents', $args);

    if ($contents === false) {
        throw new Exception('Failed to open ' . $file);
    } else {
        return $contents;
    }
}

基本上是file_get_contents的包裝器。 它會在失敗時拋出異常。 為避免覆蓋file_get_contents本身,您可以

// change this
$dom->load(call_user_func_array('file_get_contents', $args), true); 
// to
$dom->load(call_user_func_array('fget_contents', $args), true); 

現在你可以:

try {
    $html3 = file_get_html(trim("$link")); 
} catch (Exception $e) {
    // handle error here
}

錯誤抑制(通過使用@或通過降低 error_reporting 級別是一個有效的解決方案。這可能會引發異常,您可以使用它來處理您的錯誤file_get_contents可能產生警告的原因有很多,PHP 的手冊本身建議降低 error_reporting:參見手冊

使用CURL獲取 URL 並以這種方式處理錯誤響應。

curl_init() 的簡單示例:

<?php
// create a new cURL resource
$ch = curl_init();

// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch, CURLOPT_HEADER, 0);

// grab URL and pass it to the browser
curl_exec($ch);

// close cURL resource, and free up system resources
curl_close($ch);
?>

從我的觀點來看,良好的錯誤處理是 PHP 中的一大挑戰。 幸運的是,您可以注冊自己的錯誤處理程序並自行決定要做什么。

您可以像這樣定義一個相當簡單的錯誤處理程序:

function throwExceptionOnError(int $errorCode , string $errorMessage) {
    // Usually you would check if the error code is serious
    // enough (like E_WARNING or E_ERROR) to throw an exception
    throw new Exception($errorMessage);
}

並將其注冊到您的函數中,如下所示:

function file_get_html() {
    $dom = new simple_html_dom;
    $args = func_get_args();
    set_error_handler("throwExceptionOnError");
    $dom->load(call_user_func_array('file_get_contents', $args), true);
    restore_error_handler();
    return $dom;
}

要了解 file_get_contents 調用可能失敗的原因,您可以使用 php 的 error_get_last 函數:

if ($contents = file_get_contents($url)) {
    // it worked
}
else {
   die("Failed to fetch ".$url.", error: ".error_get_last()['message']);
}

如果您從外部 URL 獲取,最好的處理將來自引入 HTTP 庫(如 Zend_Http)。 這與使用 CURL 或 fopen 沒有太大區別,除了它將這些“驅動程序”的詳細信息提取到通用 API 中,然后您可以選擇要使用的。 它還會有一些內置的錯誤捕獲功能,讓您更輕松。

如果您不想要另一個庫的開銷,那么您顯然可以自己編寫代碼 - 在這種情況下,我總是更喜歡 CURL。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM