Создать папку, если она еще не существует

542

Я столкнулся с несколькими случаями с установками WordPress с Bluehost, где я столкнулся с ошибками в моей теме WordPress, потому что папка upload wp-content/uploads отсутствовала.

По-видимому, установщик Bluehost cPanel WP не создает эту папку, хотя HostGator делает.

Поэтому мне нужно добавить код в свою тему, который проверяет папку и создает ее в противном случае.

  • 3
    if (!file_exists('path/to/directory')) { mkdir('path/to/directory', 0777, true); }
Теги:
directory

15 ответов

1007
Лучший ответ

Попробуйте следующее:

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

Обратите внимание, что 0777 уже является режимом по умолчанию для каталогов и все еще может быть изменен текущей umask.

  • 9
    Вы пропустили «рекурсивный» флаг - смотрите ответ Сатиша.
  • 99
    is_dir () немного быстрее, чем file_exists ()
Показать ещё 8 комментариев
121

Вот недостающая часть. Вы должны передать флаг "рекурсивный" в качестве третьего аргумента (логическое значение true) в mkdir, например:

mkdir('path/to/directory', 0755, true);
  • 6
    флаг 'recursive' является логическим 3-м аргументом true
57

Что-то более универсальное, поскольку это появляется в Google. Хотя детали более конкретны, название этого вопроса является более универсальным.

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

Это займет путь, возможно, с длинной цепочкой несозданных каталогов и продолжит идти вверх по одному каталогу, пока не попадет в существующий каталог. Затем он попытается создать следующий каталог в этом каталоге и продолжить, пока не создаст все каталоги. Он возвращает true, если успешно.

Может быть улучшено путем обеспечения уровня остановки, поэтому он просто терпит неудачу, если он выходит за пределы папки пользователя или что-то еще, и включив разрешения.

  • 0
    по какой-то причине этот код возвращает «страница не найдена», хотя другие ответы работают ...
  • 0
    @phazei Я получаю вызов неопределенной функции из-за строки $ return = createPath ($ prev_path);
Показать ещё 1 комментарий
53

Как насчет вспомогательной функции:

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

Он вернет true, если каталог был успешно создан или уже существует, и false, если каталог не удалось создать.

A лучше альтернатива - это (не следует давать никаких предупреждений):

function makeDir($path)
{
     return is_dir($path) || mkdir($path);
}
  • 4
    Если вы удалите @ и замените его правильной is_dir , мое повышение будет вашим :) Бонусные баллы за проверку, является ли родительский каталог is_writable() для водонепроницаемой вспомогательной функции.
  • 0
    Использование @ для подавления ошибок снижает производительность. Лучше проверить, что он еще не существует, как Гамбо
Показать ещё 3 комментария
22

Более быстрый способ создания папки:

if (!is_dir('path/to/directory')) {
    mkdir('path/to/directory', 0777, true);
}
  • 0
    Это даст ошибку, если по этому пути будет файл с именем «каталог».
21

Рекурсивно создать путь к каталогу:

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

Вдохновленный Python os.makedirs()

7

В WordPress также есть очень удобная функция wp_mkdir_p, которая будет рекурсивно создавать структуру каталогов.

Источник для справки: -

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

Мне нужно то же самое для сайта входа. Мне нужно было создать каталог с двумя переменными. Каталог $- это основная папка, в которой я хотел создать другую подпапку с номером лицензии пользователей.

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

Это самое современное решение без подавления ошибок:

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

Мы всегда должны модульно кодировать наш код, и я написал ту же самую проверку ниже. Сначала мы проверяем каталог, если каталог отсутствует, мы создаем каталог.

$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;
    }
}
0
$upload = wp_upload_dir();
$upload_dir = $upload['basedir'];
$upload_dir = $upload_dir . '/newfolder';
if (! is_dir($upload_dir)) {
   mkdir( $upload_dir, 0700 );
}
0

Создать папку, если она еще не существует

Учитывая вопрос среды.

  • WordPress.
  • Сервер веб-хостинга.
  • Предполагая, что его Linux не Windows под управлением PHP.

И цитирование: http://php.net/manual/en/function.mkdir.php

bool mkdir (строка $ pathname [, int $ mode = 0777 [, bool $ recursive = FALSE [, ресурс $ context]]])

Руководство говорит, что единственным обязательным параметром является $pathname !

Итак, мы можем просто кодировать:

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

Объяснение:

Нам не нужно передавать какой-либо параметр или проверять, существует ли папка, или даже передавать параметр mode, если это не требуется; по следующим причинам:

  • Команда создаст папку с разрешением 0755 (разрешение по умолчанию для папки общего хостинга) или 0777 по умолчанию для команды.
  • mode игнорируется на хостинге под управлением PHP.
  • Команда mkdir имеет встроенную проверку, если папка существует; поэтому нам нужно проверять возврат только True | False; и это не ошибка, это только предупреждение, и предупреждение отключено на хост-серверах по умолчанию.
  • Что касается скорости, это быстрее, если предупреждение отключено.

Это просто еще один способ разобраться в вопросе и не требовать лучшего или наиболее оптимального решения.

Протестировано на PHP7, Производственный сервер, Linux

0

Я закончил работу

//if(!is_dir($path) || !is_file($path) || !file_exists($path)){ // still erroring???
    try{
        mkdir($path);
    } catch (\ErrorException $e){

    }

после того, как прокомментированная часть не сработала

0

Вы также можете попробовать:

$dirpath = "path/to/dir";
$mode = "0777";
is_dir($dirpath) || mkdir($dirpath, $mode, true);
0
if (!is_dir('path_directory')) {
    @mkdir('path_directory');
}
  • 2
    Подавление ошибок? Зачем?
  • 3
    При подавлении ошибок нет необходимости проверять, существует ли каталог
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню