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

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

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

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

文字コード

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

Q&A

1回答

875閲覧

PHPでCSVファイルを読み込んだ際に「,」で区切られるパターンと区切られないパターンがある

teru-

総合スコア13

PHP

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

文字コード

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

0グッド

0クリップ

投稿2022/07/24 12:00

前提

PHP本格入門(上)というテキストを参照して、
csvファイルを読み込んで表示するというプログラムを検証しています。
PHPでCSVファイルを読み込んだ場合、どのようなロジックで「,(カンマ)」判定をされているのかをご教授いただきたいです。
具体的な事象は下記プログラムおよび実行結果をご参照ください。

該当のソースコード

PHP

1$csv = new SplFileObject('files/sample.csv'); 2$csv->setFlags(SplFileObject::READ_CSV); 3 4foreach ($csv as $value) { 5 print_r($value); 6}

sample.csv(文字コード:UTF8)

1商品名,価格 2掃除機,"15,000" 3エアコン,"60,000" 4"アイロン高性能","20,000"

※CSVファイルの「,(カンマ)」はすべて半角で統一されております。

Array ( [0] => 商品名,価格 ) Array ( [0] => 掃除機,"15 [1] => 000" ) Array ( [0] => エアコン [1] => 60,000 ) Array ( [0] => アイロン高性能 [1] => 20,000 )

確認したいこと

上記実行結果ですと、下記の場合掃除機の直後の「,」で区切られず、

array( [0] => 掃除機,"15 [1] => 000" )

下記の場合、エアコンの直後できちんと区切られています。

Array ( [0] => エアコン [1] => 60,000 )

また、「商品名」と「価格」も「,(カンマ)」で区切られず、1行で判定されています。

なお、上記事象に直接関係はないかもしれませんが、文字コードがSJISのCSVファイルを下記のようにプログラム内でUTF8に変換して出力した場合は、上記のような事象は発生せず、期待通りに「,(カンマ)」で区切られておりました。
(テキストではその方法では動作しないと記載があったのですが、なぜかきちんと動作しました)

PHP

1foreach ($csv as $value) { 2 mb_convert_variables('UTF-8', 'SJIS-win', $value); 3 print_r($value); 4}
Array ( [0] => 商品名 [1] => 価格 ) Array ( [0] => 掃除機 [1] => 15,000 ) Array ( [0] => エアコン [1] => 60,000 ) Array ( [0] => アイロン高性能 [1] => 20,000 )

上記事象の理由をご教授いただきたいです。
よろしくお願いいたします。

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

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

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

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

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

otn

2022/07/24 13:17

php.iniのエンコーディング設定がおかしいとかでしょうか。 OSとPHPのインストール方法は何でしょうか?インストール後、php.iniは編集しましたか?
teru-

2022/07/24 14:06

回答ありがとうございます! OSはWindows10でPHPはMAMPを使ってインストールしています。 php.iniはdefault_charsetをUTF-8に変更しています。 (その他に変更はありません)
itagagaki

2022/07/24 14:45

print_r($csv->getCsvControl()); はどうなりますか?
teru-

2022/07/24 15:05

回答ありがとうございます! Array ( [0] => , [1] => " [2] => \ ) となっております。
itagagaki

2022/07/24 15:15

$csv->setFlags(SplFileObject::READ_CSV); をコメントアウトしたら出力はどうなりますか? 商品名,価格 掃除機,"15,000" エアコン,"60,000" "アイロン高性能","20,000" と表示されますか?
otn

2022/07/24 16:43

質問に書いてあるsample.csvの内容は全く改変せずコピペした物ですよね?
teru-

2022/07/25 07:16

>itagagaki 上記と同じように表示されております。
teru-

2022/07/25 07:16

>otn はい。コピペしたものになります。
otn

2022/07/25 09:26

$csv = new SplFileObject('files/sample.csv'); foreach ($csv as $value) { print_r(bin2hex($value)); } した結果を書いてください。
teru-

2022/07/29 14:23

ご返信が遅くなり申し訳ございません。 下記が出力結果になります。 8fa4956996bc2c89bf8a690d0a917c8f9c8b402c2231352c303030220d0a83478341835283932c2236302c303030220d0a2283418343838d83938d8290ab945c222c2232302c30303022
otn

2022/07/29 17:16

> 8fa4956996bc2c89bf8a690d0~~ それは、Shift_JISエンコーディングのファイルですね。 ファイルのエンコーディングがUTF-8であるという認識が間違っていると思われます。
teru-

2022/07/29 18:04

失礼いたしました。 エンコーディング対象のファイルが異なっておりました。 (sample.csvはSJISの認識で相違ありません) 下記出力が正となります。 e59586e59381e5908d2ce4bea1e6a0bc0d0ae68e83e999a4e6a99f2c2231352c303030220d0ae382a8e382a2e382b3e383b32c2236302c303030220d0a22e382a2e382a4e383ade383b3e9ab98e680a7e883bd222c2232302c30303022
otn

2022/07/30 05:25

おそらく、そういったレベルの間違いがあるのでしょうね。
guest

回答1

0

普通にfgetcsvなどで処理してみては?

PHP

1<?PHP 2$fp=fopen('files/sample.csv','r'); 3while($val=fgetcsv($fp)){; 4 $csv[]=$val; 5} 6print_r($csv);

投稿2022/07/25 01:35

yambejp

総合スコア114839

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

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

teru-

2022/07/25 07:21

回答ありがとうございます! fgetcsvを利用した場合も下記で質問にある内容と同じ出力結果になります。 (カンマが期待した位置で区切られておりません) Array ( [0] => Array ( [0] => 商品名,価格 ) [1] => Array ( [0] => 掃除機,"15 [1] => 000" ) [2] => Array ( [0] => エアコン [1] => 60,000 ) [3] => Array ( [0] => アイロン高性能 [1] => 20,000 ) )
yambejp

2022/07/25 07:54

csvはほんとにutf8でしょうか?shiftjisだったら「能」が5C問題に引っかかっているのかもと思ったのですが・・・ BOMはずしてもだめですか?
teru-

2022/07/25 08:08

サクラエディタを利用して確認したのですが、やはりUTF8になっています。 また、BOMも元からついておりません。 (念のため、BOMなしで上書きしましたが挙動に変化はないです)
yambejp

2022/07/25 08:19

たとえばこんな感じでよむとどうなりますか? $fp=fopen('sample.csv','r'); $data=""; while($val=fread($fp,1024)){; $data.=$val; } $datas=array_map(function($x){ return str_getcsv($x); },preg_split('/[\r\n]+/u',$data)); print_r($datas);
teru-

2022/07/29 14:30

ご返信が遅くなり申し訳ございません。 下記が出力結果になります。 Warning: array_map(): Expected parameter 2 to be an array, bool given in… 確認したところ、preg_splitの戻り値がfalseになっているので、上記エラーとなっているかと思われます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問