[PHP]再帰的なフォルダ生成が行える関数、mkdir()

Read More


mkdir()第3引数trueを指定すると再帰的にフォルダを生成してくれるそうな。




ちょ、








ええええええええええ!










そんなんできるの?!

今日の今日まで知らなかったよ。
今まで自前でやってたよ。


じゃあこれからはそっち使うよ…



とりあえず再帰的なフォルダ生成を試してわかったことのメモを残しておく。



■再帰的なフォルダ生成の例:その1
$dir_path = '/aaa/bbb/ccc';
mkdir($dir_path, 0777, true);

プログラムはこんな感じ。
これでaaaとbbbとcccフォルダが生成される。


仮にaaaが最初から存在していた状態でプログラムを走らせた場合は、
bbbとcccフォルダが生成される。


プログラムを走らせてフォルダが生成できる場合には問題ないのだが、
aaa、bbb、cccのフォルダが既に存在している時にプログラムを走らせると以下のようなワーニングがでる。
Warning: mkdir() [function.mkdir]: File exists in {filepath}.php on line {number}


なのでワーニングを避けるためif文チェックを追加する。



■再帰的なフォルダ生成の例:その2(改良版)
$dir_path = '/aaa/bbb/ccc';
if(!is_dir($dir_path)) {
  mkdir($dir_path, 0777, true);
}// end if

if文が邪魔で美しくないなーと感じる場合は「@演算子」のみの対応でもいいかもしれない。
# もちろんログにはでるけど。

というかmkdir()に限らずファイルやフォルダの生成・削除は基本的に頭に@を付けておいた方が無難。
これはif文のあるなしに関係なしに。


もちろんtry catchを使ってもいいが。



■再帰的なフォルダ生成の例:その3(さらに改良版)
$dir_path = '/aaa/bbb/ccc';
if(!is_dir($dir_path)) {
  @mkdir($dir_path, 0777, true);
}// end if

ということでこれがまあ無難な形かなあ?


しかしこのままだとフォルダ生成の成否が判定できてない。


実際に運用することを想定して考えた場合、
フォルダの生成の成功か失敗かより、
そのプログラムを超えた時点でちゃんとフォルダがあるかどうかが重要なわけで。


それを踏まえて実用的に書くと以下のような感じかね。



■再帰的なフォルダ生成の例:その4(実用版)
$dir_path = '/aaa/bbb/ccc';

$chk=true;

// フォルダの用意
if($chk) {
  if(!is_dir($dir_path)) {
    $chk = @mkdir($dir_path, 0777, true);
  }// end if
}// end if

// その他の処理
if($chk) $chk = (true)?:'';
if($chk) $chk = (true)?:'';
if($chk) $chk = (true)?:'';
if($chk) $chk = (true)?:'';

// 処理結果の判定
if($chk) echo 1;
else echo 0;




うむ、これならフォルダのとこでコケたらその後の処理をスキップできる。
実に自分らしい。まる。




■関連記事: [PHP]ディレクトリを再帰的に削除する
http://xirasaya.com/?m=detail&hid=539









Comments(3)

1  みやび  2014/12/20 (土) 00:29 ID:bonNbsA15
作ったディレクトリは基本的に書き込み権限あるものなんで、
単純にis_wrightable関数使って書き込めるか否かを判別すれば良いのでは?

正月休みはGoとNodeで一本ずつアプリ作ってみます。

2  みやび  2014/12/22 (月) 10:44 ID:cjwvFOq15
@マークでのエラー回避はオーバーヘッドが大きいので出来る事なら回避したいですね。
(PHP アットマーク パフォーマンス)等でぐぐったら出ました
僕が作れと言われたらこんな感じの関数作ってチェックしてからmkdirで作ると思います
(フロー長すぎでダサいコードですが(/ω\))

function is_writable_of ($path) {
$paths = explode('/', $path);
$result = false;

$last_path = '';
// 最終ディレクトリが書き込み権限ありかチェック
foreach($paths as $key => $this_path) {
$last_path .= $this_path . '/';
if (!file_exists($last_path)) {
break;
}
if (is_file($last_path)) {
$result = false;
break;
}
$result = is_writable($last_path);
}

return $result;
}

/var => false
/var/tmp => true
※軽く動かしてみましたがどうなるかはわからんです

3  シラサヤ  2014/12/22 (月) 11:31 ID:FE4sJ5r15
> @マークでのエラー回避はオーバーヘッドが大きいので出来る事なら回避したいですね。
> (PHP アットマーク パフォーマンス)等でぐぐったら出ました
うん、それは有名だよね。
だから、多用はできないけどそれでも必要なところがあるって話かな。