• 締切済み

フォーム入力(CGIでデータ取得)でシングルクォートを有効

CGIを使用してフォームで入力された値を取得する時にデータ内にシングルクォートなどがあると そこから先が消えてしまいます。 たとえばフォームに「X'mas」と入力されていた場合に、実際には「X」しか取得できません。 $buffer =~ s/'/\'/g; としてみたのですが、ダメでした。 どのようにしたらいいのでしょうか?

みんなの回答

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.2

> cgi内では"は使用できませんよね? そんなことは無いです。ちゃんと使用できますよ。 ダブルクォートで囲んだ文字列の中にダブルクォートを入れる場合、   $str = "<IMG src=\"xxx\">\n"; のように、「\」を使ってエスケープすれば大丈夫です。 ただ、この方法でHTMLを書くと \ だらけで大変見にくくなってしまうので、「ヒアドキュメント」や「qq 演算子」(または「q 演算子」)を使うことが多いです。 No.1では qq を使って「qq{文字列}」のように書きましたが、{ と } の部分は、他の種類のカッコか、別の記号文字でも構いません。 詳しくは参考書などで調べてみてください。 次に chr2ref 関数について。 「文字参照」は知ってますよね?(&lt; や &amp; など) フォームのvalue内の一部の文字参照は、送信時に文字実体となって送信されます。 つまり、   <INPUT type="hidden" name="a" value="b&amp;c"> という hiddenフォームの値を受け取ると   a=b%26c   (「%26」をデコードすると「&」) となっています。 もちろん、value="b&c" でも大丈夫ですが、前述のダブルクォートや文字参照自身を書きたい場合には必要です。 例えば「&lt;」自身を出力する場合は「&amp;lt;」としなければなりません。 通常の文字列を書き出す際に chr2ref を通すことは、フォームだけでなくHTML全体において有効ですが、受け取ったフォームの値を使う場合には注意が必要です。 なぜなら、掲示板のような‘入力された値をHTMLに出力するCGI’では、たいていの場合、入力された < や > をデコードの時点で文字参照に変換しているのです。 文字参照化されている文字列を chr2ref に通すと、   入力値  <    ↓   デコード &lt;    ↓   chr2ref &amp;lt; となってしまいます。 もしデコードで文字参照化を行っていなければ、No.1のお礼のやり方で問題ありません。 行っている場合は chr2ref は必要ないわけですが、デコードの文字参照化がちゃんと &、<、>、" の4文字を対象にしているか確認して下さい。 中途半端に < と > しかやっていないと、うまく行かないことがあります。 また、必ず & → &amp; の変換を最初に行って下さい。でないと < → &lt; → &amp;lt; となってしまいます。

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.1

フォームのvalue値をシングルクォートで囲んでいませんか? 例えば、   <INPUT type=hidden name=a value='X'mas'> のようにすると、「value='X'」と その他の属性「mas'」であるかのように認識され、X しか送信されません。 回避するには value='X\'mas' のようにすればよいでしょう。 ただし、本来ならシングルクォートではなくダブルクォートで囲み、中のダブルクォートは文字参照(&quot;)に変換するべきです。 (同様に、&、<、> の変換も必要) なので、そのような文字参照への変換関数を1つ作っておき、HTMLへの出力する値はその関数を通すようにしてはどうでしょう? sub chr2ref {   local($_) = @_;   s/&/&amp;/g; s/</&lt;/g; s/>/&gt;/g; s/"/&quot;/g;   $_; } print qq{<INPUT type="hidden" name="a" value="}, chr2ref("X'mas"), qq{">\n};

KODAMAR
質問者

お礼

回答ありがとうございます。 実際の書込みはcgiによるデータの送受信で行っているのですが、 その場合も chr2ref("$FORM{'hogehoge'}")・・ のようにしてしまってもOKなのでしょうか? またダブルクォーテーションを使用したかったのですが、cgi内では"は使用できませんよね?それで安易に'を使用してしまったのですが…。

関連するQ&A