web-dev-qa-db-ja.com

PHP unlink()例外処理

さて、unlink()関数を適切に処理できるかどうか疑問に思っていました。ファイルのリンクを解除できない場合、unlink()関数が厄介なエラーをスローすることは望ましくありません(Fileが見つからないことが原因の可能性があります)。

私は次のようなものを試しました

try { 
    unlink("secret/secret.txt"); 
} catch(Exception $e) { 
    print "whoops!"; 
    //or even leaving it empty so nothing is displayed
} 

しかし、それは機能していません。私はPHPの専門家ではありません。 Webのどこかでこの例外処理コードを検索して見つけました。しかし、私の学生時代を思い出すことができるように、同じことがJavaに使用されました。 SOうまくいったはずです。コードの何が問題なのかわかりません。

または、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)(生産および開発環境)で操作することで非表示にできますか?

22
prakashchhetri

unlinkは例外をスローせず、エラーを生成します。これを行う適切な方法は、unlinkを呼び出す前にファイルが存在することを確認することです。エラー出力がないことだけが心配な場合は、display_errorsをオフにしてください。これは、とにかく運用環境で常に実行する必要があります。その後、それらはログに記録されます。

@を使用してエラーを抑制しないでください。めったにお勧めできません。

@について詳しく説明してください

私はあなたが正確に何を意味するかわからない。しかし、ドキュメントは here です。なぜそれを使いたくないのかというと、それはコードが機能していないか問題があることを知らないからです。コードがまだ機能的な観点から機能する場合でも、問題が発生し、その問題により、他の何かが完全に機能しない可能性があります。エラーが発生しない場合は、おそらくデバッグに多くの時間を浪費することになります。

ログレベルを変更したり、エラーの表示を無効にしたりしても問題ありませんが、エラーを完全に抑制したいことはありません。

20
prodigitalson

エラーのみを抑制したい場合、これを行うことができます:

@unlink('your_file_name');

一般に、PHPでは、@はエラーを抑制します。

より良い方法は、エラー確率を最小化することです。エラーの可能性の1つは、存在しないファイルが原因であると言いました。私があなただったら、これをやる:

if(file_exists('your_file_name')){
    unlink('your_file_name');
}else{
    echo 'file not found';
}

幸運を :)

25
goFrendiAsgard

この方法は奇妙に思えるかもしれませんが、私はそれが最も確実な方法であると信じています

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_filefile_exists ではなくFILEが存在するかどうかを確認する正しい方法です。 file_exists ディレクトリとファイルの両方をチェックするため、同じファイル名を持つディレクトリに対してTRUEを返す場合があります。 nlink でディレクトリを削除することはできません。エラーをスローします。

nlink の前にファイルが存在することを確認する( is_file )ことは、ファイルを削除する正しい/最良の方法です。

if(is_file($file) && unlink($file)){

ただし、 is_file チェックと nlink の間の小さなウィンドウでファイルを削除するのが一般的であるため、絶対確実な方法ではありません。キャッシング方法がファイルシステムを使用するとき、私はこれを数回経験しました。

しかし、利用可能な最良の方法です。

だから、あなたはすべてを正しく行うことができ、それでもエラーが発生します!

まあ、少なくともエラーは失敗したかどうかを教えてくれます...実際には、エラーなしで失敗したかどうかを知ることができます

リンク解除

成功するとTRUEを返し、失敗するとFALSEを返します。

正しくコーディングし、成功と失敗を区別できる場合 nlink then YESはエラーを抑制します、それはあなたやあなたのコードに恩恵をもたらしません。

エラーが抑制されているかどうかにかかわらず、これは発生を防ぐために考えられる最良の方法です。チェックから削除までの時間を短縮することにより、エラーがスローされる可能性を減らすことができます。

編集:更新されたリンクURL

12
TarranJones

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 */ }
5
skrilled

私の経験では、file_exists()を呼び出す直前にnlink()を実行すると[〜#〜] not [〜#〜]が動作します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;
}

nlink()を呼び出すためだけに警告のエラー報告を無効にし、以前のerror_reporting()状態を復元します。

1
VCorrea

Try catchを使用して、例外としてunlink()による「リソース使用不可」エラーの処理

is_file()またはfile_exists()でもファイルが存在するかどうかを確認します。ファイルが削除を防止するアプリケーションによって使用されている可能性があり、unlink()が表示されます「リソースが利用できません」error

is_resource()is_writable()stream_get_meta_data()...などの多くのメソッドを試した後、エラーを処理する唯一の最良の方法に到達しました "deleting"not existsまたはis is are are used by some応用

function delete_file($pFilename)
{
    if ( file_exists($pFilename) ) { 
        //  Added by [email protected]
        //  '@' 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;
}

=== USAGE ===

try {
    if( delete_file('hello_world.xlsx') === true )
        echo 'File Deleted';
}
catch (Exception $e) {
    echo $e->getMessage(); // will print Exception message defined above.
}
1
Muhammad

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;
    }
0
maximark