ラムネグから一言:寝る前に読むとくだらなすぎて逆に寝れると好評なすごい適当なブログをこっちではじめてます.
どうやらphp8.4以前だとtrimが全角文字に完全には対応していないため、全角スペースなどの全角文字を第2引数でtrim対象に指定すると結果が文字化けしてしまう場合があるみたいです。
キモなのが文字化けしない場合もあるので、実装時はいくらかテストして「よし!」と思っていても実際に動かしてみると文字化けしちゃうかも、という点。
今回はphpのtrim関数で全角文字を削除すると文字化けしてしまうときの解決方法を紹介しますね。
解決方法
trimを使うのをやめます。そしてpreg_splitやpreg_replaceを使って正規表現でトリムするのがおすすめ。
わたしはある文字列の両端の半角と全角のカッコを削除したかったので、preg_splitでこんな感じにしました。
$result = preg_split("/[()()]/u", $text, 0, PREG_SPLIT_NO_EMPTY)[0];
ホントはpreg_replaceの方がいいと思います、というかこの書き方があんまりよくないですよね。preg_splitの返り値は分割された文字が入った配列なんですが、その配列の0番目を名指しで指定してるんで「配列にそんな番号ないよぅ…」ていうよくみるエラーがひょんなタイミングで出そうです。
今回は遊びだったからこんな適当なコードですが、ガチのシステムの場合はもうちょっとちゃんと書かなきゃ、ですね。
「テ」と「ト」で文字化けした
もう解決方法も紹介し終わったので、ここから下は読みたい人だけ読んでみてくださいね。
今回テストではわたしも文字化けしなかったんです。trim使いやすいな!と思っていました。第2引数にtrimしたい文字入れるだけで正規表現とか小難しいコトせずに両端の処理ができちゃうなんて!と。
で、本番というか実際にそのプログラム動かしてみたら見事に文字化け…。
私の場合、trimで全角カッコを指定していて(よくtrimで指定して、んで文字化けるのは全角スペースですよね)、それだと「テ」と「ト」が文字列の最後にある時にそれぞれ文字化けるみたいでした。それ以外にもあるのかもですがとりあえず「テ」がひらがなの「て」になり、「ト」に至ってはなんかトランプのダイヤみたいな形の中にハテナマークが入ってるみたいな謎の記号に文字化けちゃいました。
文字ってパソコンの中ではなんかごちゃごちゃした数字なんですよね。なのでtrim関数さんも実際にはそのごちゃごちゃした数字から全角スペースを表す数字の一群、であるとか全角カッコを表す数字の一群、とかを必死に探し出して「あったよ!」て時にその文字をトリムしてくれてるんです。
ただ全角文字はその数字の一群が、半角文字に比べて長いのです。マルチバイト文字とか呼ばれて、1文字を表すのに半角文字の2倍くらいの数字の羅列が必要になるんです。
で、そのせいでtrim関数さんが誤判定しちゃう、と。
全角スペースの場合はわかりませんが、全角カッコの場合だとtrim関数さんが全角カッコの数字の一群、と判断した中に本当は「テ」や「ト」に一部にあたる数字が含まれちゃって、んでトリムするときにその「テ」や「ト」の一部までごっそり取り除いちゃうから、文字が変わって、人から見ると文字化けしたように見えるんですね。
まとめ
phpのtrim関数で全角文字を削除すると文字化けする、の解決方法と理由を紹介しました。
phpってけっこうマルチバイト文字の取り扱いが分かりづらいというか、こっちの関数は対応してるけどこっちは対応してないんだ、みたいなの多い気がします。
こっちは「mb_ほにゃらら」じゃないとマルチバイト文字対応じゃないのに、こっちは「mb_」ついてなくてもマルチバイト文字おっけーなんだ、ふーん、みたいなのも割とある気がします。
とりあえずtrim関数は全角文字を第2引数に指定すると文字化けする場合があるんで、違う関数を使うのがおすすめです。
【おしらせ、というか完全なる宣伝】
文体がもうぜんぜん適当すぎてあれだけどものすごい自由に書いてるブログ「檸檬だくだく」もよろしく.寝る前に読める恐ろしくくだらないやつです.
こんなにも一ミリも目を引かれないタイトルを取り扱ってます: ココア20g / ハイチュウとかってさ / なぜ米と小麦を食べようと思ったのかの謎 /