CSV表示で文字化け - PHPプロ!Q&A掲示板

412

  • 0P

CSV表示で文字化け

質問日時 / 2007年3月14日 12:54 (最終編集:3月14日 12:57)    回答数 / 9件

Questioner:  PHPGANBA  このエントリーをはてなブックマークに追加 

キーワード / CSV表示    文字化け   

以前Pascalさんに助けていただき、CSVデーターを検索、表示
するプログラムを作成しました。
テストしますと任意の検索キーの結果が文字化けしてしまいます。
文字化けの時のキーは一定で、漢字の時も半角数字の時もおこります。
文字化けは日本語で半数英数字は化けません。

文字コードは shift_jis です。
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis"> 
<style type="text/css">

テスト環境はXAMPPでローカルPCで実施してます。

ご教授お願いします。


------------キー検索部--------------


<?php  
// 読み込むCSVファイル  
$csvfile = "CSDATA.csv";  
// CSVファイルの1行の最大サイズ  
$linesize = 4096;  
   
// 念のため変数を初期化  
$printdata = ""; 
   
// 検索キーワードを設定  
$keyword['kaishamei'] = ""; 
$keyword['tantou'] = ""; 
$keyword['shimei'] = ""; 
  
// GETで渡された値をカテゴリの検索キーワードとしてセット 
$keyword['kaishamei'] = $_GET["keyword"]; 
$keyword['tantou'] =  $_GET["keyword"];
$keyword['shimei'] = $_GET["keyword"];
 
// CSVファイルを開く  
$fh = fopen ($csvfile, "r");  
// 開けなかったら終了  
if (!$fh) {  
  exit;  
}  
   
// 1行目の見出し部分を読み込み  
if (!feof ($fh) ) {  
  $line = fgets ($fh, $linesize);  
  list ($head['kaishamei'], $head['tantou'], $head['shimei']) = explode (",", $line); 
  // 1行目の見出し行を表示用変数にセット 
  $printdata = $line; 
}  

// 2行目以降を読み込み  
while (!feof ($fh)) {  
  // 見つかったかどうかのフラグを初期化  
//  $found['kaishamei'] = false;  
  $found['tantou'] = false;
  $found['shimei'] = false;
 
  // 1行読み込み  
  $line = fgets($fh, $linesize);  
  // 読み込んだデータを「,」区切りで分割して変数に入れる  
  list ($kaishamei, $tantou, $shimei) = explode (",", $line);  
   
  // 検索ワードに一致するか確認  
  if (strlen ($keyword['kaishamei'])) { 
    $found['kaishamei'] = mb_strpos ($kaishamei, $keyword['kaishamei']); 
  } 
  if (strlen ($keyword['tantou'])) {  
    $found['tantou'] = mb_strpos ($tantou ,$keyword['tantou']);  
  }  
  if (strlen ($keyword['shimei'])) { 
    $found['shimei'] = mb_strpos ($shimei, $keyword['shimei']); 
  } 
  
  // カテゴリーに一致したら、その行を表示用変数にセット 
  if ($found['kaishamei'] !== false or $found['tantou'] !== false or $found['shimei'] !== false)
 {
    $printdata .= $line; 
  }
  
}
// ファイルを閉じる  
fclose ($fh);  
   
// 表示 
echo $printdata; 
?> 

-------------表示部--------------
-----------検索キー入力部は省略---------

</head> 
<body> 
  
<TABLE DATASRC=#CSVFILE > 
  <THEAD>   
    <TR ID="HEADER"> 
      <TH>会社名 
      <TH>担当部 
      <TH>氏名 
    </TR> 
  </THEAD>   
  
  <TBODY> 
    <TR> 
      <TD><SPAN DATAFLD=KAISHA></SPAN></TD> 
      <TD><SPAN DATAFLD=BUMON></SPAN></TD> 
      <TD><SPAN DATAFLD=SHIMEI></SPAN></TD> 
    </TR> 
</TBODY> 
</TABLE> 
</body> 
</html>

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┣A01imimiそれはソースがShift-JISで書かれているとか、 IEの
┗A02pascal文字化けするのは、例えば「表」とか「能」の場合では
 ┗A02-1PHPGANBAPascalさんありがとうございます。 3/16 13:00 ma
  ┗A02-1-1pascalmagic_quotes_gpc は、php.ini での設定になります。
   ┗A02-1-1-1PHPGANBA縄文人です。 しばらく別の仕事で対応できませんでし
    ┗A02-1-1-1-1pascalまず、文字エンコーディングは全て「Shift_JIS」に統
     ┗A02-1-1-1-1-1PHPGANBAプログラムの後に調査の結果を追記しました。 ----
      ┗A02-1-1-1-1-1-1pascal試してみましたが、こちらの環境では現象は再現しませ
       ┗A02-1-1-1-1-1-1-1PHPGANBA文字化けした場合ですが、読み込んだCSVの内容のみが

回答一覧

並び替え:

A01
answererimimi [3月14日 14:11]

それはソースがShift-JISで書かれているとか、
IEの表示→エンコードが間違っているからじゃないですか?

この意見に回答する

ツリーへ TOPへ

A02
answererpascal [3月14日 14:34]

文字化けするのは、例えば「表」とか「能」の場合ではないですか?
そして、magic_quotes_gpc が「オン」になっていませんか?

「表」の場合ですが、magic_quotes_gpc が「オン」の場合、本来「%95%5C」となるべきところ、「%95%5C%5C」と「%5C」が勝手に追加されてしまいます。
これを防ぐには magic_quotes_gpc を「オフ」にするか、get_magic_quotes_gpc でオンかオフかを確認し、オンの場合は stripslashes で勝手に追加された「%5C」を削除する必要があります。


あとついでに、全てShift_JISで統一するのであれば念のために
  1. mb_internal_encoding('SJIS');
とやっておいた方が安全だと思います。

マニュアルで mb_????(例:mb_strpos)を見るとわかりますが、文字エンコーディングを省略した場合、内部文字エンコーディングが使われます。

この意見に回答する

ツリーへ TOPへ

A02-1
replyerPHPGANBA [3月16日 14:46] (最終編集:3月16日 16:14)

Pascalさんありがとうございます。
3/16 13:00    magic_quotes_gpc はシステムの設定でしょうか?
まだ慣れて無いので良くわかってません。
(PHP.INIのハンドリング方法が良くわからない)
3/16 16:00 PHP.INIの場所は発見しました。
magic_quotes_gpcがONになってるのを確認
OFFして上書きで良いのでしょうか?
疑問は、上記のご回答を色々Webで見てみましたが、GET PUTに関する文字化けの問題の様に見えました。
私の問題は読み出したCSVがブラウザに表示されるときに文字化けするのですが、回答としては今回の対策を行うのですね。
検索キーはCSVデーターとマッチングはされてる様で、検索キーに掛かったCSVデーターが表示の時文字化けします。

Shift_JISはあまり良くないと他のページにも書いてましたのでEUC-JPを指定してみましたらもっと悪くなりました。
Shift_JIS以外の文字コード指定はどの様にするのでしょうか?
う~~んっ!

この意見に回答する

ツリーへ TOPへ

A02-1-1
replyerpascal [3月16日 18:12]

magic_quotes_gpc は、php.ini での設定になります。
設定が ON になっているとのことですので、OFFにすれば大丈夫と思われます。
また、ON のままでも以下のようにして確認・対応すれば問題ありません。
  1. <?php
  2. $test = $_POST['test'];
  3. if ( get_magic_quotes_gpc() ) {
  4.   $test = stripslashes ( $test );
  5. }
  6. ?>

EUC-JP にして文字化けしたとのことですが、その際に全てのファイル(PHP、html、CSV)を EUC-JP にしましたか?
もしくは、mb_convert_encoding で EUC-JP に変換しましたか?
例えば、CSV だけ Shift_JIS で、mb_convert_encoding による変換もされていない場合、EUC-JP で書かれた html の中に Shift_JIS のデータが入るので、当然文字化けします。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1
replyerPHPGANBA [3月26日 15:16]

縄文人です。 しばらく別の仕事で対応できませんでした。
magic_quotes_gpc を Offにしましたが現象は変わりませんでした。
htmlにはリストの様にShift_JIS構文が入ってますがPHPには記述されてません。又、EUC-JPの文字化けの時にCSVがEUC-JPに成ってますかとの注意ですがCSVをShift_JIS(あるいはEUC-JP)にするとはどの様に行うのでしょうか?
検索文字列を頭一文字にすると文字化けしないなど、原因は検索文字列の取り込みに原因がありそうですが、文字化けのデーターが検索対象のデーター数と一致してるので検索自体は上手く出来ていて、表示のみ文字化けかもしれない様な気もします。
混乱してます
すみません!

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1
replyerpascal [3月26日 15:48]

まず、文字エンコーディングは全て「Shift_JIS」に統一してください。
(おそらく、現状でもShift_JISでしょう。)

とりあえず、「メモ帳」で開いて文字化けしなければ「Shift_JIS」と思われます。
また、CSVが「Shift_JIS」以外ということはほぼないと思います。
(Excelで作れば普通は「Shift_JIS」です。)


文字化けについてですが、具体的にはどのように表示されるのですか?
具体例がなければ推測でしか言えません。
サンプルプログラムを書き込んでください。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1
replyerPHPGANBA [3月27日 12:21] (最終編集:3月27日 13:15)

プログラムの後に調査の結果を追記しました。

---------------------------------------

お手数かけます。
プログラムです。

CSVは
光陽機械,1234,山田 太郎,06-XXX-XXXX,abc@xxx.co.jp
山本機械,5678,川田 次郎,03-XXX-XXXX,def@xxx.co.jp
の様な内容です。
たとえば検索で山本をヒットさせると
会社名  名前
山本機械  川田 次郎 4567 03-xxxx  
と表示されます。
しかし、光陽でヒットすると

会社名  名前
Œõ—z‹@ŠB  ・ì・‡・@‹v・Ÿ 1234 06-xxx
(上記はコピペしましたので表示状態は同じでない様に見えますが
ほぼ同じです)
になります。


------検索キー入力及びHTMLで表示----------
<html> 
<head> 
<form action="CS01.php" METHOD="GET" > 
<input type="text" name="moji" value=""> 
<input type="submit" value="検索"> 
</form>
<meta http-equiv="Content-Type" content="text/html;charset=shift_jis">
<style type="text/css"> 
  <!-- 
  TABLE {background-color:#222288; font-size:12px;} 
  TR {background-color:#ffffee; }  
  TR#HEADER {background-color:#ffffaa; }  
  TD {padding:5px; }  
  A {color:black; text-decoration:none;} 
  A:hover {color:red;} 
--> 
</style> 
<OBJECT CLASSID="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83" ID=CSVFILE > 
  <PARAM NAME="DataURL" VALUE="CS02.php?keyword=<?php echo rawurlencode($_GET
['moji'])?>"> 
  <PARAM NAME="UseHeader" VALUE="True"> 
</OBJECT> 
</head> 
<body> 
  
<TABLE DATASRC=#CSVFILE > 
  <THEAD>   
    <TR ID="HEADER"> 
      <TH>会社名
      <TH> ID
      <TH>お名前
      <TH>電話
      <TH>アドレス 
    </TR> 
  </THEAD>   
  
  <TBODY> 
    <TR> 
      <TD><SPAN DATAFLD=KAISHAMEI></SPAN></TD>
       <TD><SPAN DATAFLD=ID></SPAN></TD>
      <TD><SPAN DATAFLD=SHIMEI></SPAN></TD>
      <TD><SPAN DATAFLD=DENWA></SPAN></TD>
      <TD><SPAN DATAFLD=ADORESU></SPAN></TD>
    </TR> 
</TBODY> 
</TABLE> 
</body> 
</html>

--------------検索キーと一致サーチ----------
<?php  
// mb_http_output("Shift_JIS");

// 読み込むCSVファイル  
$csvfile = "CSDATA.csv";  
// CSVファイルの1行の最大サイズ  
$linesize = 4096;  
   
// 念のため変数を初期化  
$printdata = ""; 
   
// 検索キーワードを設定  
$keyword['kensakukye'] = ""; 
  
// GETで渡された値をカテゴリの検索キーワードとしてセット 
$keyword['kensakukye'] = $_GET["keyword"]; 
 
// CSVファイルを開く  
$fh = fopen ($csvfile, "r");  
// 開けなかったら終了  
if (!$fh) {  
  exit;  
}  
   
// 1行目の見出し部分を読み込み  
if (!feof ($fh) ) {  
  $line = fgets ($fh, $linesize);  
 
  // 1行目の見出し行を表示用変数にセット 
 $printdata = $line; 
 }  

// 2行目以降を読み込み  
while (!feof ($fh)) {  
  // 見つかったかどうかのフラグを初期化  
// $found['itti'] = false;  
 
  // 1行読み込み  
  $line = fgets($fh, $linesize);  
   
  // 検索ワードに一致するか確認  
  if (strlen ($keyword['kensakukye'])) { 
    $found['itti'] = mb_strpos ($line, $keyword['kensakukye']); 
  } 
  
  // カテゴリーに一致したら、その行を表示用変数にセット 
  if ($found['itti'] !== false) 
 {
    $printdata .= $line; 
  }
  
}
// ファイルを閉じる  
fclose ($fh);  
   
// 表示 
echo $printdata; 
?>

-----------------------------------

光陽でヒットし文字化けするデーターの半角文字内容を1つづつ削り
ました。

06-1234-5678
06-1234-567
06-1234-56
06-1234-5
そうすると、ある所まで削ると漢字が正常に表示されました。
ふたたび06-1234-56にすると検索後文字化けします。
そこで隣のフィールド
abc@efgd.co.jpを
abc@efgd.co.j
とすると表示の文字化けがなおりました。
CSVの作り方?でき方がおかしいのかと正常表示するデーター
のままで、他のキー検索をすると。
(たとえば「光」1文字)
光が含まれるデーターはヒットしますが表示が文字化けします。 

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1-1 満足
replyerpascal [3月27日 20:07]

試してみましたが、こちらの環境では現象は再現しませんでした。

とりあえず、「検索キー入力及びHTMLで表示」としてあるファイルのHTMLが正しくないので修正してください。
headタグ内にformタグは書けません。
書いた場合、そこでheadタグが終了したとみなされ、metaタグが正常に処理されません。(たぶん)
あと、終了タグ(今回は「/th」)はなるべく省略しないようにしましょう。

文字化けした場合ですが、読み込んだCSVの内容のみが文字化けしているのでしょうか?
(テーブルの見出し部分は文字化けしていないのでしょうか?)
そうであればプログラムの問題だと思いますが、全体が文字化けしているのであれば、htmlの問題と思われます。

「CS02.php?keyword=%8C%F5%97z」などとして、CSVの検索結果をブラウザに直接表示させ、文字化けするかどうかも試してみてください。
(文字エンコーディングが自動で「日本語(シフトJIS)」にならないかもしれません。メニューの「ツール」-「エンコード」から確認してください。)


なお、こちらで再現しなかったので外しているかもしれませんが、その点はご了承ください。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1-1-1-1
replyerPHPGANBA [3月28日 15:09] (最終編集:3月28日 16:19)

文字化けした場合ですが、読み込んだCSVの内容のみが文字化けしているのでしょうか?

CSVの日本語が化けます。
英数字(1BYTE)は化けません。
テーブルはHTMLの中で定義してるので正常に表示されます。
データーでしょうか?
もう少しやってみます。

上記の後ネットで文字化けの事を書いてる所がありました。
そこに下記のサンプルがあり実験しました。
私の環境はXAMPP Winです。

----下記実験の案内---
<META http-equiv="Content-Type" content="text/html;charset=Shift_JIS">
<?php
echo "内部エンコーディング:".mb_internal_encoding()."<BR />\n" ;
echo "送信されてきたデータのエンコーディング:".mb_detect_encoding($_POST["text"], "auto")."<BR />\n" ;
echo $_POST["text"]."<BR />\n" ;
?>
<!-- 以下、タグ属性は一部をのぞいて省略 -->
<FORM>
<INPUT type="text" name="text"> <INPUT type="submit" value="送信">
</FORM>

以上をシフトJISで保存。
これで「こんにちは」を送信してみます。
すると、

内部エンコーディング:EUC-JP
送信されてきたデータのエンコーディング:SJIS
、ウ、?ヒ、チ、マ


こんな悲しい結果になりました。
でました文字化けです。
---------------------
しかし私のマシンで実行すると。

内部エンコーディング:ISO-8859-1
送信されてきたデータのエンコーディング:ASCII

なんとISO-8859 ヨーロッパ文字?
SJISでもない。
文字コードコントロールがおかしいのですかね?

研究します。

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
負荷時のmysql_connect()エラー
 このエントリーをはてなブックマークに追加 
A
これはPHPというよりOSまたはMySQLのコミュニティで質問されたほうがいいと思います。 ぱっと思いついた範囲で記すと MySQL等のDBに「ある時点において同時に接続可能なクライアントの最大数」に制限があるよう...

>>続きを読む

今回のような実践的な経験がエンジニアのキャリアに繋がると思います。是非サービスを成功させて下さい!

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)