データ一つ一つにユニークな10桁前後の英数字のIDを付与したかった。
AUTO_INCREMENTの連番でもよかったのだが、データリストを表示する時URLへ付けたIDが連番だとちょっとダサい。
データ詳細のURLから次のデータURLを予測し難くしたい時もある。
画像などのファイルを保存する時に使われる様なユニークIDは長いので不可。
マイクロ秒を取得してそれを基に10進数から36進数へ変換した英数字をIDに使う事にしました。
マイクロ秒からユニークIDを生成
考えとしては大きな10進数を36進数に変換すれば英数字のIDが作れるのではないかという事です。
素になる数字はtime()のタイムスタンプを考えたのですが、連続でタイムスタンプを取得した場合は同じ数字になるのでmicrotime()を使いマイクロ秒まで取得します。
マイクロ秒の取得であれば連続で取得しても違う数字になっています。
タイムスタンプ・マイクロ秒で取得
//マイクロ秒単位で取得
$microTime = microtime(); //0.01177900 1484176487
//半角スペースで分割
list($msec, $sec) = explode(" ", $microTime);
マイクロ秒を整数にし一つの数値へ
//マイクロ秒を整数に。下二桁は切り捨て。
$msec = $msec*1000000;
$msec = floor($msec);
//タイムスタンプ部分とマイクロ秒部分を合わせて一つの数値へ
$createTimeString = $sec.$msec;
作成した数値を逆順に入れ替え
逆順に入れ替えない場合は最初の数桁が同じIDが作成されてしまいます。
$createTimeString = strrev($createTimeString);
数値を10進数から36進数へ変換
echo base_convert($createTimeString,10,36);
関数にして使ってみる
$uniqId = createUniqId();
var_dump($uniqId);
function createUniqId(){
list($msec, $sec) = explode(" ", microtime());
$hashCreateTime = $sec.floor($msec*1000000);
$hashCreateTime = strrev($hashCreateTime);
return base_convert($hashCreateTime,10,36);
}
まとめ
どんどん増えていくタイムスタンプとマイクロ秒の組み合わせで、被らない数値から36進数を作成すればユニークIDを作れるのではと思いました。
自作アプリで利用してますが、IDの衝突などの不具合は起きていません。
色んな可能性を考えていますが、駄目な部分などあればコメント貰えると助かります。