Crea una carpeta si aún no existe


641

Me he encontrado con algunos casos con las instalaciones de WordPress con Bluehost donde he encontrado errores con mi tema de WordPress porque la carpeta de cargas wp-content/uploadsno estaba presente.

Aparentemente, el instalador de Bluehost cPanel WordPress no crea esta carpeta, aunque HostGator sí.

Por lo tanto, necesito agregar código a mi tema que verifique la carpeta y la cree de otra manera.


77
if (!file_exists('path/to/directory')) { mkdir('path/to/directory', 0777, true); }
Soy la persona más estúpida

Respuestas:


1228

Prueba esto, usando mkdir :

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

Tenga en cuenta que 0777ya es el modo predeterminado para los directorios y aún puede ser modificado por la umask actual.


11
Te perdiste la bandera 'recursiva' - mira la respuesta de Satish.
Francois Bourgeois

118
is_dir () es un poco más rápido que file_exists ()
pliashkou

43
@YuryPliashkou Sí, tal vez, pero no funciona si ya hay un archivo con ese nombre.
Gumbo

44
pregunta aquí: entonces, si hubiera un archivo llamado 'directorio' en ruta / a, is_dir devolvería verdadero, pero file_exists devolvería falso?
Igor

8
file_exists- Comprueba si existe un archivo o directorio is_file- Indica si el nombre de archivo es un archivo normal is_dir- Indica si el nombre de archivo es un directorio
TarranJones

137

Aquí está la pieza que falta. Debe pasar el indicador 'recursivo' como tercer argumento (boolean true) en la llamada mkdir de esta manera:

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

8
la bandera 'recursiva' es el tercer argumento booleanotrue
ahnbizcad

66

Algo un poco más universal ya que esto aparece en google. Si bien los detalles son más específicos, el título de esta pregunta es más universal.

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

Esto tomará una ruta, posiblemente con una larga cadena de directorios no creados, y seguirá subiendo un directorio hasta que llegue a un directorio existente. Luego intentará crear el siguiente directorio en ese directorio y continuará hasta que haya creado todos los directorios. Devuelve verdadero si tiene éxito.

Podría mejorarse proporcionando un nivel de detención, por lo que simplemente falla si va más allá de la carpeta de usuario o algo así e incluye permisos.


@phazei Recibo una llamada a una función indefinida debido a la línea $ return = createPath ($ prev_path);
Battousai

Gracias @phazei :)
Alex

58

¿Qué pasa con una función auxiliar como esta:

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

Volverá truesi el directorio se creó correctamente o si ya existe, y falsesi el directorio no se pudo crear.

Una mejor alternativa es esta (no debería dar ninguna advertencia):

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

44
Si elimina el @y lo reemplaza por una is_dirverificación adecuada , mi voto es suyo :) Puntos de bonificación para verificar si el directorio principal is_writable()para una función auxiliar hermética.
Pekka

Usar @ para suprimir los errores es un golpe de rendimiento. Mejor comprobar que ya no existe como Gumbo
Simon

1
Independientemente de la supresión de errores, estoy inclinado a -1 para el primer ejemplo. El segundo es mucho mejor que el primero no tiene sentido.
Justin Johnson

Es difícil leer el código solo por el punto de ponerlo en 1 línea. La respuesta aceptada es mucho más clara.
MikeKulls

27

Forma más rápida de crear una carpeta:

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

Esto daría error si hay un archivo llamado 'directorio' en esa ruta.
Guney Ozsan

23

Crear recursivamente la ruta del directorio:

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

Inspirado por Python os.makedirs()


11

Dentro de WordPress también existe la función muy útil wp_mkdir_p que creará recursivamente una estructura de directorio.

Fuente de referencia: -

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

Necesito lo mismo para un sitio de inicio de sesión. Necesitaba crear un directorio con dos variables. El directorio $ es la carpeta principal donde quería crear otra subcarpeta con el número de licencia de los usuarios.

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

Esta es la solución más actualizada sin supresión de errores:

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

3

Si desea evitar el problema de file_existsVS is_dir, le sugiero que mire aquí

Intenté esto y solo crea el directorio si el directorio no existe . No le importa que haya un archivo con ese nombre.

/* 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
¿Supresión de error? ¿Por qué?
canadiancreed

44
Con la supresión de errores, no hay necesidad de verificar que ese directorio existe
neoascetic

44
Es mejor manejar los errores que suprimirlos. Si esto falla, nunca sabrá por qué y tendrá que investigarlo
Tim Ogilvy

En entornos altamente concurrentes / multiproceso, es recomendable suprimir el error. Puede ocurrir una condición de carrera en la que dos o más subprocesos evaluarán is_dir () como falso e intentarán crear el directorio. El primer hilo podrá crearlo sin ningún problema, pero los otros hilos no lo harán, porque el directorio ya existe. Para evitar perder una creación de directorio realmente fallida, debe verificar la existencia del directorio después de la llamada a @mkdir () nuevamente.
tobain

2

Puedes probar también:

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

2

Para crear una carpeta si aún no existe

Teniendo en cuenta el entorno de la pregunta.

  • WordPress
  • Servidor de alojamiento web.
  • Suponiendo que su Linux no Windows ejecute PHP.

Y citando: http://php.net/manual/en/function.mkdir.php

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

Manual dice que el único parámetro requerido es el $pathname!

entonces, simplemente podemos codificar:

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

Explicación:

No tenemos que pasar ningún parámetro o verificar si existe la carpeta o incluso pasar el parámetro del modo a menos que sea necesario; por las siguientes razones:

  • El comando creará la carpeta con el permiso 0755 (permiso predeterminado de la carpeta de alojamiento compartido) o 0777 el predeterminado del comando.
  • modese ignora en el Alojamiento de Windows que ejecuta PHP .
  • El mkdircomando ya tiene un checker incorporado si la carpeta existe; entonces necesitamos verificar el retorno solo True | False; y no es un error, es solo una advertencia, y la Advertencia está deshabilitada en los servidores de alojamiento de forma predeterminada.
  • Según la velocidad, esto es más rápido si la advertencia está deshabilitada.

Esta es solo otra forma de analizar la pregunta y no reclamar una solución mejor o más óptima.

Probado en PHP7, Servidor de producción, 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

Siempre debemos modularizar nuestro código y he escrito lo mismo, verifíquelo a continuación ... Primero verificamos el directorio, si el directorio está ausente creamos el directorio.

$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

Primero debe verificar si el directorio existe file_exists('path_to_directory')

Luego use mkdir(path_to_directory)para crear un directorio

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

Más acerca de mkdir () aquí

Código completo aquí:

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

0

Aqui tienes.

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 inspecciones PHP) da exactamente esta sugerencia ;-) por cierto. puedes fusionar lo externo if en lo interno: if (! is_dir (...) &&! mkdir (...) &&! is_dir (...)) ...
aProgger

-1

La respuesta aceptada funciona pero no es la solución correcta debido a los permisos. Los permisos 0777 permiten a todos acceder / leer / escribir en el directorio. Esto no es lo que queremos para cargar el directorio en el servidor web. Aquí está la solución correcta y completa sugerida.

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

0644 son los permisos correctos para el directorio de cargas porque generalmente no queremos que se carguen en el servidor.

verdadero es el tercer parámetro para establecer la propiedad recursiva en verdadero o falso. Permite la creación de directorios anidados especificados en la ruta.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.