Tạo một thư mục nếu nó không tồn tại


641

Tôi đã gặp một vài trường hợp với cài đặt WordPress với Bluehost , nơi tôi đã gặp lỗi với chủ đề WordPress của mình vì thư mục tải lên wp-content/uploadskhông có.

Rõ ràng trình cài đặt Bluehost cPanel WordPress không tạo thư mục này, mặc dù HostGator có.

Vì vậy, tôi cần thêm mã vào chủ đề của mình để kiểm tra thư mục và tạo nó theo cách khác.


7
if (!file_exists('path/to/directory')) { mkdir('path/to/directory', 0777, true); }
Tôi là người ngu ngốc nhất

Câu trả lời:


1228

Hãy thử điều này, sử dụng mkdir :

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

Lưu ý rằng 0777đã là chế độ mặc định cho các thư mục và vẫn có thể được sửa đổi bằng ô hiện tại.


11
Bạn đã bỏ lỡ cờ 'đệ quy' - xem câu trả lời của Satish.
Francois Bourgeois

118
is_dir () nhanh hơn một chút so với file_exists ()
pliashkou

43
@YuryPliashkou Có thể, nhưng nó không hoạt động nếu đã có một tệp có tên đó.
Gumbo

4
câu hỏi ở đây: vì vậy nếu có một tệp có tên 'thư mục' trong đường dẫn / đến, is_dir sẽ trả về true, nhưng file_exists sẽ trả về false?
Igor L.

8
file_exists- Kiểm tra xem một tệp hoặc thư mục có tồn tại hay không is_file- Cho biết tên tệp có phải là tệp thông thường hay không is_dir- Cho biết tên tệp có phải là thư mục hay không
TarranJones

137

Đây là mảnh còn thiếu. Bạn cần chuyển cờ 'đệ quy' làm đối số thứ ba (boolean true) trong lệnh gọi mkdir như thế này:

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

8
cờ 'đệ quy' là đối số thứ 3 của booleantrue
ahnbizcad

66

Một cái gì đó phổ quát hơn một chút kể từ khi điều này xuất hiện trên google. Trong khi các chi tiết cụ thể hơn, tiêu đề của câu hỏi này là phổ quát hơn.

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

Điều này sẽ có một đường dẫn, có thể với một chuỗi dài các thư mục chưa được xử lý và tiếp tục đi lên một thư mục cho đến khi nó đến một thư mục hiện có. Sau đó, nó sẽ cố gắng tạo thư mục tiếp theo trong thư mục đó và tiếp tục cho đến khi nó tạo tất cả các thư mục. Nó trả về đúng nếu thành công.

Có thể được cải thiện bằng cách cung cấp một mức dừng để nó chỉ thất bại nếu nó vượt ra ngoài thư mục người dùng hoặc một cái gì đó và bằng cách bao gồm các quyền.


@phazei Tôi nhận được một cuộc gọi đến hàm không xác định do dòng $ return = createPath ($ trước_path);
Battousai

Cảm ơn @phazei :)
Alex

58

Điều gì về một chức năng của người trợ giúp như thế này:

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

Nó sẽ trở lại truenếu thư mục đã được tạo thành công hoặc đã tồn tại và falsenếu thư mục không thể được tạo.

Một cách khác tốt hơn là điều này (không nên đưa ra bất kỳ cảnh báo nào):

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

4
Nếu bạn loại bỏ @và thay thế nó bằng một is_dirkiểm tra thích hợp , upvote của tôi là của bạn :) Điểm thưởng để kiểm tra xem thư mục mẹ is_writable()cho chức năng trợ giúp kín nước.
Pekka

Sử dụng @ để loại bỏ các lỗi là một cú đánh hiệu suất. Tốt hơn để kiểm tra nó không tồn tại như Gumbo
Simon

1
Bất kể việc loại bỏ lỗi, tôi nghiêng về -1 cho ví dụ đầu tiên. Thứ hai là tốt hơn nhiều mà thứ nhất là vô nghĩa.
Justin Johnson

Điều này rất khó để đọc mã chỉ cho điểm đặt nó trên 1 dòng. Câu trả lời được chấp nhận rõ ràng hơn nhiều.
MikeKulls

27

Cách nhanh hơn để tạo thư mục:

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

Điều này sẽ gây ra lỗi nếu có một tệp có tên 'thư mục' tại đường dẫn đó.
Guney Ozsan

23

Đệ quy tạo đường dẫn thư mục:

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

Lấy cảm hứng từ Python os.makedirs()


11

Trong WordPress cũng có chức năng rất tiện dụng wp_mkdir_p sẽ tạo đệ quy một cấu trúc thư mục.

Nguồn để tham khảo: -

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

Tôi cần điều tương tự cho một trang web đăng nhập. Tôi cần phải tạo một thư mục có hai biến. Thư mục $ là thư mục chính nơi tôi muốn tạo một thư mục con khác với số giấy phép người dùng.

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

Đây là giải pháp cập nhật nhất mà không có lỗi:

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

3

Nếu bạn muốn tránh vấn đề file_existsVS is_dir, tôi khuyên bạn nên xem ở đây

Tôi đã thử điều này và nó chỉ tạo thư mục nếu thư mục không tồn tại . Nó không quan tâm nó có một tập tin với tên đó.

/* 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
Lỗi đàn áp? Tại sao?
canadiancreed

4
Với việc loại bỏ lỗi, không cần kiểm tra thư mục đó tồn tại
neoascetic

4
tốt hơn là xử lý lỗi hơn là triệt tiêu chúng. Nếu điều này thất bại, bạn sẽ không bao giờ biết tại sao từ điều này, và sẽ phải nghiên cứu nó
Tim Ogilvy

Trong các môi trường đồng thời / đa luồng rất cao, nên khắc phục lỗi. Một điều kiện cuộc đua có thể xảy ra trong đó hai hoặc nhiều luồng sẽ đánh giá is_dir () thành false và sẽ cố gắng tạo thư mục. Chuỗi đầu tiên sẽ có thể tạo ra nó mà không có bất kỳ vấn đề nào, nhưng các luồng khác sẽ không làm như vậy, vì thư mục đã tồn tại. Để tránh bỏ lỡ việc tạo thư mục thực sự thất bại, bạn nên kiểm tra sự tồn tại của thư mục sau khi gọi lại @mkdir ().
tobain

2

Bạn cũng có thể thử:

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

2

Để tạo một thư mục nếu nó không tồn tại

Xem xét môi trường của câu hỏi.

  • WordPress.
  • Máy chủ lưu trữ web.
  • Giả sử Linux của nó không chạy Windows.

Và trích dẫn từ: http://php.net/manual/en/feft.mkdir.php

bool mkdir (chuỗi $ pathname [, int $ mode = 0777 [, bool $ recursive = FALSE [, resource $ bối cảnh]]])

Hướng dẫn nói rằng tham số bắt buộc duy nhất là $pathname!

vì vậy, chúng ta có thể chỉ cần mã:

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

Giải trình:

Chúng tôi không phải vượt qua bất kỳ tham số nào hoặc kiểm tra xem thư mục có tồn tại hay thậm chí vượt qua tham số chế độ trừ khi cần thiết; vì những lý do sau đây:

  • Lệnh sẽ tạo thư mục với quyền 0755 (Quyền mặc định của thư mục lưu trữ được chia sẻ) hoặc 0777 mặc định của lệnh.
  • modebị bỏ qua trên Windows Hosting chạy PHP .
  • Đã có mkdirlệnh đã xây dựng trong trình kiểm tra nếu thư mục tồn tại; vì vậy chúng ta chỉ cần kiểm tra trả về Đúng | Sai; và nó không phải là một lỗi, nó chỉ là một cảnh báo và Cảnh báo bị tắt trong các máy chủ lưu trữ theo mặc định.
  • Theo tốc độ, điều này sẽ nhanh hơn nếu cảnh báo bị vô hiệu hóa.

Đây chỉ là một cách khác để xem xét câu hỏi và không yêu cầu một giải pháp tốt hơn hoặc tối ưu nhất.

Đã thử nghiệm trên PHP7, Máy chủ sản xuất, 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

Chúng ta nên luôn luôn mô đun hóa mã của mình và tôi đã viết cùng một kiểm tra bên dưới ... Trước tiên chúng ta kiểm tra thư mục, nếu thư mục vắng mặt, chúng ta tạo thư mục.

$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

Trước tiên bạn cần kiểm tra xem thư mục có tồn tại không file_exists('path_to_directory')

Sau đó sử dụng mkdir(path_to_directory)để tạo một thư mục

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

Tìm hiểu thêm về mkdir () tại đây

Mã đầy đủ ở đây:

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

0

Bạn đi đây

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 (với Kiểm tra PHP) đưa ra chính xác đề xuất này ;-) btw. bạn có thể hợp nhất bên ngoài nếu vào bên trong: if (! is_dir (...) &&! mkdir (...) &&! is_dir (...)) ...
aProgger

-1

Câu trả lời được chấp nhận hoạt động nhưng nó không phải là giải pháp phù hợp do các quyền. Quyền 0777 cho phép mọi người truy cập / đọc / ghi thư mục. Đây không phải là những gì chúng tôi muốn cho thư mục tải lên trong máy chủ web. Dưới đây là giải pháp chính xác và đầy đủ được đề xuất.

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

0644 là quyền phù hợp cho thư mục tải lên vì chúng tôi thường không muốn tải lên trên máy chủ để được thực thi ở đó.

true là tham số thứ ba để đặt thuộc tính đệ quy thành true hoặc false. Nó cho phép tạo các thư mục lồng nhau được chỉ định trong tên đường dẫn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.