Skip to content

Instantly share code, notes, and snippets.

@kohki-shikata
Created October 13, 2024 13:04
Show Gist options
  • Save kohki-shikata/8edac27f68e0f87f0b352cfbf638043c to your computer and use it in GitHub Desktop.
Save kohki-shikata/8edac27f68e0f87f0b352cfbf638043c to your computer and use it in GitHub Desktop.
Hash based directoryの作成
<?php
if (!function_exists('createCustomDirectoryFromFilename')) {
/**
* ファイル名からハッシュを生成し、対応するディレクトリを作成します。
*
* @param string $filename
* @param int $initialDirLength 最初のディレクトリの文字数
* @param int $subDirLevels サブディレクトリの数
* @param string $baseDir ベースディレクトリ
* @return string|false
* @throws InvalidArgumentException
*/
function createCustomDirectoryFromFilename($filename, $initialDirLength = 2, $subDirLevels = 1, $baseDir = 'uploads') {
// 引数のバリデーション
if (!is_string($filename) || empty($filename)) {
throw new InvalidArgumentException('ファイル名は非空の文字列である必要があります。');
}
if (!is_int($initialDirLength) || $initialDirLength < 1) {
throw new InvalidArgumentException('最初のディレクトリの文字数は1以上の整数である必要があります。');
}
if (!is_int($subDirLevels) || $subDirLevels < 0) {
throw new InvalidArgumentException('サブディレクトリの数は0以上の整数である必要があります。');
}
// ハッシュを生成し、最初のディレクトリを決定
$hash = hash('sha256', $filename);
$dir = substr($hash, 0, $initialDirLength); // 最初のディレクトリの文字数
$path = "{$baseDir}/{$dir}/"; // 最初のディレクトリを作成
$offset = $initialDirLength; // 初期オフセット
for ($i = 0; $i < $subDirLevels; $i++) {
$subDir = substr($hash, $offset, 1); // 1文字を取得
$path .= "{$subDir}/"; // サブディレクトリを追加
$offset++; // オフセットを更新
}
// ディレクトリが存在しない場合に作成
if (!is_dir($path)) {
if (!mkdir($path, 0777, true) && !is_dir($path)) {
throw new RuntimeException("ディレクトリの作成に失敗しました: {$path}");
}
}
return $path; // 作成されたパスを返す
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment