質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

zip

ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

Q&A

解決済

1回答

10916閲覧

PHPのZipArchive::statIndexで日本語画像ファイルを扱うと文字化けする

退会済みユーザー

退会済みユーザー

総合スコア0

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

zip

ZIPとは、複数のファイルをひとつにまとめて圧縮したり、圧縮したファイルを展開することができるアーカイブフォーマットです。 1998年以降のWindowsOS各バージョンで、標準の圧縮フォルダとして採用されています。 MacOSでも、X v10.3以降に他の圧縮ソフトとまとめてZIP機能を採用しています。

0グッド

0クリップ

投稿2015/05/27 03:37

編集2015/05/27 06:01

###環境
CentOS6.6
PHP5.5系
CodeIgniter2.2系

###要件
PHPにてWebフォームを作成。Zipアーカイブをフォームよりアップロードして、
中に含まれる日本語ファイル名のjpgファイルをサーバ上に展開したい。

###不具合内容
下記プログラムにてZIPを処理しています。

プログラム(必要箇所のみ抜粋)

lang

1private function extractTo($zip_src, $to_enc = 'UTF-8', $from_enc = 'CP932') 2{ 3 $zip = new ZipArchive(); 4 5 $num_files = $zip->numFiles; 6 for ($i = 0; $i < $num_files; $i++) 7 { 8 $stat = $zip->statIndex($i); 9//var_dump($stat['name'], mb_detect_encoding($stat['name'])); 10 $name = mb_convert_encoding($stat['name'], $to_enc, $from_enc); 11 } 12//exit; 13 $zip->close(); 14}

PHP標準のZipArchiveクラスのstatIndexメソッドにてZIPファイルから画像ファイルを読み込んでいるのですが、
var_dump($stat['name'], mb_detect_encoding($stat['name']));
すると、下記の出力が得られる状態です。

問題がない環境(Aとする)

lang

1string(28) "zip/???????W????.jpg" 2string(4) "SJIS" 3string(42) "zip/??????????????????????.jpg" 4string(4) "SJIS" 5string(30) "zip/???????????.jpg" 6string(4) "SJIS"

不具合の発生する環境(Bとする)

lang

1string(41) "zip/eoe„¢e?aWaaaC.jpg" 2string(5) "UTF-8" 3string(75) "zip/e„ eƒÑeƒ³e?e?e?uOe„£e„¨e?eƒ³aƒÐiÊ.jpg" 4string(5) "UTF-8" 5string(47) "zip/eƒ¶e}e?e}e„¦e!e?.jpg" 6string(5) "UTF-8"

いずれの環境もこの時点では文字化けしていますが、
直後にmb_convert_encodingすることで対処しています。

B環境にてstatIndexした時点ですでにUTF-8として読み込まれていることが、直接の原因と考えています。

###質問内容
上記の根本原因として、サーバ環境間になにかしらの差異があるもとと考えています。
こういった事象に近いご経験ある方に、その差異がどういった設定なのかということをご教示いただければと思います。
確認済みの事項とを以下に記載します。

###確認済み事項
localeコマンドの出力結果(両環境で差異なし)

lang

1LANG=ja_JP.UTF-8 2LC_CTYPE="ja_JP.UTF-8" 3LC_NUMERIC="ja_JP.UTF-8" 4LC_TIME="ja_JP.UTF-8" 5LC_COLLATE="ja_JP.UTF-8" 6LC_MONETARY="ja_JP.UTF-8" 7LC_MESSAGES="ja_JP.UTF-8" 8LC_PAPER="ja_JP.UTF-8" 9LC_NAME="ja_JP.UTF-8" 10LC_ADDRESS="ja_JP.UTF-8" 11LC_TELEPHONE="ja_JP.UTF-8" 12LC_MEASUREMENT="ja_JP.UTF-8" 13LC_IDENTIFICATION="ja_JP.UTF-8" 14LC_ALL=

参考記事にあるとおり、PHP標準の関数、クラスはOSのロケール設定が影響してくる場合があるとのことでしたので、ロケール設定を確認しましたが、いずれの環境でも差異はありませんでした。

長文となりましたが、
どうぞよろしくお願いいたします。

追加情報①php.iniの差分

lang

1< ; The syntax of the file is extremely simple. Whitespace and Lines 2--- 3> ; The syntax of the file is extremely simple. Whitespace and lines 485a86,87 5> ; This is php.ini-production INI file. 6> 7139,148d140 8< ; session.bug_compat_42 9< ; Default Value: On 10< ; Development Value: On 11< ; Production Value: Off 12< 13< ; session.bug_compat_warn 14< ; Default Value: On 15< ; Development Value: On 16< ; Production Value: Off 17< 18200,206c192,197 19< ; <? and ?> tags as PHP source which should be processed as such. It's been 20< ; recommended for several years that you not use the short tag "short cut" and 21< ; instead to use the full <?php and ?> tag combination. With the wide spread use 22< ; of XML and use of these tags by other languages, the server can become easily 23< ; confused and end up parsing the wrong code in the wrong context. But because 24< ; this short cut has been a feature for such a long time, it's currently still 25< ; supported for backwards compatibility, but we recommend you don't use them. 26--- 27> ; <? and ?> tags as PHP source which should be processed as such. It is 28> ; generally recommended that <?php and ?> should be used and that this feature 29> ; should be disabled, as enabling it may result in issues when generating XML 30> ; documents, however this remains supported for backward compatibility reasons. 31> ; Note that this directive does not control the <?= shorthand tag, which can be 32> ; used regardless of this directive. 33375c366 34< expose_php = On 35--- 36> expose_php = Off 37427c418 38< ; E_ALL - All errors and warnings (includes E_STRICT as of PHP 6.0.0) 39--- 40> ; E_ALL - All errors and warnings (includes E_STRICT as of PHP 5.4.0) 41585c576 42< ; Log errors to syslog (Event Log on NT, not valid in Windows 95). 43--- 44> ; Log errors to syslog (Event Log on Windows). 45731a723,726 46> ; Directory where the temporary files should be placed. 47> ; Defaults to the system default (see sys_get_temp_dir) 48> ; sys_temp_dir = "/tmp" 49> 50754c749 51< ;cgi.redirect_status_env = ; 52--- 53> ;cgi.redirect_status_env = 54771c766 55< ;fastcgi.impersonate = 1; 56--- 57> ;fastcgi.impersonate = 1 58800d794 59< ;upload_max_filesize = 2M 60958,967d951 61< ; For Win32 only. 62< ; http://php.net/smtp 63< SMTP = localhost 64< ; http://php.net/smtp-port 65< smtp_port = 25 66< 67< ; For Win32 only. 68< ; http://php.net/sendmail-from 69< ;sendmail_from = me@example.com 70< 71982a967,968 72> ; Log mail to syslog (Event Log on Windows). 73> ;mail.log = syslog 741354c1340,1352 75< session.save_path = "/var/lib/php/session" 76--- 77> 78> ; RPM note : session directory must be owned by process owner 79> ; for mod_php, see /etc/httpd/conf.d/php.conf 80> ; for php-fpm, see /etc/php-fpm.d/*conf 81> ;session.save_path = "/tmp" 82> 83> ; Whether to use strict session mode. 84> ; Strict session mode does not accept uninitialized session ID and regenerate 85> ; session ID if browser sends uninitialized session ID. Strict mode protects 86> ; applications from session fixation via session adoption vulnerability. It is 87> ; disabled by default for maximum compatibility, but enabling it is encouraged. 88> ; https://wiki.php.net/rfc/strict_sessions 89> session.use_strict_mode = 0 901435,1460c1433 91< ; find /path/to/sessions -cmin +24 | xargs rm 92< 93< ; PHP 4.2 and less have an undocumented feature/bug that allows you to 94< ; to initialize a session variable in the global scope. 95< ; PHP 4.3 and later will warn you, if this feature is used. 96< ; You can disable the feature and the warning separately. At this time, 97< ; the warning is only displayed, if bug_compat_42 is enabled. This feature 98< ; introduces some serious security problems if not handled correctly. It's 99< ; recommended that you do not use this feature on production servers. But you 100< ; should enable this on development servers and enable the warning as well. If you 101< ; do not enable the feature on development servers, you won't be warned when it's 102< ; used and debugging errors caused by this can be difficult to track down. 103< ; Default Value: On 104< ; Development Value: On 105< ; Production Value: Off 106< ; http://php.net/session.bug-compat-42 107< session.bug_compat_42 = Off 108< 109< ; This setting controls whether or not you are warned by PHP when initializing a 110< ; session value into the global space. session.bug_compat_42 must be enabled before 111< ; these warnings can be issued by PHP. See the directive above for more information. 112< ; Default Value: On 113< ; Development Value: On 114< ; Production Value: Off 115< ; http://php.net/session.bug-compat-warn 116< session.bug_compat_warn = Off 117--- 118> ; find /path/to/sessions -cmin +24 -type f | xargs rm 1191597c1570 120< mssql.compatability_mode = Off 121--- 122> mssql.compatibility_mode = Off 1231654,1678d1626 124< [COM] 125< ; path to a file containing GUIDs, IIDs or filenames of files with TypeLibs 126< ; http://php.net/com.typelib-file 127< ;com.typelib_file = 128< 129< ; allow Distributed-COM calls 130< ; http://php.net/com.allow-dcom 131< ;com.allow_dcom = true 132< 133< ; autoregister constants of a components typlib on com_load() 134< ; http://php.net/com.autoregister-typelib 135< ;com.autoregister_typelib = true 136< 137< ; register constants casesensitive 138< ; http://php.net/com.autoregister-casesensitive 139< ;com.autoregister_casesensitive = false 140< 141< ; show warnings on duplicate constant registrations 142< ; http://php.net/com.autoregister-verbose 143< ;com.autoregister_verbose = true 144< 145< ; The default character set code-page to use when passing strings to and from COM objects. 146< ; Default: system ANSI code page 147< ;com.code_page= 148< 1491688c1636 150< mbstring.internal_encoding = UTF-8 151--- 152> mbstring.internal_encoding = UTF-8 1531692c1640 154< mbstring.http_input = pass 155--- 156> mbstring.http_input = UTF-8 1571715c1663 158< mbstring.substitute_character = none; 159--- 160> mbstring.substitute_character = none 1611729c1677 162< mbstring.strict_detection = Off 163--- 164> mbstring.strict_detection = On 1651784a1733,1736 166> 167> ; RPM note : cache directory must be owned by process owner 168> ; for mod_php, see /etc/httpd/conf.d/php.conf 169> ; for php-fpm, see /etc/php-fpm.d/*conf 1701816a1769,1773 171> [curl] 172> ; A default value for the CURLOPT_CAINFO option. This is required to be an 173> ; absolute path. 174> ;curl.cainfo = 175>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KoichiSugiyama

2015/05/27 05:03

それぞれの環境のphp.iniは全く同じものを使用しているのでしょうか?
退会済みユーザー

退会済みユーザー

2015/05/27 06:02

ご指摘ありがとうございます。diffの結果を追記いたしました。mbstringディレクティブで少々差分があるようですので、合わせて検証してみます。
退会済みユーザー

退会済みユーザー

2015/05/28 01:25

B環境のphp.iniを以下のとおり修正、httpd再起動後に動作確認しましたが、変わらずでした。。 ※その後念のためA環境のphp.iniをB環境に移してみましたが、やはりダメでした。 ・mbstring.strict_detection = Off ・mbstring.http_input = pass その他現状で疑っているポイントとしましては、 ・httpd.confの差異(B環境では不要なモジュールの多くをコメントアウトしているなどの差分がございます) などあるかなあと思っています。
guest

回答1

0

ベストアンサー

php.iniの差分を見る限り「mbstring.strict_detection(文字コードの自動判別)」がONかOFFかで結果が違ってきているのではないでしょうか。

投稿2015/05/27 12:02

KoichiSugiyama

総合スコア3041

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問