Créez un dossier s'il n'existe pas déjà


641

J'ai rencontré quelques cas avec des installations WordPress avec Bluehost où j'ai rencontré des erreurs avec mon thème WordPress parce que le dossier de téléchargement wp-content/uploadsn'était pas présent.

Apparemment, le programme d' installation de Bluehost cPanel WordPress ne crée pas ce dossier, bien que contrairement à HostGator .

J'ai donc besoin d'ajouter du code à mon thème qui vérifie le dossier et le crée autrement.


7
if (!file_exists('path/to/directory')) { mkdir('path/to/directory', 0777, true); }
Je suis la personne la plus stupide du

Réponses:


1228

Essayez ceci, en utilisant mkdir :

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

Notez que 0777c'est déjà le mode par défaut pour les répertoires et peut encore être modifié par l'umask actuel.


11
Vous avez manqué le drapeau «récursif» - voir la réponse de Satish.
Francois Bourgeois

118
is_dir () est un peu plus rapide que file_exists ()
pliashkou

43
@YuryPliashkou Ouais peut-être, mais ça ne marche pas s'il y a déjà un fichier avec ce nom.
Gumbo

4
question ici: donc s'il y avait un fichier nommé 'directory' dans path / to, is_dir retournerait vrai, mais file_exists retournerait faux?
Igor L.

8
file_exists- Vérifie si un fichier ou un répertoire existe is_file- Dit si le nom de fichier est un fichier normal is_dir- Dit si le nom de fichier est un répertoire
TarranJones

137

Voici la pièce manquante. Vous devez passer l'indicateur 'récursif' comme troisième argument (booléen true) dans l' appel mkdir comme ceci:

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

8
le drapeau 'récursif' étant le 3e argument booléentrue
ahnbizcad

66

Quelque chose d'un peu plus universel puisque cela arrive sur google. Bien que les détails soient plus précis, le titre de cette question est plus universel.

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

Cela prendra un chemin, éventuellement avec une longue chaîne de répertoires non créés, et continuera à remonter d'un répertoire jusqu'à ce qu'il atteigne un répertoire existant. Ensuite, il tentera de créer le répertoire suivant dans ce répertoire et continuera jusqu'à ce qu'il ait créé tous les répertoires. Il retourne vrai en cas de succès.

Pourrait être amélioré en fournissant un niveau d'arrêt afin qu'il échoue simplement s'il dépasse le dossier utilisateur ou quelque chose et en incluant des autorisations.


@phazei J'obtiens un appel à une fonction non définie à cause de la ligne $ return = createPath ($ prev_path);
Battousai

Merci @phazei :)
Alex

58

Qu'en est-il d'une fonction d'aide comme celle-ci:

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

Il retournera truesi le répertoire a été créé avec succès ou existe déjà, et falsesi le répertoire n'a pas pu être créé.

Une meilleure alternative est la suivante (ne devrait donner aucun avertissement):

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

4
Si vous supprimez @et remplacez-le par une is_dirvérification appropriée , mon vote positif est le vôtre :) Points bonus pour vérifier si le répertoire parent is_writable()pour une fonction d'aide étanche.
Pekka

L'utilisation de @ pour supprimer les erreurs est un problème de performances. Mieux vaut vérifier qu'il n'existe pas déjà comme Gumbo
Simon

1
Indépendamment de la suppression des erreurs, je suis enclin à -1 pour le premier exemple. Le second est tellement meilleur que le premier est inutile.
Justin Johnson

Il est difficile de lire le code au point de le mettre sur 1 ligne. La réponse acceptée est beaucoup plus claire.
MikeKulls

27

Un moyen plus rapide de créer un dossier:

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

Cela donnerait une erreur s'il y a un fichier nommé «répertoire» sur ce chemin.
Guney Ozsan

23

Créez récursivement le chemin du répertoire:

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

Inspiré par Python os.makedirs()


11

Dans WordPress, il y a aussi la fonction très pratique wp_mkdir_p qui créera récursivement une structure de répertoire.

Source de référence: -

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

J'ai besoin de la même chose pour un site de connexion. J'avais besoin de créer un répertoire avec deux variables. Le répertoire $ est le dossier principal où je voulais créer un autre sous-dossier avec le numéro de licence utilisateur.

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

Il s'agit de la solution la plus récente sans suppression d'erreur:

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

3

Si vous voulez éviter le problème file_existsVS is_dir, je vous suggère de regarder ici

J'ai essayé ceci et il crée seulement le répertoire si le répertoire n'existe pas . Il s'en fiche qu'il y ait un fichier avec ce nom.

/* 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
Suppression d'erreur? Pourquoi?
canadiancreed

4
Avec la suppression des erreurs, il n'est pas nécessaire de vérifier que le répertoire existe
neoascetic

4
il vaut mieux gérer les erreurs que de les supprimer. Si cela échoue, vous ne saurez jamais pourquoi de cela, et devrez le rechercher
Tim Ogilvy

Dans les environnements hautement simultanés / multithreads, il est conseillé de supprimer l'erreur. Une condition de concurrence critique peut se produire dans laquelle deux threads ou plus évalueront is_dir () à false et tenteront de créer le répertoire. Le premier thread pourra le créer sans aucun problème, mais les autres threads ne le feront pas, car le répertoire existe déjà. Pour éviter de manquer une création de répertoire qui a échoué, vous devez vérifier à nouveau l'existence du répertoire après l'appel à @mkdir ().
tobain

2

Vous pouvez également essayer:

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

2

Pour créer un dossier s'il n'existe pas déjà

Compte tenu de l'environnement de la question.

  • WordPress.
  • Serveur d'hébergement Web.
  • En supposant que son Linux n'est pas Windows exécutant PHP.

Et en citant: http://php.net/manual/en/function.mkdir.php

bool mkdir (chaîne $ chemin d'accès [, int $ mode = 0777 [, bool $ recursive = FALSE [, ressource $ context]]]))

Le manuel indique que le seul paramètre requis est le $pathname!

donc, nous pouvons simplement coder:

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

Explication:

Nous n'avons pas besoin de passer de paramètre ou de vérifier si le dossier existe ou même de passer le paramètre de mode sauf si nécessaire; Pour les raisons suivantes:

  • La commande crée le dossier avec l'autorisation 0755 (autorisation par défaut du dossier d'hébergement partagé) ou 0777 par défaut de la commande.
  • modeest ignoré sur l' hébergement Windows exécutant PHP .
  • Déjà la mkdircommande a construit dans le vérificateur si le dossier existe; nous devons donc vérifier le retour uniquement True | False; et ce n'est pas une erreur, c'est un avertissement uniquement, et l'avertissement est désactivé par défaut dans les serveurs d'hébergement.
  • Selon la vitesse, c'est plus rapide si l'avertissement est désactivé.

C'est juste une autre façon d'examiner la question et de ne pas prétendre à une solution meilleure ou la plus optimale.

Testé sur 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

Nous devons toujours modulariser notre code et j'ai écrit la même vérification ci-dessous ... Nous vérifions d'abord le répertoire, si le répertoire est absent, nous créons le répertoire.

$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

Vous devez d'abord vérifier si le répertoire existe file_exists('path_to_directory')

Ensuite, utilisez mkdir(path_to_directory)pour créer un répertoire

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

En savoir plus sur mkdir () ici

Code complet ici:

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

0

Voici.

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 (avec PHP Inspections) donne exactement cette suggestion ;-) btw. vous pouvez fusionner l'extérieur if dans l'intérieur: if (! is_dir (...) &&! mkdir (...) &&! is_dir (...)) ...
aProgger

-1

La réponse acceptée fonctionne mais ce n'est pas la bonne solution en raison des autorisations. Les autorisations 0777 permettent à chacun d'accéder / lire / écrire dans le répertoire. Ce n'est pas ce que nous voulons pour le téléchargement du répertoire sur le serveur Web. Voici la solution correcte et complète suggérée.

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

0644 sont les bonnes autorisations pour le répertoire de téléchargement car nous ne voulons généralement pas que le téléchargement sur le serveur y soit exécuté.

true est le troisième paramètre permettant de définir la propriété récursive sur true ou false. Il permet la création de répertoires imbriqués spécifiés dans le chemin d'accès.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.