Erstellen Sie einen Ordner, falls dieser noch nicht vorhanden ist

641

Bei WordPress-Installationen mit Bluehost sind einige Fälle aufgetreten, in denen Fehler bei meinem WordPress- Design aufgetreten sind, weil der Upload-Ordner wp-content/uploadsnicht vorhanden war.

Anscheinend erstellt das Bluehost cPanel WordPress-Installationsprogramm diesen Ordner nicht, HostGator jedoch.

Daher muss ich meinem Design Code hinzufügen, der nach dem Ordner sucht und ihn anderweitig erstellt.

Scott B.
quelle
7
if (!file_exists('path/to/directory')) { mkdir('path/to/directory', 0777, true); }
Ich bin die dümmste Person

Antworten:

1226

Versuchen Sie dies mit mkdir :

if (!file_exists('path/to/directory')) {
    mkdir('path/to/directory', 0777, true);
}

Beachten Sie, dass dies 0777bereits der Standardmodus für Verzeichnisse ist und möglicherweise noch von der aktuellen Umask geändert wird.

Gumbo
quelle
11
Sie haben die 'rekursive' Flagge verpasst - siehe Satishs Antwort.
Francois Bourgeois
118
is_dir () ist etwas schneller als file_exists ()
pliashkou
43
@YuryPliashkou Ja vielleicht, aber es funktioniert nicht, wenn es bereits eine Datei mit diesem Namen gibt.
Gumbo
4
Frage hier: Wenn es also eine Datei mit dem Namen 'Verzeichnis' in Pfad / zu geben würde, würde is_dir true zurückgeben, file_exists würde false zurückgeben?
Igor L.
8
file_exists- Überprüft, ob eine Datei oder ein Verzeichnis vorhanden ist. is_file- Gibt an, ob der Dateiname eine reguläre Datei is_dirist.
Gibt an,
137

Hier ist das fehlende Stück. Sie müssen das 'rekursive' Flag als drittes Argument (boolean true) im mkdir- Aufruf wie folgt übergeben :

mkdir('path/to/directory', 0755, true);
Satish Gadhave
quelle
8
Das 'rekursive' Flag ist das boolesche dritte Argumenttrue
ahnbizcad
66

Etwas universelleres, da dies bei Google auftaucht. Während die Details spezifischer sind, ist der Titel dieser Frage universeller.

/** 
 * recursively create a long directory path
 */
function createPath($path) {
    if (is_dir($path)) return true;
    $prev_path = substr($path, 0, strrpos($path, '/', -2) + 1 );
    $return = createPath($prev_path);
    return ($return && is_writable($prev_path)) ? mkdir($path) : false;
}

Dies nimmt einen Pfad, möglicherweise mit einer langen Kette nicht erstellter Verzeichnisse, und geht ein Verzeichnis hoch, bis es zu einem vorhandenen Verzeichnis gelangt. Anschließend wird versucht, das nächste Verzeichnis in diesem Verzeichnis zu erstellen, und es wird fortgefahren, bis alle Verzeichnisse erstellt wurden. Bei Erfolg wird true zurückgegeben.

Könnte verbessert werden, indem eine Stoppstufe bereitgestellt wird, die nur fehlschlägt, wenn sie über den Benutzerordner oder etwas anderes hinausgeht, und indem Berechtigungen eingeschlossen werden.

Phazei
quelle
@phazei Ich erhalte einen Aufruf der undefinierten Funktion aufgrund der Zeile $ return = createPath ($ prev_path);
Battousai
Danke @phazei :)
Alex
58

Was ist mit einer Hilfsfunktion wie dieser:

function makeDir($path)
{
     $ret = mkdir($path); // use @mkdir if you want to suppress warnings/errors
     return $ret === true || is_dir($path);
}

Es wird zurückgegeben, truewenn das Verzeichnis erfolgreich erstellt wurde oder bereits vorhanden ist und falsewenn das Verzeichnis nicht erstellt werden konnte.

Eine bessere Alternative ist dies (sollte keine Warnungen geben):

function makeDir($path)
{
     return is_dir($path) || mkdir($path);
}
AndiDog
quelle
4
Wenn Sie das entfernen @und durch eine ordnungsgemäße is_dirÜberprüfung ersetzen , liegt meine positive Bewertung bei Ihnen :) Bonuspunkte für die Überprüfung, ob das übergeordnete Verzeichnis is_writable()für eine wasserdichte Hilfsfunktion funktioniert.
Pekka
Die Verwendung von @ zur Unterdrückung der Fehler ist ein Leistungseinbruch. Besser zu überprüfen, ob es nicht schon existiert wie Gumbo
Simon
1
Unabhängig von der Fehlerunterdrückung neige ich für das erste Beispiel zu -1. Der zweite ist so viel besser, dass der erste sinnlos ist.
Justin Johnson
Es ist schwierig, Code zu lesen, nur um ihn in eine Zeile zu setzen. Die akzeptierte Antwort ist viel klarer.
MikeKulls
26

Schnellere Möglichkeit, einen Ordner zu erstellen:

if (!is_dir('path/to/directory')) {
    mkdir('path/to/directory', 0777, true);
}
Elyor
quelle
Dies würde zu einem Fehler führen, wenn sich unter diesem Pfad eine Datei mit dem Namen "Verzeichnis" befindet.
Guney Ozsan
23

Verzeichnispfad rekursiv erstellen:

function makedirs($dirpath, $mode=0777) {
    return is_dir($dirpath) || mkdir($dirpath, $mode, true);
}

Inspiriert von Pythons os.makedirs()

Benutzer
quelle
11

In WordPress gibt es auch die sehr praktische Funktion wp_mkdir_p, die rekursiv eine Verzeichnisstruktur erstellt.

Quelle als Referenz: -

function wp_mkdir_p( $target ) {
    $wrapper = null;

    // strip the protocol
    if( wp_is_stream( $target ) ) {
        list( $wrapper, $target ) = explode( '://', $target, 2 );
    }

    // from php.net/mkdir user contributed notes
    $target = str_replace( '//', '/', $target );

    // put the wrapper back on the target
    if( $wrapper !== null ) {
        $target = $wrapper . '://' . $target;
    }

    // safe mode fails with a trailing slash under certain PHP versions.
    $target = rtrim($target, '/'); // Use rtrim() instead of untrailingslashit to avoid formatting.php dependency.
    if ( empty($target) )
        $target = '/';

    if ( file_exists( $target ) )
        return @is_dir( $target );

    // We need to find the permissions of the parent folder that exists and inherit that.
    $target_parent = dirname( $target );
    while ( '.' != $target_parent && ! is_dir( $target_parent ) ) {
        $target_parent = dirname( $target_parent );
    }

    // Get the permission bits.
    if ( $stat = @stat( $target_parent ) ) {
        $dir_perms = $stat['mode'] & 0007777;
    } else {
        $dir_perms = 0777;
    }

    if ( @mkdir( $target, $dir_perms, true ) ) {

        // If a umask is set that modifies $dir_perms, we'll have to re-set the $dir_perms correctly with chmod()
        if ( $dir_perms != ( $dir_perms & ~umask() ) ) {
            $folder_parts = explode( '/', substr( $target, strlen( $target_parent ) + 1 ) );
            for ( $i = 1; $i <= count( $folder_parts ); $i++ ) {
                @chmod( $target_parent . '/' . implode( '/', array_slice( $folder_parts, 0, $i ) ), $dir_perms );
            }
        }

        return true;
    }

    return false;
}
Trevor Mills
quelle
6

Ich brauche das gleiche für eine Login-Site. Ich musste ein Verzeichnis mit zwei Variablen erstellen. Das Verzeichnis $ ist der Hauptordner, in dem ich einen weiteren Unterordner mit der Lizenznummer des Benutzers erstellen wollte.

include_once("../include/session.php");
$lnum = $session->lnum; //Users license number from sessions
$directory = uploaded_labels; // Name of directory that folder is being created in

if (!file_exists($directory."/".$lnum)) {
mkdir($directory."/".$lnum, 0777, true);
}
Progrower
quelle
5

Dies ist die aktuellste Lösung ohne Fehlerunterdrückung:

if (!is_dir('path/to/directory')) {
    mkdir('path/to/directory');
}
Andreas
quelle
3

Wenn Sie das file_existsVS- is_dirProblem vermeiden möchten , würde ich Ihnen empfehlen, hier nachzuschauen

Ich habe es versucht und es erstellt das Verzeichnis nur, wenn das Verzeichnis nicht existiert . Es ist egal, ob es eine Datei mit diesem Namen gibt.

/* Creates the directory if it does not exist */
$path_to_directory = 'path/to/directory';
if (!file_exists($path_to_directory) && !is_dir($path_to_directory)) {
    mkdir($path_to_directory, 0777, true);
}
joaorodr84
quelle
2
if (!is_dir('path_directory')) {
    @mkdir('path_directory');
}
Mayur Kukadiya
quelle
3
Fehlerunterdrückung? Warum?
Canadiancreed
4
Mit der
Fehlerunterdrückung muss
4
Es ist besser, mit Fehlern umzugehen, als sie zu unterdrücken. Wenn dies fehlschlägt, werden Sie nie wissen, warum dies so ist, und müssen es untersuchen
Tim Ogilvy
In Umgebungen mit hoher Gleichzeitigkeit / mehreren Threads ist es ratsam, den Fehler zu unterdrücken. Möglicherweise tritt eine Race-Bedingung auf, bei der zwei oder mehr Threads is_dir () als false auswerten und versuchen, das Verzeichnis zu erstellen. Der erste Thread kann es problemlos erstellen, die anderen Threads tun dies jedoch nicht, da das Verzeichnis bereits vorhanden ist. Um zu vermeiden, dass eine tatsächlich fehlgeschlagene Verzeichniserstellung verpasst wird, sollten Sie nach dem erneuten Aufruf von @mkdir () die Existenz des Verzeichnisses überprüfen.
Tobain
2

Sie können auch versuchen:

$dirpath = "path/to/dir";
$mode = "0777";
is_dir($dirpath) || mkdir($dirpath, $mode, true);
simhumileco
quelle
2

So erstellen Sie einen Ordner, falls dieser noch nicht vorhanden ist

Berücksichtigung der Umgebung der Frage.

  • WordPress.
  • Webhosting-Server.
  • Angenommen, Linux ist nicht Windows, auf dem PHP ausgeführt wird.

Und zitiert aus: http://php.net/manual/en/function.mkdir.php

bool mkdir (Zeichenfolge $ pathname [, int $ mode = 0777 [, bool $ recursive = FALSE [, resource $ context]]])

Das Handbuch besagt, dass der einzige erforderliche Parameter der $pathname!

Also können wir einfach codieren:

<?php
error_reporting(0); 
if(!mkdir('wp-content/uploads')){
   // todo
}
?>

Erläuterung:

Wir müssen keine Parameter übergeben oder prüfen, ob ein Ordner vorhanden ist, oder sogar Parameter für den Modus übergeben, sofern dies nicht erforderlich ist. aus den folgenden Gründen:

  • Der Befehl erstellt den Ordner mit der Berechtigung 0755 (Standardberechtigung des freigegebenen Hosting-Ordners) oder 0777 mit der Standardberechtigung des Befehls.
  • modewird auf Windows Hosting mit PHP ignoriert .
  • Der mkdirBefehl verfügt bereits über eine integrierte Überprüfung, wenn ein Ordner vorhanden ist. Wir müssen also nur die Rückgabe überprüfen. True | False; und es ist kein Fehler, es ist nur eine Warnung und die Warnung ist auf Hosting-Servern standardmäßig deaktiviert.
  • Je nach Geschwindigkeit ist dies schneller, wenn die Warnung deaktiviert ist.

Dies ist nur eine andere Möglichkeit, die Frage zu untersuchen und keine bessere oder optimalste Lösung zu beanspruchen.

Getestet auf PHP7, Production Server, Linux

WPDev
quelle
2
$upload = wp_upload_dir();
$upload_dir = $upload['basedir'];
$upload_dir = $upload_dir . '/newfolder';
if (! is_dir($upload_dir)) {
   mkdir( $upload_dir, 0700 );
}
Nikunj Kathrotiya
quelle
2

Wir sollten unseren Code immer modularisieren und ich habe das gleiche geschrieben. Überprüfen Sie es unten ... Wir überprüfen zuerst das Verzeichnis. Wenn das Verzeichnis nicht vorhanden ist, erstellen wir das Verzeichnis.

$boolDirPresents = $this->CheckDir($DirectoryName);

if (!$boolDirPresents) {
        $boolCreateDirectory = $this->CreateDirectory($DirectoryName);
        if ($boolCreateDirectory) {
        echo "Created successfully";
      }
  }

function CheckDir($DirName) {
    if (file_exists($DirName)) {
        echo "Dir Exists<br>";
        return true;
    } else {
        echo "Dir Not Absent<br>";
        return false;
    }
}

function CreateDirectory($DirName) {
    if (mkdir($DirName, 0777)) {
        return true;
    } else {
        return false;
    }
}
Aditya
quelle
1

Sie müssen zuerst überprüfen, ob ein Verzeichnis vorhanden ist file_exists('path_to_directory')

Verwenden Sie dann mkdir(path_to_directory), um ein Verzeichnis zu erstellen

mkdir( string $pathname [, int $mode = 0777 [, bool $recursive = FALSE [, resource $context ]]] ) : bool

Mehr über mkdir () hier

Vollständiger Code hier:

$structure = './depth1/depth2/depth3/';
if (!file_exists($structure)) {
    mkdir($structure);
}
Nasir Khan
quelle
0

Bitte schön.

if (!is_dir('path/to/directory')) {
    if (!mkdir('path/to/directory', 0777, true) && !is_dir('path/to/directory')) {
        throw new \RuntimeException(sprintf('Directory "%s" was not created', 'path/to/directory'));
    }
}
ULIDU THEERAKE
quelle
PHPStorm (mit PHP-Inspektionen) gibt genau diesen Vorschlag ;-) Übrigens. Sie können das äußere if in das innere zusammenführen: if (! is_dir (...) &&! mkdir (...) &&! is_dir (...)) ...
aProgger
-1

Die akzeptierte Antwort funktioniert, ist jedoch aufgrund der Berechtigungen nicht die richtige Lösung. Mit 0777-Berechtigungen kann jeder auf das Verzeichnis zugreifen / es lesen / schreiben. Dies ist nicht das, was wir für das Upload-Verzeichnis auf dem Webserver wollen. Hier ist die richtige und vollständige Lösung vorgeschlagen.

$path_to_directory = 'path/to/directory';
if (!file_exists($path_to_directory) && !is_dir($path_to_directory)) {
    mkdir($path_to_directory, 0644, true);
}

0644 sind die richtigen Berechtigungen für das Upload-Verzeichnis, da wir normalerweise nicht möchten, dass das Hochladen auf den Server dort ausgeführt wird.

true ist der dritte Parameter zum Setzen der rekursiven Eigenschaft auf true oder false. Es ermöglicht die Erstellung verschachtelter Verzeichnisse, die im Pfadnamen angegeben sind.

Umair Anwar
quelle