Bagaimana saya memeriksa apakah ada direktori? “Is_dir”, “file_exists” atau keduanya?

329

Saya ingin membuat direktori jika belum ada.

Apakah is_dircukup menggunakan untuk tujuan itu?

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

Atau haruskah saya gabungkan is_dirdengan file_exists?

if ( !file_exists( $dir ) && !is_dir( $dir ) ) {
    mkdir( $dir );       
} 
Peter
sumber
3
Operator boolean ATAU harus AND, dan dalam PHP ditulis sebagai &&
Ivo Renkema
15
@IvoRenkema PHP juga mendukung or/ andselain ||/ &&.
Camilo Martin
1
Operator &&tidak berguna di sini, karena, jika file tidak ada ( !file_exists($dir) == true), pasti itu bukan direktori. Dan jika file ada, !is_dir($dir)tidak akan diperiksa, karena !file_exists($dir)akan kembali falsedan &&operator mengalami hubungan pendek .
Boolean_Type
4
Dalam pandangan saya, operator harus OR.
Mojtaba
dengan && ini berfungsi dengan baik untuk saya
FABBRj

Jawaban:

220

Keduanya akan mengembalikan true pada sistem Unix - di Unix semuanya adalah file, termasuk direktori. Tetapi untuk menguji apakah nama itu diambil, Anda harus memeriksa keduanya. Mungkin ada file biasa bernama 'foo', yang akan mencegah Anda membuat nama direktori 'foo'.

Marc B
sumber
37
jangan lupa untuk memeriksa apakah is_writable juga
Drewdin
10
@Drewdin Anda ingin memeriksa induknya is_writablebukan?
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.";
}
Maher
sumber
46
Sangat banyak yang dikatakan gema ...
kay - SE adalah kejahatan
13
mempertimbangkan itu mengambil input posting dan menggunakannya apa adanya, ditambah membuat 0777 dir, prolly tidak aman sama sekali; P
sEver
2
Lebih serius lagi, $ dirname dapat dibersihkan dan izin dapat diatur ke 0755. Tambahkan beberapa arahan .htaccess. Ada beberapa rekomendasi lebih lanjut di 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
Saat Anda menggunakan mkdir- mengapa Anda tidak memberikan '$ filename' saja?
Howdy_McGee
17

Saya pikir realpath () mungkin cara terbaik untuk memvalidasi jika ada jalan http://www.php.net/realpath

Berikut ini contoh fungsinya:

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

Versi singkat dari fungsi yang sama

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

Contoh keluaran

<?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) "/"

Pemakaian

<?php

$folder = '/foo/bar';

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

mkdir($folder);
// Continue do stuff
inckie
sumber
2
Bagi siapa saja yang menemukan ini, saya percaya bahwa cache realpath folder ketika dijalankan, jadi jika dijalankan sekali, maka folder tersebut dihapus setelah itu, itu mungkin tidak kembali salah jika dijalankan lagi.
Jase
2
begitu juga file_exists
Sebas
7

Varian kedua dalam postingan pertanyaan tidak ok, karena, jika Anda sudah memiliki file dengan nama yang sama, tetapi itu bukan direktori, !file_exists($dir)akan kembali false, folder tidak akan dibuat, sehingga kesalahan "failed to open stream: No such file or directory"akan terjadi. Di Windows ada perbedaan antara tipe 'file' dan 'folder', jadi perlu menggunakan file_exists()dan is_dir()pada saat yang sama, untuk 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);
}
Boolean_Type
sumber
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);
}
rons
sumber
1
Anda dapat memeriksa jalur lengkap dan jika tidak ada, buat dengan mkdir rekursif: if (! File_exists ($ filename2)) {mkdir ($ filename2, 0777, true); } Juga, kode Anda tidak akan pernah membuat path lengkap jika $ nama file tidak ada ...
Niels R.
3
$save_folder = "some/path/" . date('dmy');

if (!file_exists($save_folder)) {
   mkdir($save_folder, 0777);
}
jam pria
sumber
3
Pengaturan chmod 777 tidak pernah merupakan ide yang baik. 755 sudah cukup untuk folder.
Oldskool
2

tambahkan true setelah 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.";
    }
     ?>
Sujeet Kumar
sumber
1

Nah alih-alih memeriksa keduanya, Anda bisa melakukannya if(stream_resolve_include_path($folder)!==false). Itu lebih lambat tetapi membunuh dua burung dalam satu tembakan.

Pilihan lain adalah mengabaikan saja E_WARNING, bukan dengan menggunakan @mkdir(...);(karena itu hanya akan menghapus semua kemungkinan peringatan, bukan hanya direktori yang sudah ada), tetapi dengan mendaftarkan penangan kesalahan tertentu sebelum melakukannya:

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();
Sebas
sumber
1

Ini adalah pertanyaan lama, tapi masih hangat. Cukup uji dengan is_dir()atau file_exists()fungsi untuk keberadaan .atau ..file dalam direktori yang diuji. Setiap direktori harus mengandung file-file ini:

is_dir("path_to_directory/.");    
djordje
sumber
0

Inilah yang saya lakukan

if(is_dir("./folder/test"))
{
  echo "Exist";
}else{
  echo "Not exist";
}
Jetro Bernardo
sumber
Saat menjawab pertanyaan lama, jawaban Anda akan jauh lebih berguna bagi pengguna StackOverflow lain jika Anda menyertakan beberapa konteks untuk menjelaskan bagaimana jawaban Anda membantu, terutama untuk pertanyaan yang sudah memiliki jawaban yang diterima. Lihat: Bagaimana saya menulis jawaban yang bagus .
David Buck
0

Cara untuk memeriksa apakah path adalah direktori dapat mengikuti:

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

CATATAN: Ini akan mengembalikan false untuk jalur yang tidak ada juga, tetapi bekerja dengan sempurna untuk UNIX / Windows

Máxima Alekz
sumber