web-dev-qa-db-fra.com

PHP unlink () gérant l'exception

Eh bien, je me demandais si je pouvais gérer correctement la fonction unlink(). Je ne veux pas que la fonction unlink() génère une mauvaise erreur si elle ne parvient pas à dissocier le fichier (cela peut être dû au fichier introuvable).

J'ai essayé quelque chose comme

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

Mais ça ne fonctionne pas. Je ne suis pas un expert en PHP. J'ai cherché et trouvé ce code de traitement des exceptions quelque part sur le Web. Mais comme je me souviens de mes jours d’école, la même chose a été utilisée pour Java. SO cela aurait dû fonctionner. Je ne sais pas ce qui ne va pas avec le code.

Ou puis-je simplement utiliser une déclaration if..else comme

if(unlink($file)){
  //leaving here empty must ensure that nothing is displayed
}else{
  //leaving here empty must ensure that nothing is displayed
}

Mais ce code ne fonctionne pas non plus. Où est-ce que je fais l'erreur? Quels sont les autres moyens de le gérer correctement?

Les erreurs peuvent-elles être masquées en manipulant le rapport d'erreur (PHP) (environnement de production et de développement)?

19
prakashchhetri

unlink ne lève pas d'exceptions, génère des erreurs. Pour ce faire, vérifiez que le fichier existe avant d'essayer d'appeler unlink. Si vous êtes simplement inquiet de ne pas avoir le résultat des erreurs, désactivez simplement display_errors, ce que vous devriez toujours faire dans un environnement de production. Ensuite, ils seront simplement connectés.

Ne supprimez pas les erreurs avec le @, qui est rarement conseillé.

Pouvez-vous être plus descriptif sur @

Je ne suis pas sûr de ce que vous voulez dire exactement. Mais la documentation est ici . En ce qui concerne la raison pour laquelle vous ne voulez pas l'utiliser ... C'est parce que vous ne savez jamais que le code ne fonctionne pas ou est problématique. Même si le code fonctionne toujours d'un point de vue fonctionnel, il a toujours un problème et ce problème pourrait faire en sorte que quelque chose d'autre ne fonctionne plus du tout à un moment donné. Si vous n'avez jamais l'erreur, vous perdrez probablement beaucoup de temps à déboguer. 

Cela vous convient de changer votre niveau de journalisation ou de désactiver l'affichage des erreurs, mais vous ne voulez jamais les supprimer complètement.

18
prodigitalson

Si vous voulez seulement surpasser l'erreur, vous pouvez faire ceci:

@unlink('your_file_name');

Généralement, en php, @ supprimera toute erreur.

La meilleure façon est de minimiser la probabilité d'erreur. Vous avez dit que l'une des possibilités d'erreur est causée par un fichier inexistant. Si j'étais vous, je ferai ceci:

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

Bonne chance :)

22
goFrendiAsgard

Cette méthode peut sembler étrange mais je crois qu’elle est la plus infaillible

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
}

Pourquoi? 

Premièrement, is_file est la méthode correcte pour vérifier si un fichier existe déjà file_exists . file_exists recherche à la fois les répertoires et les fichiers, de sorte que la variable TRUE doit être retournée pour vous ne pouvez pas supprimer un répertoire avec unlink et cela provoquerait une erreur. 

Vérifier un fichier existe ( is_file ) avant que unlink soit le moyen correct/idéal pour supprimer un fichier. 

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

Mais ce n'est pas une méthode infaillible, car il est courant qu'un fichier soit supprimé dans la petite fenêtre entre le contrôle is_file et le unlink . J'ai expérimenté cela plusieurs fois lorsqu'une méthode de mise en cache utilise le système de fichiers.

Mais c'est la meilleure méthode disponible. 

Donc, vous pouvez tout faire correctement et toujours avoir une erreur!

Eh bien au moins l'erreur vous indique si elle échoue ... eh bien vous pouvez dire si elle échoue sans l'erreur 

unlink

Retourne TRUE en cas de succès ou FALSE en cas d'échec.

Si vous l'avez correctement codé et que vous pouvez faire la différence entre un succès et un échec unlink alors OUI supprimer l'erreur, cela ne vous avantage pas, ni votre code. 

Que l'erreur soit supprimée ou non, c'est la meilleure méthode à laquelle je puisse penser pour l'empêcher. En réduisant le délai entre la vérification et la suppression, vous réduirez les risques d'erreur. 

EDIT: URL de lien mises à jour

11
TarranJones

Vous pouvez utiliser is_writable pour vérifier si vous disposez des autorisations appropriées pour modifier ou supprimer un fichier.

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

Gestion de l'erreur "Resource Unavailable" par unlink () en tant qu'exception à l'aide de try catch

Même si is_file() ou file_exists() vérifie si le fichier existe ou non, il est probable que le fichier utilisé par certaines applications empêche la suppression et que unlink() affiche "Resource indisponible" error.

Donc, après avoir essayé plusieurs méthodes telles que: is_resource(), is_writable(), stream_get_meta_data()... etc., j'ai atteint le seul moyen de gérer les erreurs lorsque "supprimer" un fichier qui est n'existe pas ou existe mais utilisé par certaines applications

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

Utilisez 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

D'après mon expérience, appeler file_exists () juste avant d'appeler unlink () ne fonctionne pas ET PAS, même si clearstatcache () a été appelé juste avant d'appeler file_exists ( ).

Il existe de nombreuses combinaisons de versions PHP et de systèmes d’exploitation et la seule façon pour moi de toujours fonctionner (c’est-à-dire d’éviter d’afficher le message d’avertissement en cas d’erreur) consiste à créer ma propre fonction 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;
}

Il désactive le rapport d'erreur des avertissements juste pour appeler unlink () et restaure le statut précédent error_reporting ().

0
VCorrea