4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-10-28

現象

#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: */

関連

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?