1) 2バイト文字を含む長い文字列がキーとなるデータがある
2) 1データ毎にファイルを作りたい
3) ファイル名長に制限があるのでキーとなる文字列を短くしたい
例)
キー「りんごのデータ」
キー「みかんのデータ」
↓
キーを元に短い文字列を作成
↓
キー「りんごのデータ」→ 短いキー「apple」
キー「みかんのデータ」→ 短いキー「orange」
↓
ファイルを作成
↓
apple.txt
orange.txt
データ取得時にはキーを使用
↓
キー「りんごのデータ」から apple.txt を抽出
※このとき、キー←→短いキー(ファイル名)は可逆でどの方向にも
一意になるものとします。※
この、キーを生成するプログラムが知りたいです。
よろしくお願いいたします。
文字列長が不明なので厳密に一意というのは無理かと思います。
特に「長いキー」から「短いキー」にするという事は、その時点で可逆圧縮するので「結果、短くならない可能性」もあります。
なので私は代替しか提案できませんが、「変換履歴ファイル」を別に保存しておくのが一番だと思います。
[trans.dat]
0001,200606020116,りんごのデータ
0002,200606020132,みかんのデータ
これで 0001.txt, 0002.txt ... と生成していきます。
新しくキーが登録された場合は「行数」から連番を生成等でもかまいません。
あるいは、いっその事……このキー関連付けを連想配列にして動的に生成されるファイルをincludeするという荒業もあります。
※ 以下コード、面倒なので文字エスケープとか例外とか省略
[main.php]
include "trans.php";
echo $transdata[りんごのデータ];
[trans.php] (このファイルを動的に生成する)
$transdata["りんごのデータ"] = "apple";
$transdata["みかんのデータ"] = "orange";
// もしくは array関数で一度に登録
[addkey.php]
$key = "ぶどうのデータ";
$data = "grape";
$fp = fopen("trans.php","a");
fputs($fp,"transdata[\"$key\"] = \"$data\";\n");
// array関数で登録している場合はもうちょい複雑。
この荒業の欠点は、キーができればできるほどメモリ消費するという事です。
ファイル名のバイト列を可逆圧縮してbase64みたいな方法で文字列化すれば一応目的の様な事はできるとは思います。しかし、Chietherさんが書かれた通りで、ファイル名がある一定の長さを越えない保証はありません。
やはり代替案になりますが、キーと短いキーとの対応表をデータベースに保存してはいかがでしょうか。大規模であればそっちの方がパフォーマンスがよくなります。
また、2.の要望には反しますが、いっその事データベースにファイルの内容も入れてしまえば、そもそも短いキーも作る必要がなくなります。
繰り返しになりますが、「データベースと仰っているのは上で出ている定義ファイルと同じ」という発言が根本的な発想が同じという意味であれば同意しますが、パフォーマンスも同じという主旨であればそうではない場合の方がはるかに多いです。
しかし、確かに私の回答を見ると「短いキー」はファイル名を圧縮して作るようにも読めますね(私自身はIDの様な一意になる数字のつもりで書いていました)。誤解をまねく表現でどうもすみません。
只今高熱に苛まれていますので、走り書きメモ程度に。
連想配列の方がいいのか……define()の方がいいのか。
でもget_defined_constantsあたりで取得できるあたり
パフォーマンスは変わらないのかもしれない。
むしろdefinedする必要があるから不便で効率悪いかも。
if( $key == "りんご" ) $val="apple";
な関数でも用意しておいて、 PHPA とか APC あたりでキャッシュ化した方がいいのか……。
データ量次第で判断変わるから、いろいろ試してみてください。
伝わってないようなので補足します。
「長」から「短」への一意の重複しない(人の手が不必要で簡易な)方法を示しました。
連想配列は作り手の恣意的な名前が入る上に
>キーは数十万件になり
との事で、重複しないと確定させる事が困難になります。
その上で、他の方が書かれているDB・ファイル等の方法を使って「短」から「長」への方法を示したまでです。
他の方へのコメントもそうですが、回答した方への配慮が欠けているように見受けられます。
> Chietherさん
ありがとうございます。こちらでも色々ためしてみます。
ハッシュ関数は『「長」から「短」への一意の重複しない』を満たしません。数十万件程度では確率的にはかなり低いですが、重複する可能性があります。