Crea una cartella se non esiste già


641

Mi sono imbattuto in alcuni casi con installazioni di WordPress con Bluehost in cui ho riscontrato errori con il mio tema WordPress perché la cartella dei caricamenti wp-content/uploadsnon era presente.

Apparentemente il programma di installazione di Wordhost cPanel WordPress non crea questa cartella, anche se HostGator lo fa.

Quindi ho bisogno di aggiungere codice al mio tema che controlla la cartella e la crea diversamente.


7
if (!file_exists('path/to/directory')) { mkdir('path/to/directory', 0777, true); }
Sono la persona più stupida il

Risposte:


1228

Prova questo, usando mkdir :

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

Si noti che 0777è già la modalità predefinita per le directory e potrebbe essere ancora modificata dall'umask corrente.


11
Ti sei perso la bandiera "ricorsiva" - vedi la risposta di Satish.
Francois Bourgeois,

118
is_dir () è un po 'più veloce di file_exists ()
pliashkou

43
@YuryPliashkou Sì, forse, ma non funziona se c'è già un file con quel nome.
Gumbo,

4
domanda qui: quindi se ci fosse un file chiamato 'directory' nel percorso / to, is_dir restituirebbe true, ma file_exists restituirebbe false?
Igor L.,

8
file_exists- Verifica se esiste un file o una directory is_file- Indica se il nome file è un file normale is_dir- Indica se il nome file è una directory
TarranJones,

137

Ecco il pezzo mancante. Devi passare il flag 'ricorsivo' come terzo argomento (booleano true) nella chiamata mkdir in questo modo:

mkdir('path/to/directory', 0755, true);

8
la bandiera "ricorsiva" è il terzo argomento booleanotrue
ahnbizcad,

66

Qualcosa di un po 'più universale dal momento che questo si presenta su Google. Mentre i dettagli sono più specifici, il titolo di questa domanda è più universale.

/** 
 * 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;
}

Questo prenderà un percorso, possibilmente con una lunga catena di directory non create, e continuerà a salire di una directory fino a raggiungere una directory esistente. Quindi tenterà di creare la directory successiva in quella directory e continuerà fino a quando non verranno create tutte le directory. Restituisce vero se ha successo.

Potrebbe essere migliorato fornendo un livello di arresto in modo che fallisca se va oltre la cartella dell'utente o qualcosa del genere e includendo le autorizzazioni.


@phazei Ricevo una chiamata alla funzione indefinita a causa della linea $ return = createPath ($ prev_path);
Battousai,

Grazie @phazei :)
Alex

58

Che dire di una funzione di supporto come questa:

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

Restituirà truese la directory è stata creata correttamente o esiste già e falsese la directory non può essere creata.

Un'alternativa migliore è questa (non dovrebbe dare alcun avvertimento):

function makeDir($path)
{
     return is_dir($path) || mkdir($path);
}

4
Se lo rimuovi @e lo sostituisci con un is_dircontrollo adeguato , il mio voto è tuo :) Punti bonus per verificare se la directory principale is_writable()per una funzione di supporto a tenuta stagna.
Pekka,

L'uso di @ per eliminare gli errori è un hit prestazionale. Meglio verificare che non esista già come Gumbo
Simon,

1
Indipendentemente dalla soppressione degli errori, sono propenso a -1 per il primo esempio. Il secondo è molto meglio che il primo è inutile.
Justin Johnson,

Questo è difficile da leggere codice solo per il punto di metterlo su 1 riga. La risposta accettata è molto più chiara.
MikeKulls,

27

Modo più veloce per creare una cartella:

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

Ciò darebbe errore se ci fosse un file chiamato 'directory' in quel percorso.
Guney Ozsan,

23

Creare ricorsivamente il percorso della directory:

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

Ispirato da Python os.makedirs()


11

All'interno di WordPress c'è anche la funzione molto utile wp_mkdir_p che creerà ricorsivamente una struttura di directory.

Fonte di riferimento: -

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

6

Ho bisogno della stessa cosa per un sito di accesso. Avevo bisogno di creare una directory con due variabili. La directory $ è la cartella principale in cui volevo creare un'altra sottocartella con il numero di licenza dell'utente.

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

5

Questa è la soluzione più aggiornata senza soppressione degli errori:

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

3

Se vuoi evitare il problema file_existsVS is_dir, ti suggerisco di guardare qui

Ho provato questo e crea la directory solo se la directory non esiste . Non importa che esista un file con quel nome.

/* 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);
}

2
if (!is_dir('path_directory')) {
    @mkdir('path_directory');
}

3
Soppressione degli errori? Perché?
canadese concordato

4
Con la soppressione degli errori, non è necessario verificare l'esistenza della directory
neoascetico,

4
è meglio gestire gli errori piuttosto che eliminarli. Se fallisce, non saprai mai perché da questo, e dovrai ricercarlo
Tim Ogilvy,

In ambienti altamente concorrenti / multithread è consigliabile eliminare l'errore. Potrebbe verificarsi una race condition in cui due o più thread valuteranno is_dir () su false e proveranno a creare la directory. Il primo thread sarà in grado di crearlo senza alcun problema, ma gli altri thread non riusciranno a farlo, poiché la directory esiste già. Per evitare di perdere una creazione di directory effettivamente fallita, è necessario verificare nuovamente l'esistenza della directory dopo la chiamata a @mkdir ().
Tobain,

2

Puoi provare anche:

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

2

Per creare una cartella se non esiste già

Considerando l'ambiente della domanda.

  • WordPress.
  • Server di Webhosting.
  • Supponendo che Linux non sia Windows con PHP.

E citando da: http://php.net/manual/en/function.mkdir.php

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

Il manuale dice che l'unico parametro richiesto è il $pathname!

quindi, possiamo semplicemente codificare:

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

Spiegazione:

Non è necessario passare alcun parametro o verificare l'esistenza della cartella o addirittura passare il parametro mode a meno che non sia necessario; per i seguenti motivi:

  • Il comando creerà la cartella con l'autorizzazione 0755 (autorizzazione predefinita della cartella di hosting condiviso) o 0777 l'impostazione predefinita del comando.
  • modeviene ignorato sull'hosting Windows che esegue PHP .
  • Già il mkdir comando ha compilato in checker se esiste una cartella; quindi dobbiamo controllare solo il ritorno True | False; e non è un errore, è solo un avviso e Avviso è disabilitato nei server di hosting per impostazione predefinita.
  • In base alla velocità, questo è più veloce se l'avviso è disabilitato.

Questo è solo un altro modo per esaminare la domanda e non rivendicare una soluzione migliore o più ottimale.

Testato su PHP7, Production Server, Linux


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

2

Dovremmo sempre modulare il nostro codice e ho scritto lo stesso controllo sotto ... Prima controlliamo la directory, se la directory è assente creiamo la directory.

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

1

Devi prima controllare se esiste la directory file_exists('path_to_directory')

Quindi utilizzare mkdir(path_to_directory)per creare una directory

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

Maggiori informazioni su mkdir () qui

Codice completo qui:

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

0

Ecco qui.

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'));
    }
}

PHPStorm (con PHP Inspections) fornisce esattamente questo suggerimento ;-) tra l'altro. puoi unire l'esterno se nell'interno: if (! is_dir (...) &&! mkdir (...) &&! is_dir (...)) ...
aProgger

-1

La risposta accettata funziona ma non è la soluzione giusta a causa delle autorizzazioni. Le autorizzazioni 0777 consentono a tutti di accedere / leggere / scrivere alla directory. Questo non è ciò che vogliamo per la directory di upload nel web server. Ecco la soluzione corretta e completa suggerita.

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

0644 sono le autorizzazioni giuste per la directory dei caricamenti perché di solito non vogliamo che il caricamento sul server venga eseguito lì.

true è il terzo parametro per impostare la proprietà ricorsiva su true o false. Consente la creazione di directory nidificate specificate nel percorso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.