示例#1
0
 /**
  * Reads a row of data as an array from a CSV file. It's able to
  * read memo fields with multiline data.
  *
  * @param string $file   The filename where to write the data
  * @param array  &$conf   The configuration of the dest CSV
  *
  * @return mixed Array with the data read or false on error/no more data
  */
 function readQuoted($file, &$conf)
 {
     if (!($fp = File_CSV::getPointer($file, $conf, FILE_MODE_READ))) {
         return false;
     }
     $buff = $old = $prev = $c = '';
     $ret = array();
     $fields = 1;
     $in_quote = false;
     $quote = $conf['quote'];
     $f = (int) $conf['fields'];
     $sep = $conf['sep'];
     while (false !== ($ch = fgetc($fp))) {
         $old = $prev;
         $prev = $c;
         $c = $ch;
         // Common case
         if ($c != $quote && $c != $sep && $c != "\n" && $c != "\r") {
             $buff .= $c;
             continue;
         }
         // Start quote.
         if ($in_quote === false && $quote && $c == $quote && ($prev == $sep || $prev == "\n" || $prev === null || $prev == "\r" || $prev == '' || $prev == ' ' || $prev == '=')) {
             $in_quote = true;
             // excel compat, removing the = part but only if we are in a quote
             if ($prev == '=') {
                 $buff[strlen($buff) - 1] = '';
             }
         }
         if ($in_quote) {
             // When does the quote end, make sure it's not double quoted
             if ($c == $sep && $prev == $quote && $old != $quote) {
                 $in_quote = false;
             } elseif ($c == $sep && $buff == $quote . $quote) {
                 // In case we are dealing with double quote but empty value
                 $in_quote = false;
             } elseif ($c == "\n" || $c == "\r") {
                 $sub = $prev == "\r" ? 2 : 1;
                 $buff_len = strlen($buff);
                 if ($buff_len >= $sub && $buff[$buff_len - $sub] == $quote) {
                     $in_quote = false;
                 }
             }
         }
         if (!$in_quote && ($c == $sep || $c == "\n" || $c == "\r")) {
             $return = File_CSV::_readQuotedFillers($fp, $f, $fields, $ret, $buff, $quote, $c, $sep);
             if ($return !== false) {
                 return $return;
             }
             if ($prev == "\r") {
                 $buff = substr($buff, 0, -1);
             }
             // Convert EOL character to Unix EOL (LF).
             if ($conf['eol2unix']) {
                 $buff = preg_replace('/(\\r\\n|\\r)$/', "\n", $buff);
                 // Below replaces things everywhere not just EOL
                 //$buff = str_replace(array("\r\n", "\r"), "\n", $buff);
             }
             $ret[] = File_CSV::unquote($buff, $quote);
             if (count($ret) === $f) {
                 return $ret;
             }
             $buff = '';
             ++$fields;
             continue;
         }
         $buff .= $c;
     }
     /* If it's the end of the file and we still have something in buffer
      * then we process it since files can have no CL/FR at the end
      */
     $feof = feof($fp);
     if ($feof && strlen($buff) > 0 && !in_array($buff, array("\r", "\n"))) {
         $ret[] = File_CSV::unquote($buff, $quote);
         if (count($ret) == $f) {
             return $ret;
         }
     }
     if ($feof && count($ret) !== $f) {
         $return = File_CSV::_readQuotedFillers($fp, $f, $fields, $ret, $buff, $quote, $c, $sep);
         if ($return !== false) {
             return $return;
         }
     }
     return !$feof ? $ret : false;
 }