PHP
FuelPHP

FuelPHPのformatクラスの改行判定でハマった

More than 3 years have passed since last update.


やりたかったこと

csvのファイルを読み込んで内容を配列に入れる

aaa,bbb,ccc

aaa,bbb,ccc

array(

0 => array(
0 => "aaa",
1 => "bbb",
2 => "ccc"
),
1 => array(
0 => "aaa",
1 => "bbb",
2 => "ccc"
)
)

にする。


やったこと

Format::forge(File::read('test.csv', true), 'csv')->to_array();

みたいな感じ。


ハマったこと

ファイル内の改行が改行と判断されたりされなかったりする

期待通りの配列ができた例

test11,test12,test13

test21,test22,test23

array(

0 => array(
0 => "test11",
1 => "test12",
2 => "test13"
),
1 => array(
0 => "test21",
1 => "test22",
2 => "test23"
)
)

期待通りの配列ができなかった例

test11,test12,aaa

test21,test22,bbb

array(

0 => array(
0 => "test11",
1 => "test12",
2 => "aaa
test21",
3 => "test21",
4 => "test22",
5 => "bbb"
)
)


csvフォーマットのデフォルト設定を確認

項目

区切り文字
,

囲い込み文字
"

改行
\n

エスケープ文字
\

https://github.com/fuel/core/blob/1.7/master/config/format.php

'csv' => array(

'import' => array(
'delimiter' => ',',
'enclosure' => '"',
'newline' => "\n",
'escape' => '\\',
),
'export' => array(
'delimiter' => ',',
'enclosure' => '"',
'newline' => "\n",
'escape' => '\\',
),
'regex_newline' => "\n",
'enclose_numbers' => true,
),

デフォルトだと、csvの値を「"」で囲まないとダメ?

でも想定通りの配列ができる場合もある。。


仕方なくソースを読む

https://github.com/fuel/core/blob/1.7/master/classes/format.php#L467-L474

if (empty($enclosure))

{
$rows = preg_split('/(['.$newline.'])/m', trim($string), -1, PREG_SPLIT_NO_EMPTY);
}
else
{
$rows = preg_split('/(?<=[0-9'.preg_quote($enclosure).'])'.$newline.'/', trim($string));
}

どうやら「" or 0-9の数字」+「\n」を改行する場所として判断してるみたい。。

enclosureを空に設定することで以下も期待通りの配列にできた。

test11,test12,aaa

test21,test22,bbb


まとめ


  • enclosureを空文字に設定することで解決した

  • フレームワークの動作を予想してはいけない(予想通りになることをテストする)

  • 予想通りにならなかったらソースを読む

  • 正規表現に0-9を入れている不思議