-
Notifications
You must be signed in to change notification settings - Fork 2
/
IteratorExt.php
139 lines (118 loc) · 2.82 KB
/
IteratorExt.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<?php
namespace DesignPatterns\Behavioral;
/**
* Allows iterate over CSV file rows
*/
class CsvIterator implements \Iterator
{
/**
* File descriptor
* @var resource
*/
protected $file = null;
/**
* The delimiter for the CSV file, e.g. ',', ';'
* @var string
*/
protected $delimiter = null;
/**
* The current row, which is returned on each iteration
* @var array
*/
protected $currentRow = null;
/**
* The row counter
* @var int
*/
protected $rowCounter = null;
/**
* Tries to open the CSV file
* @param string $filePath Path to the input CSV file
* @param string $delimiter The delimiter like ',' or ';'
* @throws \Exception
*/
public function __construct(string $filePath, string $delimiter = ';')
{
if (!is_readable($filePath)) {
throw new \Exception("The file cannot be read");
}
$this->file = fopen($filePath, 'rb');
$this->delimiter = $delimiter;
}
/**
* Resets the file pointer
*/
public function rewind()
{
rewind($this->file);
$this->rowCounter = 0;
}
/**
* Returns the current CSV row
* @return array The current CSV row as a 2-dimensional array
*/
public function current()
{
$this->currentRow = fgetcsv($this->file, 4096, $this->delimiter);
$this->rowCounter++;
return $this->currentRow;
}
/**
* Returns the current row number
* @return int The current row number
*/
public function key()
{
return $this->rowCounter;
}
/**
* Checks if the end of file has been reached
* @return boolean Returns true on EOF reached, false otherwise
*/
public function next()
{
if (is_resource($this->file)) {
return !feof($this->file);
}
return false;
}
/**
* This method checks if the next row is a valid row
* @return boolean If the next row is a valid row
*/
public function valid()
{
if (!$this->next()) {
if (is_resource($this->file)) {
fclose($this->file);
}
return false;
}
return true;
}
}
# Client code example
// some CSV data
$csvContent = <<<CSV
Name;Value;isActive
First;10;true
Second;20;false
Third;30;true
CSV;
try {
// create temp file and save CSV data inside
$file = tmpfile();
$path = stream_get_meta_data($file)['uri'];
fwrite($file, $csvContent);
$csv = new CsvIterator($path);
foreach ($csv as $key => $row) {
echo $key . ':' . implode(', ', $row) . PHP_EOL;
}
} catch (\Exception $e) {
echo $e->getMessage();
}
/* Output:
1:Name, Value, isActive
2:First, 10, true
3:Second, 20, false
4:Third, 30, true */