LoginSignup
6
6

More than 5 years have passed since last update.

PHPで同時実行を考慮したmkdirs

Last updated at Posted at 2014-07-31

PHP標準のmkdirsだと、異なるプロセスやスレッドから新規に複数階層のディレクトリを同時に作成しようとすると後続のmkdirsがエラーになることがあった。
PHPのソースを確認したところ、タイミングによっては、先行するプロセスやスレッドで作成されたディレクトリを後続のプロセスやスレッドが同じディレクトリを作成しようとして失敗し、その結果エラーになる可能性があった。
そこで、ディレクトリ階層のmkdirで失敗してもディレクトリが存在する場合はエラーとしないようにコードを書いてみた。

サンプルコード

const DIRECTORY_SEPARATOR = '/';

function mkdirs($path, $mode = 0777) {
  $dirs = explode(DIRECTORY_SEPARATOR, $path);
  $currentPath = '';
  foreach ($dirs as $dir) {
    $currentPath .= _joinDir($currentPath, $dir);
    if (!is_dir($currentPath) && !mkdir($currentPath, $mode)) {
      $error = error_get_last();
      if (!is_dir($currentPath)) {
        return false;
      }
    }
  }
  return true;
}

function _joinDir($currentDir, $dir) {
  if (strlen($dir) <= 0) {
    return DIRECTORY_SEPARATOR;
  }
  if (strlen($currentDir) <= 0 && 0 < strlen($dir)) {
    return $dir;
  }
  if ($currentDir == DIRECTORY_SEPARATOR) {
    return $dir;
  }
  return DIRECTORY_SEPARATOR .$dir;
}

参考

同時実行に耐えうるファイル操作の方式検討 (mkdir システムコール直接発行等 · Issue #12 · ToshiyukiTerashita/castoro

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6