[英]PHP unlink() handling the exception
好吧,我一直想知道我是否可以正確處理unlink()
function。 我不希望unlink()
function 如果無法取消鏈接文件(可能是由於找不到文件)拋出一些討厭的錯誤。
我嘗試了類似的東西
try {
unlink("secret/secret.txt");
} catch(Exception $e) {
print "whoops!";
//or even leaving it empty so nothing is displayed
}
但它不起作用。 我不是 PHP 方面的專家。 我在 web 的某處搜索並找到了這個異常處理代碼。 但我記得我的學生時代,Java 也是如此。 所以它應該工作。 我不知道代碼有什么問題。
或者我可以簡單地使用 if..else 語句,如
if(unlink($file)){
//leaving here empty must ensure that nothing is displayed
}else{
//leaving here empty must ensure that nothing is displayed
}
但是這段代碼也不起作用。 我在哪里做錯了? 還有什么其他方法可以正確處理它?
可以通過使用錯誤報告(PHP)(生產和開發環境)來隱藏錯誤嗎?
注意:這可能不再起作用。 見布賴恩的評論
如果你只想抑制錯誤,你可以這樣做:
@unlink('your_file_name');
通常,在 PHP 中,@ 會抑制任何錯誤。
更好的方法是最小化錯誤概率。 您已經說過錯誤可能性之一是由不存在的文件引起的。 如果我是你,我會這樣做:
if(file_exists('your_file_name')){
unlink('your_file_name');
}else{
echo 'file not found';
}
祝你好運 :)
unlink
不會拋出異常,會產生錯誤。 正確的方法是在嘗試調用unlink
之前檢查文件是否存在。 如果您只是擔心沒有錯誤輸出,那么您應該關閉display_errors
,無論如何您應該在生產環境中始終這樣做。 然后他們將被記錄。
不要用@
抑制錯誤,它很少是可取的。
你能更詳細地描述
@
我不確定你的意思是什么。 但是文檔在這里。 至於為什么你不想使用它......那是因為你永遠不知道代碼不起作用或有問題。 即使從功能的角度來看代碼仍然有效,它仍然存在問題,並且該問題可能會使其他某些東西在某些時候完全無法工作。 如果您從未遇到過錯誤,您可能會浪費大量時間進行調試。
更改日志級別或禁用錯誤顯示很好,但您永遠不想完全抑制它們。
這種方法可能看起來很奇怪,但我相信它是最萬無一失的方法,它說明了“競爭條件”。
is_file
if(is_file($file) && @unlink($file)){
// delete success
} else if (is_file ($file)) {
// unlink failed.
// you would have got an error if it wasn't suppressed
} else {
// file doesn't exist
}
為什么?
首先is_file是檢查 FILE 是否存在而不是file_exists的正確方法。 file_exists檢查目錄和文件,因此對於具有相同文件名的目錄,可能會返回TRUE
,您不能使用unlink刪除目錄,這樣做會引發錯誤。
在取消鏈接之前檢查文件是否存在( is_file )是刪除文件的正確/最佳方法。
if(is_file($file) && unlink($file)){
但這不是萬無一失的方法,因為在is_file check 和unlink之間的小窗口中刪除文件是很常見的。 當緩存方法使用文件系統時,我已經多次體驗過這種情況。
但這是最好的方法。
好吧,至少錯誤會告訴你它是否失敗......實際上你可以在沒有錯誤的情況下判斷它是否失敗
成功時返回
TRUE
,失敗時返回FALSE
。
如果您對它進行了正確編碼並且可以區分成功和失敗的取消鏈接,那么YES 會抑制錯誤,它不會使您或您的代碼受益。
無論錯誤是否被抑制,這是我能想到的防止它發生的最好方法。 通過減少檢查和刪除之間的時間,您將減少拋出錯誤的可能性。
編輯:更新的鏈接 URL
您可以使用is_writable
來測試您是否具有修改或刪除文件的適當權限。
http://php.net/manual/en/function.is-writable.php
try {
if(!is_writable($file))
throw new Exception('File not writable');
unlink($file);
}
catch(Exception $e) { /* do what you want */ }
我的經驗說,調用file_exists()只調用的unlink()之前不工作,即使clearstatcache()函數被調用只調用file_exists()之前。
PHP 版本和操作系統有多種組合,我發現始終有效的唯一方法(即避免在出現錯誤時顯示警告消息)是創建我自己的函數Silent_unlink() :
function silent_unlink( $filename )
{
$old_er = error_reporting();
error_reporting( $old_er & ~E_WARNING );
$result = unlink( $filename );
error_reporting( $old_er );
return $result;
}
它禁用僅用於調用unlink()的警告錯誤報告並恢復先前的error_reporting()狀態。
即使is_file()
或file_exists()
也會檢查文件是否存在,有可能文件正在被某些應用程序使用,這將阻止刪除,並且unlink()
將顯示“資源不可用”錯誤。
因此,在嘗試了許多方法后,例如: is_resource()
、 is_writable()
、 stream_get_meta_data()
...等,我達到了處理錯誤的唯一最佳方法,同時“刪除”了一個不存在或存在但被使用的文件一些應用
function delete_file($pFilename)
{
if ( file_exists($pFilename) ) {
// Added by muhammad.begawala@gmail.com
// '@' will stop displaying "Resource Unavailable" error because of file is open some where.
// 'unlink($pFilename) !== true' will check if file is deleted successfully.
// Throwing exception so that we can handle error easily instead of displaying to users.
if( @unlink($pFilename) !== true )
throw new Exception('Could not delete file: ' . $pFilename . ' Please close all applications that are using it.');
}
return true;
}
=== 用法 ===
try {
if( delete_file('hello_world.xlsx') === true )
echo 'File Deleted';
}
catch (Exception $e) {
echo $e->getMessage(); // will print Exception message defined above.
}
使用 PHP_Exceptionizer https://github.com/DmitryKoterov/php_exceptionizer/blob/master/lib/PHP/Exceptionizer.php
$exceptionizer = new PHP_Exceptionizer(E_ALL);
try {
unlink($file)
} catch (E_WARNING $e) {
return false;
}
if (file_exists($file) && is_writable($file)) {
return unlink($file);
}
據說錯誤抑制算子成本很高,它具有隱藏意外錯誤的潛在缺點,並且它解決的問題幾乎總是有更好的解決方案。
但是,在這種情況下,我們已經在進行重要的 I/O 操作(因此增加的處理時間可能不是什么大問題),我們正在調用一個單獨的內置 function (它限制了錯誤屏蔽問題)並且有沒有辦法阻止警告觸發。 如果我們能夠捕獲警告消息,也許我們有一個合法的@
用例:
$success = @unlink($path);
$errorInfo = error_get_last();
if ($success === false) {
$error = $errorInfo['message'] ?? 'unlink() failed';
throw new \RuntimeException("Failed to delete file {$path}: $error");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.