[PHP]アップロードでPOST項目の文字化け発生(enctype=”multipart/form-data”)

PHP

ファイルアップロードしているフォームで文字化けが発生しました!
処理としてはFormDataを新規に作って、jqueryからajaxでpostしています。
前回のこれ↓みたいな感じで、作ってるフォームですね。
ドラッグ&ドロップでマルチファイルアップロードまとめ

原因

ローカルでは指定してなかったphp.iniの設定が、テスト環境は設定されていました。
mbstringの箇所がこんな感じに・・・・
ローカルでは何も指定していなかったのに、テスト環境では(ry
何のためのdockerかと・・・

調べてみるとmbstring.encoding_translation, mbstring.http_inputの設定値がよくない感じでした。

[mbstring]
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.http_input = auto
mbstring.http_output = UTF-8
mbstring.encoding_translation = On

解決策1

mbstring.encoding_translation = Onになっているところをmbstring.encoding_translation = Offにするか
mbstring.http_input = autoになっているところをmbstring.http_input = passにすれば解決します。

mbstring.encoding_translation の設定項目っていうのが、公式にも書いていますが

入力される HTTP クエリに関して、 文字エンコーディング検出および内部文字エンコーディングへの変換を行う 透過的な文字エンコーディングフィルタを有効にします。

となっているので、javascriptからpostされた文字コードが自動的に変換されて化けてたのかと思います。
javascriptはutf-16っていうのをどこかでみたので、それがutf-8に無理やり変更されて化けていたのかと・・・

mbstring.http_input のほうは

HTTP 入力文字エンコーディングのデフォルト値を定義します。

となっていて、passにすると入力した文字コードでそのまま行くみたいですが、autoになっていたので、utf-16=>utf-8で化けていたぽいです?🤔

解決策2

php.iniは影響が大きい。と言われ(たしかに・・)
それ以外の解決策をプログラムのほうで考えて、実装してみました。

文字化けするなら化けない形にしたらいいじゃない(笑)

javascriptでencodeURIComponentを使って、URLエンコードして、
phpの受け側でurldecodeを使用して、URLデコードして使うとよさげでした。

ソースとしてはこんな感じですね。

js

let form_data = new FormData($('#foo').get(0));
// ajaxにdataとして渡す前に、それぞれurlencode
form_data.set("info1", encodeURIComponent($("#info1").val()));
form_data.set("info2", encodeURIComponent($("#info2").val()));
form_data.set("info3", encodeURIComponent($("#info3").val()));

php

// decodeして使う
$info1 = urldecode($_POST["info1"]);
$info2 = urldecode($_POST["info2"]);
$info3 = urldecode($_POST["info3"]);

まとめ

mbstring.http_input は既に非推奨なので使わないでほしい!
本来はphp.iniをさっと直せばOK。

では。

コメント

タイトルとURLをコピーしました