電子書籍の厳選無料作品が豊富!

原則からはずれるのですが、htmlspecialcharsをあえて、mysqlに登録する前に使えませんか?
例えば1000行10カラムを表示する場合、1万回もhtmlspecialcharsを使わなくてはいけないので、何とか軽く処理できないかと思いました

そこでhtmlspecialcharsを使って変換してからmysqlに登録したいのです
変換した文字がmysqlに不具合を与えることはありますか?

&
"
'
<
>

A 回答 (4件)

DBに何かを突っ込む時は、最低限の正規化を行う以外はなるべく元のデータのまま入れるようにし、変換は出力の直前に行うようにします。



「原則からはずれる」と書かれてますので、この辺りご存知の上での質問だと思いますが、もし「なぜそうするのか?」という部分が納得いくレベルで理解できていない場合は、下記をご参考ください。


例えば、改行とHTMLタグの混ざったデータがあるとします。

<h1>sample</h1>
<は<span>&lt;</span>と書きます

htmlspecialchars() を通すと↓のようになり、これをDBに入れたとします。

&lt;h1&gt;sample&lt;/h1&gt;
&lt;は&lt;span&gt;&amp;lt;&lt;/span&gt;と書きます

【例1】HTMLとして出力したい
「htmlspecialchars_decode() を通し改行を<br>に変換する」という処理が必要になります。

【例2】<h1>を含むデータを検索したい
単純に htmlspecialchars() を通して <h1> ⇒ &lt;h1&gt; にして検索するだけでは、例えば「&lt;」での検索結果がおかしくなりますので、処理がやや煩雑になります。

【例3】phpMyAdmin等から簡単に中身を確認したい
パッと見では何が入っているのかよく分かりません(笑)


このように、データに対する「汎用性」が失われてしまうので、「最低限の正規化を行う以外はなるべく元のデータのまま入れるようにし、変換は出力の直前に行うようにする」わけです。

そういった事まで「理解した上で」あえて htmlspecialchars() を通してからDBに入れるという設計にしたいのであれば、好きにすれば良いです。


> 変換した文字がmysqlに不具合を与えることはありますか?

DBにデータを入れる際に適切な処理(プリペアドステートメントを使う or 特殊文字のエスケープを行う)が行われているのであれば、どのような文字列であっても、DBにデータを入れる事自体には問題ありません。


> 例えば1000行10カラムを表示する場合、1万回もhtmlspecialcharsを使わなくてはいけないので、何とか軽く処理できないか

DBに格納する処理よりも出力する処理が呼ばれる回数の方が圧倒的に多くなりますから、DBに突っ込んだデータをそのまま出力する事を想定しているのであれば、決して間違った発想ではありませんが、例えば…

$html = '';
while ($row = $stmt->fetch()) {
$html .= $row['foo'];
}
$html = htmlspecialchars($html);

…のようにすれば1回で済みますよね。始めから「1万回htmlspecialchars() 呼ばなければいけない」と決めつけるのではなく、柔軟な発想が必要です。


更に究極を言えば、PHPを通してHTMLを出力するよりも、静的なHTMLを出力した方が処理速度は圧倒的に速いです。

即ち、htmlspecialchars() 等を通し更にHTMLとして加工した結果をHTMLファイルとして保存し、出力はDBを通さずにそのHTMLファイルを出力するようにするのが最速です。
    • good
    • 0
この回答へのお礼

お答え頂きありがとうございます
>のようにすれば1回で済みますよね。
頭固かったです!すいません
>HTMLを出力
やってみます。ありがとうございました(_ _

お礼日時:2013/06/07 12:00

私も#2さん同様に、どうしてもやりたいならやれば?という感じです。


少なくとも、
>変換した文字がmysqlに不具合を与えることはありますか?
というのは杞憂です。
変換したからと言って、それが理由でmysqlに不具合を与えることはありません。

#2さんと違うのは
>登録する前に処理するか、後に処理するかのレベルで
>処理は軽くならないですね
というのは違うだろうというところですかね。
登録は1度でも、表示は何千回もという事は普通にあるので…。

ま、検索性やHTML表示以外に使い難くなるという指摘は完全にその通り。
それ以外には、登録後に再編集する場合にhtmlspecialchars_decodeで元に戻す必要があるとか、$double_encode = trueを指定していた場合は正しく戻せない場合があるとか、他のシステムは変換して保存する事はほとんどないので混乱しやすい(しかも、もしミスをすれば重篤なセキュリティホールの可能性が)とデメリットは多い。

どうしても必要なら、入力値そのままと変換後の値を別々のフィールドに格納するといいかも。

仮に現在titleというフィールドがあるとして、title、encoded_titleのように分けて登録しておいて…
検索にはtitleを使って、表示にはencoded_titleを使う。
再編集の際には、htmlspecialchars_decodeを使って元に戻すのではなく、titleからデータを引っ張ってきてのような感じ。
#2さんの指摘の、データ量がちょっと増えるどころか、倍以上に増えるという事になってしまってますが。

encodedがついたフィールドは変換済みと明確なので、混乱度合いが小さく済むだろうという期待も込めて。


ちなみに、
>例えば1000行10カラムを表示する場合
これは、ユーザーが使い難いUIとなる気がするので、50行程度でページ分割するなどの方法を選ぶ方がずっといいとは思う。
    • good
    • 0
この回答へのお礼

お答え頂きありがとうございます
>というのは杞憂です。
少し安心しました
>htmlspecialchars_decodeで元に戻す
こんなことができるんですね
>登録後に再編集する場合にhtmlspecialchars_decodeで元に戻す必要がある

そうですよね。再編集のときに戻さないといけないですよね、コレについてはもう一つ選択がありました

お礼日時:2013/06/07 11:48

>mysqlに登録する前に使えませんか?



使いたければ使えばよいのでは?・・・レベルの話
ただし・・・

>何とか軽く処理できないか

登録する前に処理するか、後に処理するかのレベルで
処理は軽くならないですね
むしろ前にする方がデータは重くなるし、検索性もわるくなるし
html以外にデータ活用する際に邪魔になるしいいこと一つもないと思いますが
    • good
    • 0
この回答へのお礼

お答え頂きありがとうございます
そうですよね、検索は重くなりますよね、今回は<などの記号を使う人は1000人いたら10人くらいですので検索の重さはきにならないです

お礼日時:2013/06/07 11:38

「gt」という文字列を検索したら、「<」が検出される。

    • good
    • 0
この回答へのお礼

お答え頂きありがとうございます
今回は、<などを使う人が少ないのでこれについては大丈夫そうです

お礼日時:2013/06/07 11:36

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!