web-dev-qa-db-fra.com

Comment vérifier si un répertoire existe? "is_dir", "file_exists" ou les deux?

Je veux créer un répertoire s'il n'existe pas déjà.

Est-ce qu'utiliser is_dir est suffisant pour cela?

if ( !is_dir( $dir ) ) {
    mkdir( $dir );       
}

Ou devrais-je combiner is_dir avec file_exists?

if ( !file_exists( $dir ) && !is_dir( $dir ) ) {
    mkdir( $dir );       
} 
298
Peter

Les deux renverraient true sur les systèmes Unix - sous Unix, tout est un fichier, répertoires compris. Mais pour vérifier si ce nom est pris, vous devriez vérifier les deux. Il pourrait y avoir un fichier normal nommé 'foo', ce qui vous empêcherait de créer un nom de répertoire 'foo'.

194
Marc B
$dirname = $_POST["search"];
$filename = "/folder/" . $dirname . "/";

if (!file_exists($filename)) {
    mkdir("folder/" . $dirname, 0777);
    echo "The directory $dirname was successfully created.";
    exit;
} else {
    echo "The directory $dirname exists.";
}
124
Maher

Je pense que realpath () peut être le meilleur moyen de valider si un chemin existe http://www.php.net/realpath

Voici un exemple de fonction:

<?php
/**
 * Checks if a folder exist and return canonicalized absolute pathname (long version)
 * @param string $folder the path being checked.
 * @return mixed returns the canonicalized absolute pathname on success otherwise FALSE is returned
 */
function folder_exist($folder)
{
    // Get canonicalized absolute pathname
    $path = realpath($folder);

    // If it exist, check if it's a directory
    if($path !== false AND is_dir($path))
    {
        // Return canonicalized absolute pathname
        return $path;
    }

    // Path/folder does not exist
    return false;
}

Version courte de la même fonction

<?php
/**
 * Checks if a folder exist and return canonicalized absolute pathname (sort version)
 * @param string $folder the path being checked.
 * @return mixed returns the canonicalized absolute pathname on success otherwise FALSE is returned
 */
function folder_exist($folder)
{
    // Get canonicalized absolute pathname
    $path = realpath($folder);

    // If it exist, check if it's a directory
    return ($path !== false AND is_dir($path)) ? $path : false;
}

Exemples de sortie

<?php
/** CASE 1 **/
$input = '/some/path/which/does/not/exist';
var_dump($input);               // string(31) "/some/path/which/does/not/exist"
$output = folder_exist($input);
var_dump($output);              // bool(false)

/** CASE 2 **/
$input = '/home';
var_dump($input);
$output = folder_exist($input);         // string(5) "/home"
var_dump($output);              // string(5) "/home"

/** CASE 3 **/
$input = '/home/..';
var_dump($input);               // string(8) "/home/.."
$output = folder_exist($input);
var_dump($output);              // string(1) "/"

Usage

<?php

$folder = '/foo/bar';

if(FALSE !== ($path = folder_exist($folder)))
{
    die('Folder ' . $path . ' already exist');
}

mkdir($folder);
// Continue do stuff
16
inckie

La deuxième variante de l'article en question n'est pas acceptable, car si vous avez déjà un fichier portant le même nom mais qu'il ne s'agit pas d'un répertoire, !file_exists($dir) renverra false, le dossier ne sera pas créé, donc l'erreur "failed to open stream: No such file or directory" se produira. Dans Windows, il existe une différence entre les types 'fichier' et 'dossier', vous devez donc utiliser file_exists() et is_dir() en même temps, par exemple:

if (file_exists('file')) {
    if (!is_dir('file')) { //if file is already present, but it's not a dir
        //do something with file - delete, rename, etc.
        unlink('file'); //for example
        mkdir('file', NEEDED_ACCESS_LEVEL);
    }
} else { //no file exists with this name
    mkdir('file', NEEDED_ACCESS_LEVEL);
}
7
Boolean_Type
$year = date("Y");   
$month = date("m");   
$filename = "../".$year;   
$filename2 = "../".$year."/".$month;

if(file_exists($filename)){
    if(file_exists($filename2)==false){
        mkdir($filename2,0777);
    }
}else{
    mkdir($filename,0777);
}
3
rons

ajouter true après 0777

<?php
    $dirname = "small";
    $filename = "upload/".$dirname."/";

    if (!is_dir($filename )) {
        mkdir("upload/" . $dirname, 0777, true);
        echo "The directory $dirname was successfully created.";
        exit;
    } else {
        echo "The directory $dirname exists.";
    }
     ?>
2
Sujeet Kumar
$save_folder = "some/path/" . date('dmy');

if (!file_exists($save_folder)) {
   mkdir($save_folder, 0777);
}
2
hour man

Au lieu de vérifier les deux, vous pouvez faire if(stream_resolve_include_path($folder)!==false). C'est plus lent mais tue deux oiseaux d'un coup.

Une autre option consiste simplement à ignorer le E_WARNING, et non en utilisant @mkdir(...); (car cela renverrait simplement tous les avertissements possibles, pas seul le répertoire existe déjà), mais en enregistrant un gestionnaire d’erreurs spécifique avant de le faire:

namespace com\stackoverflow;

set_error_handler(function($errno, $errm) { 
    if (strpos($errm,"exists") === false) throw new \Exception($errm); //or better: create your own FolderCreationException class
});
mkdir($folder);
/* possibly more mkdir instructions, which is when this becomes useful */
restore_error_handler();
1
Sebas