Створіть папку, якщо вона ще не існує


642

Я зіткнувся з кількома випадками, коли WordPress встановлює з Bluehost, де я стикався з помилками в моїй темі WordPress, оскільки папки завантажень wp-content/uploadsне було.

Мабуть, встановитель Bluehost cPanel WordPress не створює цю папку, хоча і HostGator .

Тому мені потрібно додати код до своєї теми, яка перевіряє папку та створює її інакше.


7
if (!file_exists('path/to/directory')) { mkdir('path/to/directory', 0777, true); }
Я найдурніша людина

Відповіді:


1227

Спробуйте це, використовуючи mkdir :

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

Зауважте, що 0777це вже режим за замовчуванням для каталогів і може все ще бути змінений поточним умаском.


11
Ви пропустили "рекурсивний" прапор - див. Відповідь Сатиша.
Франсуа Буржуа

118
is_dir () трохи швидше, ніж file_exists ()
pliashkou

43
@YuryPliashkou Так, можливо, але це не працює, якщо вже є файл з таким ім'ям.
Gumbo

4
питання тут: тож, якщо в шляху / до файлу буде файл з іменем "каталог", is_dir поверне справжнє, але file_exists поверне помилкове?
Ігор Л.

8
file_exists- Перевіряє, чи існує файл чи каталог is_file- Розповідає, чи є ім'ям файлу звичайний файл is_dir- Розповідає, чи є ім'ям файлу каталог
TarranJones

137

Ось відсутній шматок. Вам потрібно передавати прапор "рекурсивного" як третій аргумент (справжнє булеве значення) у виклику mkdir таким чином:

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

8
"рекурсивний" прапор є true
бульним

66

Щось трохи більш універсальне, оскільки це з'являється в 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;
}

Це піде шляхом, можливо, з довгим ланцюжком нестворених каталогів, і продовжуйте рухатися вгору по одному каталогу, поки він не потрапить у існуючий каталог. Потім він спробує створити наступний каталог у цьому каталозі та продовжить, поки не буде створено всі каталоги. Якщо він успішний, він повертає істину

Можна вдосконалити, забезпечивши рівень зупинки, тому він просто не працює, якщо виходить за межі користувацької папки чи чогось, а також включивши дозволи.


@phazei я отримую виклик до невизначеної функції через рядок $ return = createPath ($ prev_path);
Battousai

Дякую @phazei :)
Олексій

58

Як щодо такої функції помічника:

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

Він повернеться, trueякщо каталог було успішно створено або вже існує, і falseякщо каталог не вдалося створити.

Краще альтернатива цьому (не повинні давати ніяких попереджень):

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

4
Якщо ви виймете @та заміните його належним чином is_dir, мій підсумок є вашим :) Бонусні бали за перевірку того, чи є батьківський каталог is_writable()для непромокальної функції помічника.
Pekka

Використання @ для придушення помилок - це ефективність. Краще переконайтесь, що вона вже не існує, як Gumbo
Simon

1
Незалежно від придушення помилок, я схильний до -1 для першого прикладу. Друга настільки краще, що перша - безглузда.
Джастін Джонсон

Це важко читати код лише для того, щоб ставити його на 1 рядок. Прийнята відповідь набагато зрозуміліша.
MikeKulls

26

Швидший спосіб створення папки:

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

Це призведе до помилки, якщо на цьому шляху є файл з назвою 'каталог'.
Guney Ozsan

23

Рекурсивно створюйте шлях до каталогу:

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

Натхненний Python's os.makedirs()


11

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

6

Мені потрібно те ж саме для сайту для входу. Мені потрібно було створити каталог з двома змінними. Каталог $ - це основна папка, в якій я хотів створити іншу підпапку з номером ліцензії користувачів.

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

Це найсучасніше рішення без придушення помилок:

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

3

Якщо ви хочете уникнути проблеми з file_existsVS is_dir, я б запропонував вам подивитися тут

Я спробував це, і він створює лише каталог, якщо каталог не існує . Не байдуже, є файл з таким ім'ям.

/* 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
Помилка придушення? Чому?
канадський заступник

4
З придушенням помилок немає необхідності перевіряти існування каталогу
неоасцетичний

4
краще обробляти помилки, ніж придушувати їх. Якщо це не вдасться, ви ніколи не дізнаєтеся, чому саме з цього, і доведеться досліджувати це
Тім Огілві,

У високо одночасних / багатопотокових середовищах доцільно придушити помилку. Може статися умова перегону, в якій два або більше потоків оцінить is_dir () на false та спробує створити каталог. Перший потік зможе створити його без жодних проблем, але інші потоки не зможуть це зробити, оскільки каталог вже існує. Щоб не пропустити фактично невдале створення каталогу, слід знову перевірити існування каталогу після виклику на @mkdir ().
tobain

2

Ви також можете спробувати:

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

2

Створити папку, якщо вона ще не існує

Розглядаючи середовище питання.

  • WordPress.
  • Сервер веб-хостингу.
  • Припустимо, що його Linux не Windows працює з PHP.

І цитую з: http://php.net/manual/en/function.mkdir.php

bool mkdir (рядок $ pathname [, int $ mode = 0777 [, bool $ рекурсивний = FALSE [, ресурс $ контекст]]])

Посібник говорить, що єдиним необхідним параметром є $pathname!

Отже, ми можемо просто кодувати:

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

Пояснення:

Нам не потрібно передавати жоден параметр або перевіряти, чи існує папка або навіть параметр режиму, якщо це не потрібно; з наступних причин:

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

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

Тестовано на PHP7, Production Server, Linux



2

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

$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

Спочатку потрібно перевірити, чи існує каталог file_exists('path_to_directory')

Потім використовуйте mkdir(path_to_directory)для створення каталогу

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

Більше про mkdir () тут

Повний код тут:

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

0

Ось ви йдете.

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 (з інспекціями PHP) дає саме таку пропозицію ;-) btw. ви можете об'єднати зовнішнє, якщо з внутрішнім: if (! is_dir (...) &&! mkdir (...) &&! is_dir (...)) ...
aProgger

-1

Прийнята відповідь працює, але це не правильне рішення через дозволи. 0777 дозволи дозволяють усім отримувати доступ / читати / писати в каталог. Це не те, що ми хочемо для завантаження каталогу на веб-сервері. Ось запропоноване правильне та повне рішення.

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

0644 - це правильні дозволи для каталогу завантажень, оскільки ми зазвичай не хочемо, щоб завантажені на сервер там виконувалися.

true - третій параметр для встановлення рекурсивного властивості на true або false. Це дозволяє створювати вкладені каталоги, вказані в імені шляху.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.