Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@algo13

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

現象

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

関連

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
5
Help us understand the problem. What are the problem?