Buat folder jika belum ada

641

Saya mengalami beberapa kasus dengan pemasangan WordPress dengan Bluehost di mana saya mengalami kesalahan dengan tema WordPress saya karena folder unggahan wp-content/uploadstidak ada.

Tampaknya installer WordPress Bluehost cPanel tidak membuat folder ini, meskipun HostGator melakukannya.

Jadi saya perlu menambahkan kode ke tema saya yang memeriksa folder dan membuatnya sebaliknya.

Scott B
sumber
7
if (!file_exists('path/to/directory')) { mkdir('path/to/directory', 0777, true); }
Saya Orang yang Paling Bodoh

Jawaban:

1228

Coba ini, menggunakan mkdir :

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

Perhatikan bahwa 0777sudah merupakan mode default untuk direktori dan masih dapat dimodifikasi oleh umask saat ini.

Gumbo
sumber
11
Anda melewatkan bendera 'rekursif' - lihat jawaban Satish.
Francois Bourgeois
118
is_dir () sedikit lebih cepat, daripada file_exists ()
pliashkou
43
@YuryPliashkou Ya mungkin, tetapi tidak berfungsi jika sudah ada file dengan nama itu.
Gumbo
4
pertanyaan di sini: jadi jika akan ada file bernama 'direktori' di jalur / ke, is_dir akan mengembalikan true, tetapi file_exists akan mengembalikan false?
Igor L.
8
file_exists- Memeriksa apakah file atau direktori ada is_file- Memberitahu apakah nama file adalah file biasa is_dir- Memberitahu apakah nama file adalah direktori
TarranJones
137

Ini bagian yang hilang. Anda perlu memberikan flag 'rekursif' sebagai argumen ketiga (boolean true) di mkdir seperti ini:

mkdir('path/to/directory', 0755, true);
Satish Gadhave
sumber
8
bendera 'rekursif' menjadi argumen ke 3 booleantrue
ahnbizcad
66

Sesuatu yang lebih universal karena ini muncul di google. Meskipun detailnya lebih spesifik, judul pertanyaan ini lebih 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;
}

Ini akan mengambil jalur, mungkin dengan rantai panjang direktori yang tidak dibuat, dan terus naik satu direktori hingga sampai ke direktori yang ada. Kemudian akan mencoba untuk membuat direktori berikutnya di direktori itu, dan melanjutkan sampai itu membuat semua direktori. Mengembalikan nilai true jika berhasil.

Dapat ditingkatkan dengan memberikan level berhenti sehingga hanya gagal jika melampaui folder pengguna atau sesuatu dan dengan memasukkan izin.

phazei
sumber
@ phazei Saya mendapatkan panggilan ke fungsi tidak terdefinisi karena baris $ return = createPath ($ prev_path);
Battousai
Terima kasih @ phazei :)
Alex
58

Bagaimana dengan fungsi pembantu seperti ini:

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

Ini akan kembali truejika direktori berhasil dibuat atau sudah ada, dan falsejika direktori tidak dapat dibuat.

Alternatif yang lebih baik adalah ini (tidak boleh memberi peringatan):

function makeDir($path)
{
     return is_dir($path) || mkdir($path);
}
AndiDog
sumber
4
Jika Anda menghapus @dan menggantinya dengan is_dircek yang tepat , upvote saya adalah milik Anda :) Poin bonus untuk memeriksa apakah direktori induk is_writable()untuk fungsi pembantu kedap air.
Pekka
Menggunakan @ untuk menekan kesalahan adalah hit kinerja. Lebih baik untuk memeriksa itu belum ada seperti Gumbo
Simon
1
Terlepas dari penekanan kesalahan, saya cenderung -1 untuk contoh pertama. Yang kedua jauh lebih baik sehingga yang pertama tidak ada gunanya.
Justin Johnson
Ini sulit untuk membaca kode hanya untuk meletakkannya di 1 baris. Jawaban yang diterima jauh lebih jelas.
MikeKulls
27

Cara lebih cepat untuk membuat folder:

if (!is_dir('path/to/directory')) {
    mkdir('path/to/directory', 0777, true);
}
Elyor
sumber
Ini akan memberikan kesalahan jika ada file bernama 'direktori' di jalur itu.
Guney Ozsan
23

Secara rekursif membuat jalur direktori:

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

Terinspirasi oleh Python os.makedirs()

pengguna
sumber
11

Di dalam WordPress ada juga fungsi wp_mkdir_p yang sangat berguna yang secara rekursif akan membuat struktur direktori.

Sumber untuk referensi: -

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;
}
Trevor Mills
sumber
6

Saya memerlukan hal yang sama untuk situs masuk. Saya perlu membuat direktori dengan dua variabel. Direktori $ adalah folder utama tempat saya ingin membuat sub-folder lain dengan nomor lisensi pengguna.

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);
}
Progrower
sumber
5

Ini adalah solusi paling mutakhir tanpa penindasan kesalahan:

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

Jika Anda ingin menghindari masalah file_existsVS is_dir, saya sarankan Anda untuk melihat di sini

Saya mencoba ini dan itu hanya membuat direktori jika direktori tidak ada . Tidak peduli ada file dengan nama itu.

/* 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);
}
joaorodr84
sumber
2
if (!is_dir('path_directory')) {
    @mkdir('path_directory');
}
Mayur Kukadiya
sumber
3
Penindasan kesalahan? Mengapa?
canadiancreed
4
Dengan penindasan kesalahan, tidak perlu memeriksa bahwa direktori ada
neoascetic
4
lebih baik menangani kesalahan daripada menekannya. Jika ini gagal, Anda tidak akan pernah tahu mengapa dari ini, dan harus
merisetnya
Dalam lingkungan yang sangat konkuren / multithreaded, disarankan untuk menekan kesalahan. Kondisi ras mungkin terjadi di mana dua atau lebih utas akan mengevaluasi is_dir () menjadi false dan akan mencoba membuat direktori. Utas pertama akan dapat membuatnya tanpa masalah, tetapi utas lainnya akan gagal melakukannya, karena direktori sudah ada. Untuk menghindari kehilangan pembuatan direktori yang sebenarnya gagal, Anda harus memeriksa keberadaan direktori setelah panggilan ke @mkdir () lagi.
tobain
2

Anda juga dapat mencoba:

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

Untuk membuat folder jika belum ada

Mempertimbangkan lingkungan pertanyaan.

  • WordPress.
  • Server Webhosting.
  • Dengan asumsi Linux bukan Windows yang menjalankan PHP.

Dan mengutip dari: http://php.net/manual/en/function.mkdir.php

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

Manual mengatakan bahwa satu-satunya parameter yang diperlukan adalah $pathname!

jadi, Kita cukup kode:

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

Penjelasan:

Kami tidak harus melewati parameter apa pun atau memeriksa apakah folder ada atau bahkan melewati parameter mode kecuali diperlukan; karena alasan berikut:

  • Perintah akan membuat folder dengan izin 0755 (izin default folder shared hosting) atau 0777 standar perintah.
  • modediabaikan pada Windows Hosting yang menjalankan PHP .
  • Sudah ada mkdirperintah build in checker jika folder ada; jadi kita perlu memeriksa kembali hanya Benar | Salah; dan itu bukan kesalahan, itu hanya peringatan, dan Peringatan dinonaktifkan di server hosting secara default.
  • Sesuai kecepatan, ini lebih cepat jika peringatan dinonaktifkan.

Ini hanyalah cara lain untuk melihat pertanyaan dan tidak mengklaim solusi yang lebih baik atau paling optimal.

Diuji pada PHP7, Server Produksi, Linux

WPDev
sumber
2
$upload = wp_upload_dir();
$upload_dir = $upload['basedir'];
$upload_dir = $upload_dir . '/newfolder';
if (! is_dir($upload_dir)) {
   mkdir( $upload_dir, 0700 );
}
Nikunj Kathrotiya
sumber
2

Kita harus selalu memodernisasi kode kita dan saya telah menulis yang sama dengan memeriksanya di bawah ... Kita pertama-tama memeriksa direktori, jika direktori tidak ada, kita membuat direktori.

$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;
    }
}
Aditya
sumber
1

Pertama-tama Anda perlu memeriksa apakah direktori ada file_exists('path_to_directory')

Kemudian gunakan mkdir(path_to_directory)untuk membuat direktori

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

Lebih lanjut tentang mkdir () di sini

Kode lengkap di sini:

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

Ini dia

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'));
    }
}
ULIDU THEERAKE
sumber
PHPStorm (dengan Inspeksi PHP) memberikan persis saran ini ;-) btw. Anda dapat menggabungkan bagian luar jika ke bagian dalam: if (! is_dir (...) &&! mkdir (...) &&! is_dir (...)) ...
aProgger
-1

Jawaban yang diterima berfungsi tetapi itu bukan solusi yang tepat karena izin. 0777 izin memungkinkan semua orang untuk mengakses / membaca / menulis direktori. Ini bukan yang kita inginkan untuk direktori unggah di server web. Berikut ini adalah solusi yang tepat dan lengkap yang disarankan.

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

0644 adalah izin yang tepat untuk direktori unggahan karena kami biasanya tidak ingin unggah di server dieksekusi di sana.

true adalah parameter ketiga untuk menyetel properti rekursif ke true atau false. Ini memungkinkan pembuatan direktori bersarang yang ditentukan dalam pathname.

Umair Anwar
sumber