Laravelにおける空文字の扱いブログLaravelにおける空文字の扱いLaravelでは5.4以降、リクエスト内の空文字をnullに変換するようになりました。5.3でとあるシステムの開発を行っており、開発途中で新にリリースされた5.4に更新したところ、このnull化のあたりでハマりました。空文字のnull変換はConvertEmptyStringsToNullミドルウェアで処理しています。5.4からこのミドルウェアが登録されたため、空文字がnullに変換されるようになりました。このため、app/Http/Kernel.phpの$middlewareからConvertEmptyStringsToNullを削除してしまえば、元の動作に戻すことはできます。当時、ConvertEmptyStringsToNullを削除してしまおうとも考えたのですが、Laravelがそのような作り変更したのであれば、それに則った作りにした方がいいと判断し、ConvertEmptyStringsToNullはそのままにしてアプリケーション側を修正することにしました。空文字がnullに変換されるようになったことで、多くの場合、以下の問題が発生することになると思います。データベースへの保存時フォーム上のテキストボックス等の入力を省略した時に、従来はデータベースに空文字を設定していましたが、NULLを設定しようとします。NULL属性だと保存時にエラーとなります。このため、値が存在しない時にNULL値を格納するのが適切なカラムであればNULLを受け付けるカラムに変更したり、そうでなければリクエスト内のnull値を空文字に戻す処理が必要になります。私は各フォームのフォームリクエストクラス内で、入力がなかった時のデフォルト値を定義するようにし、入力が省略された項目に対してデフォルト値を設定してからデータベースに保存するようにしています(実装の詳細は省きますが)。省略可能項目のバリデーションルール指定5.4以前では例えば数字を受け付ける必須項目の場合は'required|numeric'のようにルールを指定し、省略可能項目の場合は'numeric'のように'required'を省略した形で指定していました。'numeric'しかし、5.4以降では'numeric'の指定だと入力を省略した時に「nullはnumericでない」と判断されてエラーとなってしまいます。5.4以降では省略可能項目には以下のように'nullable'を指定する必要があります。'numeric'だとnullがnumericでないと判断されエラーになるこれはバリデーション時、入力値が空文字の場合、「入力が省略された」とみなしrules(上の例1では'numeric')を適用しないのですが、入力値がnullだと「nullが入力された」とみなし'numeric'ルールを適用してしまうためです(詳細は*1参照)。このため、入力を省略してもバリデーションが実行されエラーになってしまいます。これを防ぐため、省略可能項目ではnullableを指定しておく必要があります。ConvertEmptyStringsToNullに関連して発生した問題は以上です。システム内の全てのフォームで見直しが必要になるので、運用中のシステムを5.4以降にアップグレードする場合は、ConvertEmptyStringsToNullを削除してしまう方が安全かもしれません。ConvertEmptyStringsToNullの追加に関しては結構インパクトのある変更だと思うのですが、https://readouble.com/laravel/5.4/ja/upgrade.htmlの5.4へのアップグレードガイドにはなぜか記述がありません。当時、nullの扱いに悩んだのでその時のまとめでした。このあたりのrulesを適用するしないの制御はvendor/laravel/framework/src/Illuminate/Validation/Validator.phpのpresentOrRuleIsImplicit()で行っています。入力が空文字だった場合、$implicitRulesに指定されているruleのみ実行し、その他は無視するようになっています。];$implicitRulesにはrequred系のルールが並んでいるので、空文字が入力された場合、入力の必須チェックだけが実行されることになります。このため、空文字の場合、'required'での必須チェックは行われるが'numeric'によるチェックは行われません。nullの場合、通常の入力として扱われるので、'numeric'のチェックが必ず行われます。このため、'nullable'がない'とnumeric'でエラーになります。省略可能項目に対するnullable指定についてはhttps://readouble.com/laravel/5.4/ja/validation.html#a-note-on-optional-fieldsにも説明があります。LTSで確認しています。(1)技術的な情報は以下にもあります。