wysiwygエディタで入力したhtmlをデータベースに保存するというのはよくあるケースではないかと思います。
今回は、エディタを保存するフィールドを何も考えずTEXT型にしてしまうと、不具合になるかもよ!というお話です。
ある日のテストで、登録処理を通ったのにエディタに何も出てこない不具合を発見。
- ログにエラーは吐かれていない。
- エディタを外しても現象は再現する。
- 別所で同じエディタを使っている所は通るし、中身も出る。
phpから取ったsqlを投げてみると
error 1406 - Data too long for column
指定のフィールドを見てみると途中でエディタに入力した内容が途切れていました。
よくよく見ると、中身が出たデータも途中で切れています。
根本的な原因
TEXT型の最大値の量を超えたため。
MySQL 5.6 リファレンスマニュアルには
最大長が 65,535 (216 − 1) 文字の TEXT カラム。値にマルチバイト文字が含まれる場合、有効な最大長は少なくなります。各 TEXT 値は、値のバイト数を示す 2 バイト長のプリフィクスを使用して格納されます。
とあるので、日本語だと4万文字もあればキャパオーバーしそうです。
なぜ真っ白に?
入っているデータの出だしは以下の通り。
[{"craft":"<p>boss<\/p>\r\n","~
json_encodeされていますね。
途中で途切れた結果、閉じ括弧がなくjson_decodeが出来なかったのでしょう。
なぜ正常に通ってしまったのか
SQLを抽出してMySQLで投げると通らないパターンがちょいちょいあります。大体NULL関係と文字長さで引っかかるんですが。。。
フレームワークによるものなのか何なのか、詳しい方是非ご教授お願いいたします。
対策
きちんと使用目的に合った型を宣言する事。
今回はどれだけの長さになるか想定できないので対象のフィールドをLONGTEXT型とし解決しました。
それだけでなくquery長(SQL文の文字数)にも制限があるので注意。
詳しくはmax_allowed_packet
などで検索検索ゥ!
最大文字数に合わせて各input項目にバリデーションがあると尚良いかなと思います!
決してTEXT型に限ったお話でもないので、皆様もサイレント文字数カットによる不具合にお気をつけ下さい。