Wie überprüfe ich, ob ein Verzeichnis vorhanden ist? "Is_dir", "file_exists" oder beides?

329

Ich möchte ein Verzeichnis erstellen, wenn es noch nicht existiert.

Ist is_dirgenug für diesen Zweck zu verwenden?

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

Oder sollte ich kombinieren is_dirmit file_exists?

if ( !file_exists( $dir ) && !is_dir( $dir ) ) {
    mkdir( $dir );       
} 
Peter
quelle
3
Der boolesche Operator OR sollte AND sein, und in PHP wird er als &&
Ivo Renkema
15
@IvoRenkema PHP unterstützt auch or/ andneben ||/ &&.
Camilo Martin
1
Der Operator &&ist hier nicht sinnvoll, denn wenn die Datei nicht vorhanden ist ( !file_exists($dir) == true), handelt es sich sicher nicht um ein Verzeichnis. Und wenn eine Datei vorhanden ist, !is_dir($dir)wird diese nicht überprüft, da !file_exists($dir)sie zurückkehrt falseund der &&Bediener kurzgeschlossen ist .
Boolean_Type
4
Meiner Ansicht nach sollte der Operator OR sein.
Mojtaba
mit && funktioniert das perfekt für mich
FABBRj

Antworten:

220

Beide würden auf Unix-Systemen true zurückgeben - unter Unix ist alles eine Datei, einschließlich Verzeichnisse. Um zu testen, ob dieser Name verwendet wird, sollten Sie beide überprüfen. Möglicherweise gibt es eine reguläre Datei mit dem Namen "foo", die Sie daran hindert, einen Verzeichnisnamen "foo" zu erstellen.

Marc B.
quelle
37
Vergessen Sie nicht zu überprüfen, ob is_writable auch
Drewdin
10
@Drewdin Sie möchten die Eltern überprüfen, is_writablenicht wahr ?
Matthew Scharley
133
$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.";
}
Maher
quelle
46
Sehr viel, was das Echo sagt ...
Kay - SE ist böse
13
wenn man bedenkt, dass es Post-Input nimmt und es so verwendet, wie es ist, plus macht 0777 dir, wahrscheinlich gar nicht so sicher; P
immer
2
Im Ernst, $ dirname könnte bereinigt und die Berechtigung auf 0755 gesetzt werden. Fügen Sie dazu einige .htaccess-Anweisungen hinzu. Es gibt einige weitere Empfehlungen bei OWASP: owasp.org
James P.
# The following directives force the content-type application/octet-stream # and force browsers to display a download dialog for non-image files. # This prevents the execution of script files in the context of the website: #ForceType application/octet-stream Header set Content-Disposition attachment <FilesMatch "(?i)\.(gif|jpe?g|png)$"> ForceType none Header unset Content-Disposition </FilesMatch> # The following directive prevents browsers from MIME-sniffing the content-type. # This is an important complement to the ForceType directive above: Header set X-Content-Type-Options nosniff
James P.
7
Wenn Sie verwenden mkdir- warum haben Sie nicht einfach '$ filename' übergeben?
Howdy_McGee
17

Ich denke, realpath () ist möglicherweise der beste Weg, um zu überprüfen, ob ein Pfad vorhanden ist. Http://www.php.net/realpath

Hier ist eine Beispielfunktion:

<?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;
}

Kurzversion der gleichen Funktion

<?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;
}

Ausgabebeispiele

<?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) "/"

Verwendungszweck

<?php

$folder = '/foo/bar';

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

mkdir($folder);
// Continue do stuff
inckie
quelle
2
Für jeden, der darauf stößt, glaube ich, dass realpath Ordner zwischenspeichert, wenn es ausgeführt wird. Wenn es also einmal ausgeführt wird, wird der Ordner danach entfernt, und es wird möglicherweise nicht false zurückgegeben, wenn es erneut ausgeführt wird.
Jase
2
aber auch file_exists
Sebas
7

Die zweite Variante im fraglichen Beitrag ist nicht in Ordnung, denn wenn Sie bereits eine Datei mit demselben Namen haben, es sich jedoch nicht um ein Verzeichnis handelt, !file_exists($dir)wird zurückgegeben false, der Ordner wird nicht erstellt, sodass ein Fehler "failed to open stream: No such file or directory"auftritt. In Windows gibt es einen Unterschied zwischen ‚Datei‘ und ‚Ordner‘ Typen, so verwenden müssen, file_exists()und is_dir()zur gleichen Zeit, für ex .:

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);
}
Boolean_Type
quelle
3
$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);
}
rons
quelle
1
Sie können den vollständigen Pfad überprüfen und ihn, falls er nicht vorhanden ist, mit rekursivem mkdir erstellen: if (! File_exists ($ filename2)) {mkdir ($ filename2, 0777, true); } Außerdem wird Ihr Code niemals den vollständigen Pfad erstellen, wenn $ filename nicht existiert ...
Niels R.
3
$save_folder = "some/path/" . date('dmy');

if (!file_exists($save_folder)) {
   mkdir($save_folder, 0777);
}
Stunde Mann
quelle
3
Das Einstellen von chmod 777 ist niemals eine gute Idee. 755 ist ausreichend für Ordner.
Oldskool
2

addiere true nach 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.";
    }
     ?>
Sujeet Kumar
quelle
1

Anstatt beides zu überprüfen, könnten Sie es tun if(stream_resolve_include_path($folder)!==false). Es ist langsamer , tötet aber zwei Fliegen auf einmal.

Eine andere Möglichkeit besteht darin, das einfach zu ignorieren E_WARNING, nicht indem Sie es verwenden @mkdir(...);(da dies einfach auf alle möglichen Warnungen verzichten würde, nicht nur das bereits vorhandene Verzeichnis), sondern indem Sie einen bestimmten Fehlerbehandler registrieren, bevor Sie dies tun:

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();
Sebas
quelle
1

Dies ist eine alte, aber immer noch aktuelle Frage. Nur Test mit der is_dir()oder file_exists()Funktion für das Vorhandensein von der .oder ..Datei im Verzeichnis unter Test. Jedes Verzeichnis muss folgende Dateien enthalten:

is_dir("path_to_directory/.");    
djordje
quelle
0

So mache ich das

if(is_dir("./folder/test"))
{
  echo "Exist";
}else{
  echo "Not exist";
}
Jetro Bernardo
quelle
Wenn Sie eine alte Frage beantworten, ist Ihre Antwort für andere StackOverflow-Benutzer viel nützlicher, wenn Sie einen Kontext angeben, um zu erklären, wie Ihre Antwort hilft, insbesondere für eine Frage, für die bereits eine Antwort akzeptiert wurde. Siehe auch : Wie kann ich eine gute Antwort schreiben .
David Buck
0

Es gibt folgende Möglichkeiten, um zu überprüfen, ob ein Pfad ein Verzeichnis ist:

function isDirectory($path) {
    $all = @scandir($path);
    return $all !== false;
}

HINWEIS: Es wird auch für nicht vorhandene Pfade false zurückgegeben, funktioniert jedoch perfekt unter UNIX / Windows

Máxima Alekz
quelle