Skip to content

Instantly share code, notes, and snippets.

@m4tthumphrey
Created April 16, 2014 16:18
Show Gist options
  • Save m4tthumphrey/10901569 to your computer and use it in GitHub Desktop.
Save m4tthumphrey/10901569 to your computer and use it in GitHub Desktop.
Simple class to iterate a CSV file quickly, allowing the user to manipulate the value of each field
<?php
class Reader
{
protected $fields = [];
protected $filters = [];
public function read($file)
{
try {
$handle = fopen($file, 'r');
while ($line = fgetcsv($handle)) {
foreach ($this->filters as $check) {
if (false === call_user_func($check, $line)) {
continue 2;
}
}
yield $line;
}
} finally {
fclose($handle);
}
}
public function fields(array $fields)
{
foreach ($fields as $header => $callback) {
$this->field($header, $callback);
}
return $this;
}
public function field($header, $callback, $position = 0)
{
if (!$position) {
$position = count($this->fields) + 10;
}
$this->fields[] = [
'header' => $header,
'position' => $position,
'callback' => $callback
];
return $this;
}
public function sort($on = 'position', $order = SORT_ASC)
{
usort($this->fields, function($a, $b) use ($on, $order) {
if ($a[$on] == $b[$on])
return 0;
else
return ($order===SORT_ASC ? $a[$on] > $b[$on] : $a[$on] < $b[$on]) ? 1 : -1;
});
}
public function filter(Closure $callback)
{
$this->filters[] = $callback;
return $this;
}
public function row(array $row)
{
$fields = [];
foreach ($this->fields as $field) {
if ($field['callback'] instanceof Closure) {
$fields[] = call_user_func($field['callback'], $row);
} else {
$fields[] = $row[$field['callback']];
}
}
return $fields;
}
public function headers()
{
return array_map(function($field) {
return $field['header'];
}, $this->fields);
}
}
<?php
$reader = new Reader();
$reader->fields(array(
'Call ID' => 0,
'Call Type' => function($call) {
return $call[8] === 'O' ? 'Outbound' : 'Inbound';
},
'NGN' => 1,
'Date' => 2,
'Duration' => function($call) {
return round($call[4] / 60, 3);
},
'Type' => 5,
'Cost' => function($call) {
return round($call[6], 3);
},
'Caller' => 7,
'Target' => function($call) {
return 'N/A';
}
));
$reader->filter(function($call) {
if (in_array($call[0], array('HEADER', 'TRAILER'))) {
return false;
}
return true;
});
$headers = $reader->headers();
$rows = $reader->read('/path/to/file.csv');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment