1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace CsvParser\Reader; |
4
|
|
|
|
5
|
|
|
class StringReader implements ReaderInterface |
6
|
|
|
{ |
7
|
11 |
|
public static function read(\CsvParser\Parser $parser, $string) |
8
|
|
|
{ |
9
|
11 |
|
$data = array(); |
10
|
|
|
|
11
|
|
|
// shorten some vars for use later |
12
|
11 |
|
$d = $parser->fieldDelimiter; |
13
|
11 |
|
$e = $parser->fieldEnclosure; |
14
|
11 |
|
$l = $parser->lineDelimiter; |
15
|
|
|
|
16
|
|
|
// get headings and body (if \n line feeds, also support reading on carriage returns) |
17
|
11 |
|
list($headings, $body) = $l=="\n" ? preg_split('/[\n\r]/', $string, 2) : explode($l, $string, 2); |
18
|
|
|
|
19
|
|
|
// format array of headings/keys |
20
|
11 |
|
$headings = str_getcsv($headings, $d, $e); |
21
|
|
|
|
22
|
|
|
// Split row lines |
23
|
|
|
// to do this we replace new lines with a key and then explode on them |
24
|
|
|
// regex to match new lines, but not inside quotes, based on: https://stackoverflow.com/questions/632475/regex-to-pick-commas-outside-of-quotes/25544437#25544437 |
25
|
11 |
|
$rKey = '*%~LINE_BREAK~%*'; |
26
|
11 |
|
$qE = preg_quote($e); |
27
|
11 |
|
$qL = $l=="\n" ? '\n|\r' : preg_quote($l); |
28
|
11 |
|
$body = preg_replace('/'.$qE.'[^'.$qE.']*'.$qE.'(*SKIP)(*F)|'.$qL.'/', $rKey, $body); |
29
|
11 |
|
$lines = explode($rKey, $body); |
30
|
|
|
|
31
|
|
|
// any lines found? loop them |
32
|
11 |
|
if ( ! empty($lines)) { |
33
|
11 |
|
foreach ($lines as $i => $line) { |
34
|
11 |
|
if ($line==='') { |
35
|
|
|
continue; // blank line... |
36
|
|
|
} |
37
|
11 |
|
$fields = str_getcsv($line, $d, $e); |
38
|
11 |
|
$data[$i] = array(); |
39
|
|
|
// loop the headings to map to columns |
40
|
11 |
|
foreach ($headings as $j => $heading) { |
41
|
11 |
|
$field = isset($fields[$j]) ? $fields[$j] : ''; |
42
|
11 |
|
$data[$i][$heading] = $field; |
43
|
|
|
} |
44
|
|
|
} |
45
|
|
|
} |
46
|
|
|
|
47
|
11 |
|
return new \CsvParser\Csv($data); |
48
|
|
|
} |
49
|
|
|
} |
50
|
|
|
|