Skip to content

Instantly share code, notes, and snippets.

@pix0r
Created February 26, 2010 20:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pix0r/316099 to your computer and use it in GitHub Desktop.
Save pix0r/316099 to your computer and use it in GitHub Desktop.
function get_csv_line($fp) {
$sep = '|';
$quote = '"';
$escape = "\\";
$fields = array();
$field = '';
$in_field = true;
$in_quoted_field = false;
$in_escape = false;
$line_idx = -1;
$field_idx = -1;
while (!feof($fp)) {
$c = fgetc($fp);
++$line_idx;
if ($in_field) {
++$field_idx;
if ($in_escape) {
// Escape character goes directly into data
$field .= $c;
$in_escape = false;
} else if ($c == $quote) {
if ($in_quoted_field) {
// Field is over
$in_quoted_field = false;
$in_field = false;
$fields[] = $field;
} else if (!$field_idx) {
// Field starts with quote
$in_quoted_field = true;
} else {
// Stray quote, wtf?
echo "Stray quote found (wtf?)\n";
echo "line_idx=$line_idx field_idx=$field_idx\n";
die();
}
} else if (!$in_quoted_field && is_newline($c)) {
// Finished, need to add this field
strip_newline($fp);
$fields[] = $field;
$field_idx = -1;
return $fields;
} else {
$field .= $c;
}
} else {
if ($c == $sep) {
// New field
$in_field = true;
$field = '';
$field_idx = -1;
} else if (is_newline($c)) {
// Finished
strip_newline($fp);
return $fields;
}
}
}
}
function is_newline($ch) {
$ret = $ch == "\n" || $ch == "\r";
return $ret;
}
function strip_newline($fp) {
while (!feof($fp)) {
$pos = ftell($fp);
$c = fgets($fp);
if (!is_newline($c)) {
// Seek back
fseek($fp, $pos);
return;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment