Làm thế nào để tôi kiểm tra nếu một thư mục tồn tại? Tiếng is_dir, tập tin_xác tập tin hay cả hai?


329

Tôi muốn tạo một thư mục nếu nó chưa tồn tại.

Là sử dụng is_dirđủ cho mục đích đó?

if ( !is_dir( $dir ) ) {
    mkdir( $dir );       
}

Hay tôi nên kết hợp is_dirvới file_exists?

if ( !file_exists( $dir ) && !is_dir( $dir ) ) {
    mkdir( $dir );       
} 

3
Toán tử boolean HOẶC phải là AND và trong PHP, nó được viết là &&
Ivo Renkema

15
@IvoRenkema PHP cũng hỗ trợ or/ andbên cạnh ||/ &&.
Camilo Martin

1
Toán tử &&không đáng tin ở đây, bởi vì, nếu tệp không tồn tại ( !file_exists($dir) == true), chắc chắn nó không phải là một thư mục. Và nếu tập tin tồn tại, !is_dir($dir)sẽ không được kiểm tra, bởi vì !file_exists($dir)sẽ trả về false&&toán tử bị đoản mạch .
Boolean_Type 8/03/2016

4
Theo quan điểm của tôi, toán tử nên OR.
Mojtaba

với && điều này hoạt động hoàn hảo với tôi
FABBRj

Câu trả lời:


220

Cả hai sẽ trả về đúng trên các hệ thống Unix - trong Unix mọi thứ đều là một tệp, bao gồm các thư mục. Nhưng để kiểm tra nếu tên đó được thực hiện, bạn nên kiểm tra cả hai. Có thể có một tệp thông thường có tên 'foo', điều này sẽ ngăn bạn tạo tên thư mục 'foo'.


37
đừng quên kiểm tra nếu is_writable cũng được
Drewdin

10
@Drewdin bạn muốn kiểm tra phụ huynh is_writablephải không?
Matthew Scharley

133
$dirname = $_POST["search"];
$filename = "/folder/" . $dirname . "/";

if (!file_exists($filename)) {
    mkdir("folder/" . $dirname, 0777);
    echo "The directory $dirname was successfully created.";
    exit;
} else {
    echo "The directory $dirname exists.";
}

46
Rất nhiều những gì tiếng vang nói Ngày
kay - SE là xấu xa

13
xem xét nó cần đầu vào bài đăng và sử dụng nguyên trạng, cộng với làm cho 0777 dir, hoàn toàn không an toàn; P
sEver

2
Nghiêm trọng hơn, $ dirname có thể được khử trùng và quyền có thể được đặt thành 0755. Thêm vào đó một số chỉ thị .htaccess. Có một số khuyến nghị khác tại OWASP: owasp.org
James P.

# The following directives force the content-type application/octet-stream # and force browsers to display a download dialog for non-image files. # This prevents the execution of script files in the context of the website: #ForceType application/octet-stream Header set Content-Disposition attachment <FilesMatch "(?i)\.(gif|jpe?g|png)$"> ForceType none Header unset Content-Disposition </FilesMatch> # The following directive prevents browsers from MIME-sniffing the content-type. # This is an important complement to the ForceType directive above: Header set X-Content-Type-Options nosniff
James P.

7
Khi bạn sử dụng mkdir- tại sao bạn không vượt qua '$ filename'?
Howdy_McGee

17

Tôi nghĩ realpath () có thể là cách tốt nhất để xác thực nếu một đường dẫn tồn tại http://www.php.net/realpath

Đây là một chức năng ví dụ:

<?php
/**
 * Checks if a folder exist and return canonicalized absolute pathname (long version)
 * @param string $folder the path being checked.
 * @return mixed returns the canonicalized absolute pathname on success otherwise FALSE is returned
 */
function folder_exist($folder)
{
    // Get canonicalized absolute pathname
    $path = realpath($folder);

    // If it exist, check if it's a directory
    if($path !== false AND is_dir($path))
    {
        // Return canonicalized absolute pathname
        return $path;
    }

    // Path/folder does not exist
    return false;
}

Phiên bản ngắn của cùng chức năng

<?php
/**
 * Checks if a folder exist and return canonicalized absolute pathname (sort version)
 * @param string $folder the path being checked.
 * @return mixed returns the canonicalized absolute pathname on success otherwise FALSE is returned
 */
function folder_exist($folder)
{
    // Get canonicalized absolute pathname
    $path = realpath($folder);

    // If it exist, check if it's a directory
    return ($path !== false AND is_dir($path)) ? $path : false;
}

Ví dụ đầu ra

<?php
/** CASE 1 **/
$input = '/some/path/which/does/not/exist';
var_dump($input);               // string(31) "/some/path/which/does/not/exist"
$output = folder_exist($input);
var_dump($output);              // bool(false)

/** CASE 2 **/
$input = '/home';
var_dump($input);
$output = folder_exist($input);         // string(5) "/home"
var_dump($output);              // string(5) "/home"

/** CASE 3 **/
$input = '/home/..';
var_dump($input);               // string(8) "/home/.."
$output = folder_exist($input);
var_dump($output);              // string(1) "/"

Sử dụng

<?php

$folder = '/foo/bar';

if(FALSE !== ($path = folder_exist($folder)))
{
    die('Folder ' . $path . ' already exist');
}

mkdir($folder);
// Continue do stuff

2
Đối với bất kỳ ai gặp phải điều này, tôi tin rằng realpath lưu trữ các thư mục khi nó chạy, vì vậy nếu nó chạy một lần, thì thư mục đó sẽ bị xóa sau đó, nó có thể không trả về false nếu chạy lại.
Jase

2
file_exists cũng vậy
Sebas

7

Biến thể thứ hai trong câu hỏi không ổn, bởi vì, nếu bạn đã có tệp có cùng tên, nhưng nó không phải là thư mục, !file_exists($dir)sẽ trả về false, thư mục sẽ không được tạo, do đó "failed to open stream: No such file or directory"sẽ xảy ra lỗi . Trong Windows có sự khác biệt giữa 'file' và 'thư mục' loại, vì vậy cần phải sử dụng file_exists()is_dir()cùng một lúc, cho ex .:

if (file_exists('file')) {
    if (!is_dir('file')) { //if file is already present, but it's not a dir
        //do something with file - delete, rename, etc.
        unlink('file'); //for example
        mkdir('file', NEEDED_ACCESS_LEVEL);
    }
} else { //no file exists with this name
    mkdir('file', NEEDED_ACCESS_LEVEL);
}

3
$year = date("Y");   
$month = date("m");   
$filename = "../".$year;   
$filename2 = "../".$year."/".$month;

if(file_exists($filename)){
    if(file_exists($filename2)==false){
        mkdir($filename2,0777);
    }
}else{
    mkdir($filename,0777);
}

1
Bạn có thể kiểm tra trên đường dẫn đầy đủ và nếu nó không tồn tại, hãy tạo nó với mkdir đệ quy: if (! File_exists ($ filename2)) {mkdir ($ filename2, 0777, true); } Ngoài ra, mã của bạn sẽ không bao giờ tạo đường dẫn đầy đủ nếu tên tệp $ không tồn tại ...
Niels R.

3
$save_folder = "some/path/" . date('dmy');

if (!file_exists($save_folder)) {
   mkdir($save_folder, 0777);
}

3
Đặt chmod 777 không bao giờ là một ý tưởng tốt. 755 là đủ cho các thư mục.
Oldskool

2

thêm đúng sau 0777

<?php
    $dirname = "small";
    $filename = "upload/".$dirname."/";

    if (!is_dir($filename )) {
        mkdir("upload/" . $dirname, 0777, true);
        echo "The directory $dirname was successfully created.";
        exit;
    } else {
        echo "The directory $dirname exists.";
    }
     ?>

1

Vâng, thay vì kiểm tra cả hai, bạn có thể làm if(stream_resolve_include_path($folder)!==false). Nó chậm hơn nhưng giết chết hai con chim trong một phát bắn.

Một tùy chọn khác là đơn giản bỏ qua E_WARNING, không phải bằng cách sử dụng @mkdir(...);(vì đơn giản là sẽ từ bỏ tất cả các cảnh báo có thể, không chỉ thư mục đã tồn tại), mà bằng cách đăng ký một trình xử lý lỗi cụ thể trước khi thực hiện:

namespace com\stackoverflow;

set_error_handler(function($errno, $errm) { 
    if (strpos($errm,"exists") === false) throw new \Exception($errm); //or better: create your own FolderCreationException class
});
mkdir($folder);
/* possibly more mkdir instructions, which is when this becomes useful */
restore_error_handler();


1

Đây là một câu hỏi cũ, nhưng vẫn còn thời sự. Chỉ cần kiểm tra với is_dir()hoặc file_exists()chức năng cho sự hiện diện của tệp .hoặc ..trong thư mục được kiểm tra. Mỗi thư mục phải chứa các tệp này:

is_dir("path_to_directory/.");    

0

Đây là cách tôi làm

if(is_dir("./folder/test"))
{
  echo "Exist";
}else{
  echo "Not exist";
}

Khi trả lời một câu hỏi cũ, câu trả lời của bạn sẽ hữu ích hơn nhiều cho những người dùng StackOverflow khác nếu bạn đưa vào một số ngữ cảnh để giải thích cách trả lời của bạn, đặc biệt đối với một câu hỏi đã có câu trả lời được chấp nhận. Xem: Làm thế nào để tôi viết một câu trả lời tốt .
David Buck

0

Một cách để kiểm tra nếu một đường dẫn là thư mục có thể được theo sau:

function isDirectory($path) {
    $all = @scandir($path);
    return $all !== false;
}

LƯU Ý: Nó cũng sẽ trả về false cho đường dẫn không tồn tại, nhưng hoạt động hoàn hảo cho UNIX / Windows

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.