-
Notifications
You must be signed in to change notification settings - Fork 0
/
CsvIterator.class.php
238 lines (208 loc) · 4.75 KB
/
CsvIterator.class.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
<?php
/**
* Iterator to easily handle CSV rows
*
* @author Damian Senn <[email protected]>
*/
class CsvIterator implements Iterator {
/**
* Represents the current line in $this->handle
*
* @var int
*/
private $position = 0;
/**
* Defines the maximal length of a line
*
* @var int
*/
private $length = null;
/**
* Holds the file pointer/handler
*
* @var resource
*/
private $handle = null;
/**
* Holds the current row
*
* @var array
*/
private $current = null;
/**
* Defines if the rows should be fetched associative
*
* @var bool
*/
private $assoc = null;
/**
* Holds the array keys if $this->assoc is true
*
* @var array
*/
private $keys = null;
/**#@+
* @var string
*/
/**
* Defines the CSV field enclosure character
*/
private $enclosure = null;
/**
* Defines the CSV delimiter
*/
private $delimiter = null;
/**
* Defines the CSV escape character
*/
private $escape = null;
/**#@-*/
/**
* Constructor of CsvIterator
*
* @author Damian Senn <[email protected]>
* @throws RuntimeException
* @param string $file
* @param string $delimiter
* @param bool $assoc
* @return void
*/
public function __construct($file, $delimiter = ';', $assoc = false){
$this->position = 0;
$this->delimiter = $delimiter;
$this->enclosure = '"';
$this->length = 2048; // null == unlimited but slower
$this->escape = '\\';
$this->assoc = $assoc;
$this->handle = @fopen($file, 'r');
if($this->handle === false){
throw new RuntimeException(sprintf('Could not open file %s', $file));
}
}
/**
* If set to true, the first row will be used as fieldnames
*
* @author Damian Senn <[email protected]>
* @param bool $assoc
* @return this
*/
public function setAssoc($assoc){
$this->assoc = $assoc;
return $this;
}
/**
* Sets the escape character used in fgetcsv
*
* @author Damian Senn <[email protected]>
* @param string $escape
* @return this
*/
public function setEscape($escape){
$this->escape = $escape;
return $this;
}
/**
* Sets the length used in fgetcsv
*
* @author Damian Senn <[email protected]>
* @param int $length
* @return this
*/
public function setLength($length){
$this->length = $length;
return $this;
}
/**
* Sets the enclosing character used in fgetcsv
*
* @author Damian Senn <[email protected]>
* @param string $enclosure
* @return this
*/
public function setEnclosure($enclosure){
$this->enclosure = $enclosure;
return $this;
}
/**
* Sets the delimiter character used in fgetcsv
*
* @author Damian Senn <[email protected]>
* @param string $delimiter
* @return this
*/
public function setDelimiter($delimiter){
$this->delimiter = $delimiter;
return $this;
}
/**
* Rewinds back to the first element of the Iterator
* This method is only called while starting a foreach loop
*
* @author Damian Senn <[email protected]>
* @return void
*/
public function rewind(){
$this->position = 0;
rewind($this->handle);
if($this->assoc){
$this->keys = fgetcsv($this->handle, $this->length, $this->delimiter);
}
$this->current = fgetcsv($this->handle, $this->length, $this->delimiter);
}
/**
* Returns the current row
*
* @author Damian Senn <[email protected]>
* @return array
*/
public function current(){
return $this->assoc
? array_combine($this->keys, $this->current)
: $this->current;
}
/**
* Returns the current position (file line)
*
* @author Damian Senn <[email protected]>
* @return int
*/
public function key(){
return $this->position;
}
/**
* Moves the current position to the next element
* This method is called after each foreach loop
*
* @author Damian Senn <[email protected]>
* @return void
*/
public function next(){
if(is_resource($this->handle)){
$this->current = fgetcsv($this->handle, $this->length, $this->delimiter);
$this->position++;
}
}
/**
* This method is called after self::rewind() and self::next() to check if
* the current position is valid.
*
* @author Damian Senn <[email protected]>
* @return bool
*/
public function valid(){
if($this->current === false){
fclose($this->handle);
return false;
}
return true;
}
/**
* CsvIterator destructor closes the opened CSV file
*
* @author Damian Senn <[email protected]>
* @return void
*/
public function __destruct(){
if(is_resource($this->handle)) fclose($this->handle);
}
}