Help us understand the problem. What is going on with this article?

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

More than 3 years have 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: */

関連

algo13
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした