質問するログイン新規登録
PHP

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

Q&A

解決済

2回答

1024閲覧

日本語ファイル名の変換後の文字化けについての質問

TaisukeWada

総合スコア11

PHP

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

0グッド

0クリップ

投稿2023/08/15 09:11

編集2023/08/15 09:42

0

0

事情によりファイル名(日本語)の文字コードをUTF-8からSIS-WINに文字変換して処理をし再度ファイル名をSIS-WINからUTF-8に変換するプログラムを作成しております。
しかしながら、こちらPHP5.3では作動したにも関わずPHP8.2では文字化けを起こしてしまい、UTF-8の文字コードに戻らず困っております。

<?php header('Content-Type: text/html; charset=UTF-8'); $word = "./これはテスト.jpg"; $word2 = mb_convert_encoding($word, 'sjis-win','UTF-8'); echo "$word2<br>"; $word3 = mb_convert_encoding($word2, 'UTF-8','sjis-win'); echo "$word3<br><br>"; $zip = new ZipArchive; $zipFilePath = './sample.zip'; $extractPath = './inprocess/sample/'; $fileToAdd = './これはテスト.jpg'; // Zipファイルをオープン if ($zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) { // ファイルをZipアーカイブに追加 $zip->addFile($fileToAdd, mb_convert_encoding(basename($fileToAdd), 'sjis-win','UTF-8')); //$zip->addFile($fileToAdd, basename($fileToAdd)); // 展開先ディレクトリが存在しない場合は作成 if (!is_dir($extractPath)) { mkdir($extractPath, 0777, true); } // Zipファイル内のファイルを展開 $zip->extractTo($extractPath); for ($i = 0; $i < $zip->numFiles; $i++) { $filename = $zip->getNameIndex($i); echo " $filename<br>"; $filename2 = mb_convert_encoding($filename, 'UTF-8', 'sjis-win'); echo "$filename2<br>"; $zip->extractTo($extractPath, $filename); } $zip->close(); echo 'ファイルが正常に追加され、展開されました。'; } else { echo 'ファイルのオープンに失敗しました。'; } ?>

結果としては

./����̓e�X�g.jpg
./これはテスト.jpg

é▒éΩé═âeâXâg.jpg
テゥ笆津ゥホゥテゥ笊静「eテ「Xテ「g.jpg
ファイルが正常に追加され、展開されました。

と出て、プログラム上に記述した文字だと文字化けしないのですが、サーバに実在する日本語のファイルを読み込むと文字化けを起こしてしまいます。
これは何かサーバ自体の環境の問題なのでしょうか?
初歩的な質問で大変に申し訳ございませんが、何卒宜しくお願い申し上げます。

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

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

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

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

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

yambejp

2023/08/15 09:14

ソースがくずれていますので正しくマークダウンしてください
TaisukeWada

2023/08/15 09:23

ご指摘ありがとうございます。文章を修正いたしました。
ikedas

2023/08/15 09:30

ソースコードは https://teratail.com/help#about-markdown ここに書いてある「コードを入力」のやりかたで書いてください。
TaisukeWada

2023/08/15 09:42

再度修正いたしました。ありがとうございます。
otn

2023/08/15 10:18

> サーバに実在する日本語のファイルを読み込むと文字化けを起こしてしまいます。 これは、質問文に掲載したプログラムとは異なるプログラムの話ですか?であればそれも掲載しましょう。
guest

回答2

0

ベストアンサー

プログラム上に記述した文字だと文字化けしないのですが、サーバに実在する日本語のファイルを読み込むと文字化けを起こしてしまいます。

の意味が不明でしたが、プログラムを見ると、文字列を直接変換すると問題ないが、zipファイルに格納して取り出すと文字が化けるという事ですね。

サーバーに実在するとかは関係なくて、ZipArchiveライブラリーの問題です。
取り出し時にエントリー名を勝手にエンコーディング変換するようですね。
知りませんでしたが、ググって知った。

PHP

1$filename = $zip->getNameIndex($i, ZipArchive::FL_ENC_RAW);

にすれば、勝手な変換を回避して格納したまま(SJISのまま)取り出せるようです。

おそらく古いバージョンだと勝手な変換が無かったのですかね。

投稿2023/08/15 13:03

otn

総合スコア86380

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

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

TaisukeWada

2023/08/16 00:34

こちらありがとうございます。こちらで解決いたしました。「ベストアンサー」をotnさんに付けさせていただきたかったのですが、操作を間違え違う方に付けてしまいました。大変に申し訳なく現在、修正できるか調べております。
guest

0

【間違っている部分を取り消しています】

2 header('Content-Type: text/html; charset=UTF-8');

最初にこのヘッダを送信しているため、ウェブブラウザでは、これから受け取る内容はすべてUTF-8で符号化されているという前提で画面表示を行います。逆に言うと、今後はUTF-8で符号化されていないものを出力するとすべて文字化けします。

4 $word = "./これはテスト.jpg"; 5 $word2 = mb_convert_encoding($word, 'sjis-win','UTF-8'); 6 echo "$word2<br>";

ソースコードはUTF-8で符号化されているはずですから、$wordに代入されたファイル名もUTF-8で符号化されています。

したがって、$word2は正しくsjis-winで符号化された文字列に変換されるため、それをそのまま出力すると上の説明の通り文字化けします。

7 $word3 = mb_convert_encoding($word2, 'UTF-8','sjis-win'); 8 echo "$word3<br><br>";

正しくsjis-winに変換されたものをUTF-8に変換してから出力しているので、正しく表示されます。

18 // ファイルをZipアーカイブに追加 19 $zip->addFile($fileToAdd, mb_convert_encoding(basename($fileToAdd), 'sjis-win','UTF-8'))

ファイルシステムから取り出したファイル名はsjis-winで符号化されていると思われます。しかし、ここではそれをUTF-8で符号化されているつもりでさらにsjis-winに変換しようとしています。つまり、 正しく変換できません。

31 $filename = $zip->getNameIndex($i); 32 echo " $filename<br>";

上の19行目で正しく変換できていないので、sjis-winでもUTF-8でもない奇怪なものが表示されます。

33 $filename2 = mb_convert_encoding($filename, 'UTF-8', 'sjis-win'); 34 echo "$filename2<br>";

sjis-winで符号化されているつもりでUTF-8に変換しています。上の2行目で出力はUTF-8で符号化されているとブラウザに伝えていますから、正しく変換されれば文字化けしないはずです。しかし、上の19行目で正しくsjis-winに変換できていないものをUTF-8に変換しようとしているので、意味のある表示になっていません。

投稿2023/08/15 10:55

編集2023/08/15 23:21
ikedas

総合スコア4441

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

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

otn

2023/08/16 00:21

Tarsanさん、 「SJISの(はずの)ファイル名をUTF-8変換しても元に戻らない」というのが質問ポイントかと思っていたのですが、 「ウェブ画面上で化ける」が質問ポイントだったのでしょうか?
TaisukeWada

2023/08/16 00:29

こちら、説明を汲み取ってくださり、ありがとうございました。正にotnさんの回答いただいたので解決いたしました。先ほど、間違えた方にベストアンサーを付けてしまいました。今、訂正できるか検索中です。
ikedas

2023/08/16 00:32

otnさん 私はソースを見てHTTP経由で結果を確認していると思ったのですが、コンソール上の出力で確認している可能性もありますね (その場合はコンソールのコードセットがUTF-8であればUTF-8のテキストは化けない)。 どちらにしろ、正しくUTF-8に変換できているかが主眼なので、そこは質問のポイントではないでしょう。
TaisukeWada

2023/08/16 00:39

ikedasさん こちら、アドバイスありがとうございました。 $filename = $zip->getNameIndex($i, ZipArchive::FL_ENC_RAW); としてみましたら、解決いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問