- 締切済み
フォーム入力(CGIでデータ取得)でシングルクォートを有効
CGIを使用してフォームで入力された値を取得する時にデータ内にシングルクォートなどがあると そこから先が消えてしまいます。 たとえばフォームに「X'mas」と入力されていた場合に、実際には「X」しか取得できません。 $buffer =~ s/'/\'/g; としてみたのですが、ダメでした。 どのようにしたらいいのでしょうか?
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- leaz024
- ベストアンサー率75% (398/526)
> cgi内では"は使用できませんよね? そんなことは無いです。ちゃんと使用できますよ。 ダブルクォートで囲んだ文字列の中にダブルクォートを入れる場合、 $str = "<IMG src=\"xxx\">\n"; のように、「\」を使ってエスケープすれば大丈夫です。 ただ、この方法でHTMLを書くと \ だらけで大変見にくくなってしまうので、「ヒアドキュメント」や「qq 演算子」(または「q 演算子」)を使うことが多いです。 No.1では qq を使って「qq{文字列}」のように書きましたが、{ と } の部分は、他の種類のカッコか、別の記号文字でも構いません。 詳しくは参考書などで調べてみてください。 次に chr2ref 関数について。 「文字参照」は知ってますよね?(< や & など) フォームのvalue内の一部の文字参照は、送信時に文字実体となって送信されます。 つまり、 <INPUT type="hidden" name="a" value="b&c"> という hiddenフォームの値を受け取ると a=b%26c (「%26」をデコードすると「&」) となっています。 もちろん、value="b&c" でも大丈夫ですが、前述のダブルクォートや文字参照自身を書きたい場合には必要です。 例えば「<」自身を出力する場合は「&lt;」としなければなりません。 通常の文字列を書き出す際に chr2ref を通すことは、フォームだけでなくHTML全体において有効ですが、受け取ったフォームの値を使う場合には注意が必要です。 なぜなら、掲示板のような‘入力された値をHTMLに出力するCGI’では、たいていの場合、入力された < や > をデコードの時点で文字参照に変換しているのです。 文字参照化されている文字列を chr2ref に通すと、 入力値 < ↓ デコード < ↓ chr2ref &lt; となってしまいます。 もしデコードで文字参照化を行っていなければ、No.1のお礼のやり方で問題ありません。 行っている場合は chr2ref は必要ないわけですが、デコードの文字参照化がちゃんと &、<、>、" の4文字を対象にしているか確認して下さい。 中途半端に < と > しかやっていないと、うまく行かないことがあります。 また、必ず & → & の変換を最初に行って下さい。でないと < → < → &lt; となってしまいます。
- leaz024
- ベストアンサー率75% (398/526)
フォームのvalue値をシングルクォートで囲んでいませんか? 例えば、 <INPUT type=hidden name=a value='X'mas'> のようにすると、「value='X'」と その他の属性「mas'」であるかのように認識され、X しか送信されません。 回避するには value='X\'mas' のようにすればよいでしょう。 ただし、本来ならシングルクォートではなくダブルクォートで囲み、中のダブルクォートは文字参照(")に変換するべきです。 (同様に、&、<、> の変換も必要) なので、そのような文字参照への変換関数を1つ作っておき、HTMLへの出力する値はその関数を通すようにしてはどうでしょう? sub chr2ref { local($_) = @_; s/&/&/g; s/</</g; s/>/>/g; s/"/"/g; $_; } print qq{<INPUT type="hidden" name="a" value="}, chr2ref("X'mas"), qq{">\n};
お礼
回答ありがとうございます。 実際の書込みはcgiによるデータの送受信で行っているのですが、 その場合も chr2ref("$FORM{'hogehoge'}")・・ のようにしてしまってもOKなのでしょうか? またダブルクォーテーションを使用したかったのですが、cgi内では"は使用できませんよね?それで安易に'を使用してしまったのですが…。