今回はちょっとした実験です。
ユニークなファイル名を生成する関数「tempnam()」関数がPHPにはあるのですが、XAMP環境ではうまく動作しないと以前書きました。
そこで以下のようなユニーク文字列生成関数を作って使っています。
function tempName($length=8){ // ファイル名で使う文字列を指定 $str = "23456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ"; // 文字数を取得 $num = strlen($str); $tmp = ""; // 引数で指定した分だけ繰り返し for($i = 0; $i < $length; $i++){ // 0~文字数-1の数字からランダムで選択 $index = rand(0, $num-1); // 文字列からランダムで指定した位置の一文字を取得して連結 $tmp .= substr($str, $index, 1); } // 生成した文字を返す return $tmp; }
tempnam()関数との違いは、完全なユニークにならないかもしれないこと。
tempnam()関数は、指定したディレクトリでユニークなファイル名を生成し、空のファイルを作成します。
でも、上記で作成した関数では、存在チェックを行っていないので、重複する可能性があります。
いったいどれくらいの文字数でいくつ作成したら重複するのか?を調べてみました。
チェックを行ったコードは以下の通りです。
$count = 0; for($i=0;$i<100;$i++){ $array = array(); $result = array(); for($j=0;$j<100;$j++){ $array[] = tempName(※); } $result = array_unique($array); if(count($result) != 100) $count++; } echo $count;
単純にランダム文字列生成を100回繰り返して生成し、その中で重複しているものを取り除いた配列を用意します。($result)
その配列の個数が100でない場合を1回と数えて、それを100回繰り返してみました。($count)
さらに生成する文字数によっても重複率を出してみました。
「※」の部分に作成文字列数として2、4、6、8、10文字のランダムな文字列を5パターンで計測した結果が以下です。
100個作るくらいだと、4文字以上の文字列を作ればほぼ大丈夫そうですね。
ちなみに1000個作った場合だと、
2文字のランダム文字列なんて、必ず重複してますw
4文字でも1000個作って100回繰り返すと5%前後は重複するようですね。(多いときは10回以上)
ということを踏まえると、ユニーク文字列を作る場合、例えば、
$str = date('Ymd')."-".tempName();
このようにして、文字列の頭に当日の日付の数字8桁が入るように指定して生成してやれば、
1日に1000個ファイル名として生成したとしても、8文字以上で作っていればほぼ問題なさそうですね。
それでも気になるようでしたら、倍の16文字ならまず大丈夫でしょう。(保障はできませんが・・・)
ちなみに、上記1000個を100回繰り返すのに、さくらのレンタルサーバ ライトで実行した結果、実行時間が80~100秒くらい処理にかかりました・・・文字列1000個を100回生成して、10回試行しましたからね・・・
【追記】
ちょっと気になったので調べたら、各レンタルサーバーで応答時間が相当違いました。
レンタルサーバー会社 | プラン | 応答時間 |
---|---|---|
株式会社KDDIウェブコミュニケーションズ CPI |
シェアード(共有) | 約34秒 |
レンタルサーバーミニム |
ミニマムプラン | 約35秒 |
ヘテムル |
- | 約43秒 |
ファーストサーバ |
ギガント2 | 約44秒 |
エクスビット | パーソナル300メガ | 約46秒 |
WebARENA |
- | 約47秒 |
ロリポップ! |
チカッパプラン | 約52秒 |
さくらのレンタルサーバ |
ライト | 約85秒 |
サーバーカウボーイ | 計測不能※ | |
ITPARK | (同上) |
※タイムアウトしました。max_execution_timeが指定できなかった。