Windows
0x5C
ダメ文字
5c問題
PHP7.1

Windows版 PHP 7.1 で日本語パス(パス文字列のエンコーディング)が対応されることによる影響

More than 1 year has passed since last update.


現象

#1854 Fixed the UTF-8 and long path support in the streams on Windows. が PHP 7.1.0 Alpha 2 に マージ されました。


  1. 最大パス長が2048バイトになりました。

  2. 今まで、 get_file_contents の引数などのパス文字列のエンコーディングは、日本語版Windowsの場合、 CP932 でしたが、これが、INIディレクティブ(internal_encoding, default_charset, zend.multibyte) に依存するようになりました。(RFC)

  3. コンソールのコードページがやんわり対応されました。

(※ PHP 7.1 UPGRADE NOTES の 12. Windows Support も参照)

この対応により、間接的に日本語パス(0x5c問題)が解決されますが、既存のPHPソースコードにて、パス文字列のエンコーディングを操作していたり、0x5cをエスケープしていた場合は、 個別に修正が必要です。


対策(及び確認項目)


対策方針候補


  1. 設定もアプリケーションも全て UTF-8 にする(推奨)

  2. php.ini の default_charsetCP932 にする。(影響範囲に注意)

  3. 個別に ini_set('default_charset', 'CP932'); (コンソール出力が乱れる可能性あり)

  4. 個別に mb_convert_encoding('日本語.txt', 'UTF-8', 'CP932') (緊急応急処置として)

※ 基本的に 1. で対応(したい)。大量のPHPソースコードを Shift_JIS(CP932) にしていた場合など、 他も検討。


影響のありそうなケース(既存のPHPソースコードのチェック対象)

Case 2 以降の例では、file_get_contents の引数のみですが、 fopen, file などパス文字列に関連する全ての処理がチェック対象です。


Case 1: コンソール出力時に文字コードを変換している場合

<?php

if (PHP_OS === 'WIN32' || PHP_OS === 'WINNT') {
ob_start(function($buffer) {
return mb_convert_encoding($buffer, 'CP932', 'UTF-8');
});
}
echo '日本語';
/* vim:set fenc=utf8 ff=unix: */

ソースコードがUTF-8の場合、 ob_start ごと不要。PHP5も対応しときたい場合は以下

<?php

if (((PHP_OS === 'WIN32') || (PHP_OS === 'WINNT'))
&& (version_compare(PHP_VERSION, '7.1.0') < 0)
) {
ob_start(function($buffer) {
return mb_convert_encoding($buffer, 'CP932', 'UTF-8');
});
}
echo '日本語';
/* vim:set fenc=utf8 ff=unix: */


Case 2: パスの文字列のエンコーディングを変更していた場合。

<?php

echo file_get_contents(mb_convert_encoding('日本語.txt', 'CP932', 'UTF-8'));
/* vim:set fenc=utf8 ff=unix: */

以下のようにエンコーディング変更ロジックを削除。

<?php

echo file_get_contents('日本語.txt');
/* vim:set fenc=utf8 ff=unix: */


Case 3: パスの文字列の 0x5c をエスケープしていた場合。

<?php

echo file_get_contents(mb_convert_encoding('表\.txt', 'CP932', 'UTF-8'));
echo file_get_contents(addcslashes(mb_convert_encoding('表.txt', 'CP932', 'UTF-8'), '\\'));
/* vim:set fenc=utf8 ff=unix: */

このエスケープ処理も削除。

<?php

echo file_get_contents('表.txt');
echo file_get_contents('表.txt');
/* vim:set fenc=utf8 ff=unix: */


関連