いよいよ、ソースのコーディングに移るわけですが、その前にもう一つ決めておくべき重要なことがあります。
書き込まれたデータをどのよう保存するべきか、という設計です。
今回の掲示板ではMySQLのようなDBMSに保存するのではなく、いままで実験してきたようにテキストファイルとして保存することにしています。よって、その保存の仕方が問題になります。
一般的なのは、一行に一件の書込みデータを保存して、項目をカンマで区切ったCSVファイルのような形式で保存する方法です。
このような形式にしておけば、保存データのサイズが大きくなったときに、書込みごとに別々にファイルを作って保存するよりも、ずっと管理しやすくなります。
そこで、保存されるファイルのサンプルを示すと、したのようになります。
[記録する情報の一覧]
|
項目名
|
属性1
|
属性2
|
|
番号
|
自動
|
-
|
|
なまえ
|
20文字まで
|
必須
|
|
件名
|
40文字まで
|
任意(空欄なら自動)
|
|
内容
|
500文字まで
|
必須
|
|
日時
|
自動
|
-
|
[実際に保存されるログファイルデータのサンプル]
番号 , 名前 , 件名 , 内容 , 時間
1 , マイク , お知らせ , 内容はこちら1 , 2004/6/15 12:00
2 , メアリ , お返事 , 内容はこちら , 2004/6/16 16:23
3 , ポール , 、、、、、
(注)カンマを赤で書いています。
|
これで一見問題ないかのように見えますが、一つだけ問題があります。
CSV形式で保存するので、各書込みごとのデータの区切りは「行」で問題なく、そのそれぞれの項目はカンマ「,」だと思うので、データを読み込んだ時にそのような分離の処理をすればいいのですが、書き込まれた内容にカンマ「,」があった場合にどうするか、ということです。
これだけではピンとこないですよね?
例えば、データの処理をするのに、各行を読み出して変数に入れる場合を考えてみてください。
[各項目を横の変数に入れるとします]
番号 $number
名前 $name
件名 $subject
内容 $content
時間 $time
|
以上のような変数が割り当てられていた場合、
「1 , マイク , お知らせ , 内容はこちら1 , 2004/6/15 12:00」
のようなデータは「 , 」で区切って
番号 $number="1";
名前 $name="マイク";
件名 $subject="お知らせ";
内容 $content="内容はこちら1";
時間 $time="2004/6/15 12:00";
|
というように各変数に格納されます。これは問題ないのですが、仮にデータが次のようだった場合を考えてみてください。
「5 , 花子 , お知らせ , 売りますパソコン2,000円 , 2004/6/15 12:00」
カンマでデータを区切って先ほどのように変数に格納することを考えると次のようになりそうですが、、、
番号 $number="5";
名前 $name="花子";
件名 $subject="お知らせ";
内容 $content="売りますパソコン2,000円";
時間 $time="2004/6/15 12:00";
|
実際はどうなのでしょうか?これを同じように処理すると実際には以下のようになります。
番号 $number="5";
名前 $name="花子";
件名 $subject="お知らせ";
内容 $content="売りますパソコン2";
時間 $time="000円";
|
一見普通に見えますが、よく見ると内容と時間がおかしくなっているのがわかります。これは、内容の「売りますパソコン2,000円」という文字列にカンマ「 , 」が入っていることが原因です。
入力されたデータの中にカンマが含まれており、データの区切記号としてカンマを使っているので、意図しない場所でデータが区切られてしまった結果、本来表示されるべき内容と時間がおかしくなってしまった、、、という結果なのです。
では、このような問題が起こらないようにするためにはどのような方法があるのでしょうか?そこでよく検討されるのが、この区切記号(セパレーター)をカンマ以外のあまり使われない文字にしてしまうという方法です。
例えば、区切文字として、普段は絶対に使わないような「 | 」や「 [ 」などを使う方法です。この区切文字は一文字である必要はなく、「 ||| 」や「 *+?> 」なんていう「ほぼ」ありえない文字の組み合わせでもOKなのです。
[例:こんな感じ]
「5||花子||お知らせ||売りますパソコン2,000円||2004/6/15 12:00」
でも、顔文字等で記号を多様する今日、「ほぼ」というあいまいな基準にたよると、いつデータが壊れるとも限りません。そこで発想の転換というか区切記号(セパレーター)として利用した文字列は入力を受け付けない、という方法をとるのです。
カンマの例でいうなら、カンマ「 , 」は利用者からの書込みによって入力されるわけですから、カンマを無効にしてしまう、もしくは別の文字に変換してしまうという方法です。
そうすることで、カンマ「 , 」を確実に区切記号(セパレーター)として利用することが可能になります。
データの入力のところで、「\n」や「\r」などの改行コードを無効化したりしましたよね?これと同じことをカンマについても置換という形で行えば済むことになります。
s/\,/,/g;
※カンマの前の「\」はエスケープ用です。
「,」でブラウザにはカンマを表示できます。
これで、カンマを入力されてもデータ的には変換されてしまいます。
|
上の処理をデータ受け取りのところですることで、先ほど問題のあった処理は下のように記録されることになります。
「5 , 花子 , お知らせ , 売りますパソコン2,000円 , 2004/6/15 12:00」
データを視覚的に見るとおかしいですが、もともとHTMLに表示させるためのログデータなので、HTML上では普通に見えます。これで、データがおかしなところで区切られてしまう問題は発生しません。
次回は、入力されるとデータがおかしくなってしまうような文字の処理の仕方について考えたいと思います。
(2004/2/27 by あいまい)
|