Hatena::ブログ(Diary)

仮メモ

2017-11-11

[][]parse_url()の結果が壊れる

parse_url()で日本語URL(IRI状態)を渡すと壊れる。具体的には全角空白が別のUTF-8として無効な文字列になった。(PHP7.1)

調べてみるとphp_replace_controlchars_ex()でiscntrl()を呼び出し、コントロール文字を'_'に置換している。

日本語のWindows環境ではASCIIの\x00-\x1f, \x7fだけでなく\x80も対象になるため、UTF-8の全角空白(U+3000 = \xe3\x80\x80)が壊れたようだ。

バグ報告も昔からされているUNIX系環境のen_US.UTF8で普段作業するせいか知らなかった。回避するにはlocaleを無難なものに設定すればよい。

普通のウェブプログラムではlocale依存の処理はOSに任せずに文字コード系もmbstringのUTF-8一択なので、余計な作用が出ないほうが望ましい。

そこで冒頭で

<?php
setlocale(LC_ALL, 'C');

とした。限定的ならばLC_CTYPEのみを一時的に変更する。

<?php
$oldLocale = setlocale(LC_CTYPE, 0); // Japanese_Japan.932
setlocale(LC_CTYPE, 'C');
parse_url(...);
setlocale(LC_CTYPE, $oldLocale);

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/const/20171111/p1