Я хочу создать каталог, если он не существует.
Использует ли is_dir
достаточно для этой цели?
if (!is_dir($dir)) { mkdir($dir); }
Или мне следует комбинировать is_dir
с file_exists
?
if (!file_exists($dir) && !is_dir($dir)) { mkdir($dir); }
Оба вернут true в Unix-системах – в Unix все это файл, включая каталоги. Но чтобы проверить, взято ли это имя, вы должны проверить оба. Возможно, существует обычный файл с именем 'foo', который помешает вам создать имя каталога 'foo'.
$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."; }
Я думаю, что realpath () может быть лучшим способом проверить, существует ли путь http://www.php.net/realpath
Вот пример функции:
<?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; }
Короткая версия той же функции
<?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; }
Примеры вывода
<?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) "/"
Применение
<?php $folder = '/foo/bar'; if(FALSE !== ($path = folder_exist($folder))) { die('Folder ' . $path . ' already exist'); } mkdir($folder); // Continue do stuff
Второй вариант в вопросе post не подходит, потому что, если у вас уже есть файл с тем же именем, но это не каталог !file_exists($dir)
вернет false
, папка не будет создана, поэтому ошибка "failed to open stream: No such file or directory"
не будет. В Windows существует разница между типами «файл» и «папка», поэтому вам необходимо одновременно использовать file_exists()
и is_dir()
, например:
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); }
$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); }
$save_folder = "some/path/" . date('dmy'); if (!file_exists($save_folder)) { mkdir($save_folder, 0777); }
Ну, вместо того, чтобы проверять оба if(stream_resolve_include_path($folder)!==false)
, вы можете сделать, if(stream_resolve_include_path($folder)!==false)
. Он медленнее, но убивает двух птиц одним выстрелом.
Другой вариант – просто игнорировать E_WARNING
, а не использовать @mkdir(...);
(потому что это просто отменяет все возможные предупреждения, а не только каталог уже существует), но, зарегистрировав конкретный обработчик ошибок, прежде чем делать это:
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();