php - such - mkdir(): permission denied
Crea una carpeta si no existe (13)
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/uploads
no estaba presente.
Aparentemente, el instalador de Bluehost cPanel WP no crea esta carpeta, aunque HostGator sí.
Así que necesito agregar código a mi tema que comprueba la carpeta y la crea de otra manera.
Para crear una carpeta si no existe ya.
Teniendo en cuenta el entorno de la pregunta.
- WordPress.
- Servidor de alojamiento web.
- Suponiendo que su Linux no es Windows ejecutando PHP.
Y citando de: http://php.net/manual/en/function.mkdir.php
bool mkdir (string $ pathname [, int $ mode = 0777 [, bool $ recursive = FALSE [, resource $ context]]])
¡El manual dice que el único parámetro requerido es el $pathname
!
así, podemos simplemente 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 una 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.
-
mode
se ignora en Windows Hosting ejecutando PHP . - Ya el comando
mkdir
tiene un compilador incorporado si la carpeta existe; por lo que tenemos que comprobar la devolución sólo True | False; y no es un error, solo es una advertencia, y la Advertencia está desactivada 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, Production Server, Linux
¿Qué pasa con una función de ayuda como esta:
function makeDir($path)
{
$ret = mkdir($path); // use @mkdir if you want to suppress warnings/errors
return $ret === true || is_dir($path);
}
Devolverá true
si el directorio se creó correctamente o ya existe, y false
si no se pudo crear el directorio.
Una mejor alternativa es esta (no debería dar ninguna advertencia):
function makeDir($path)
{
return is_dir($path) || mkdir($path);
}
Algo un poco más universal ya que esto viene en google. Mientras que 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á un camino, posiblemente con una larga cadena de directorios no creados, y continuará subiendo un directorio hasta que llegue a un directorio existente. Luego intentará crear el siguiente directorio en ese directorio y continuará hasta que se creen todos los directorios. Devuelve true si tiene éxito.
Podría mejorarse al proporcionar un nivel de detención, por lo que simplemente falla si va más allá de la carpeta del usuario o algo así, e incluye permisos.
Aquí está la pieza que falta. Debe pasar el indicador ''recursivo'' como tercer argumento (verdadero booleano) en mkdir call así:
mkdir(''path/to/directory'', 0755, true);
Crear recursivamente la ruta del directorio:
function makedirs($dirpath, $mode=0777) {
return is_dir($dirpath) || mkdir($dirpath, $mode, true);
}
Inspirado por los os.makedirs()
de Python os.makedirs()
Dentro de WordPress también está la muy práctica función wp_mkdir_p que creará recursivamente una estructura de directorios.
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;
}
Esta es la solución más actualizada sin supresión de errores:
if (!is_dir(''path/to/directory'')) {
mkdir(''path/to/directory'');
}
Manera más rápida de crear carpeta:
if (!is_dir(''path/to/directory'')) {
mkdir(''path/to/directory'', 0777, true);
}
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 quise crear otra subcarpeta con el número de licencia del usuario.
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);
}
Prueba esto:
if (!file_exists(''path/to/directory'')) {
mkdir(''path/to/directory'', 0777, true);
}
Tenga en cuenta que 0777
ya es el modo predeterminado para los directorios y aún puede ser modificado por la umask actual.
Puedes probar también:
$dirpath = "path/to/dir";
$mode = "0777";
is_dir($dirpath) || mkdir($dirpath, $mode, true);
$upload = wp_upload_dir();
$upload_dir = $upload[''basedir''];
$upload_dir = $upload_dir . ''/newfolder'';
if (! is_dir($upload_dir)) {
mkdir( $upload_dir, 0700 );
}
if (!is_dir(''path_directory'')) {
@mkdir(''path_directory'');
}