fgetcsv ändern anderes Trennzeichen

Hallo zusammen!
Habe vor längerer Zeit mal eine Klasse zu diesem Thema geschrieben. Müsstet sie euch mal anschauen. Kann sie auch gerne nochmal die Tage überarbeiten.
MfG, Andy

PHP:
<?php

/**
 * Class CsvHandler
 * 
 * The CsvHandler class enables reading lines
 * from csv-files. Furtehermore you are able to
 * read the complete file into an array.
 * 
 * @package CsvHandler
 * @version 0.3
 * @date 3/4/2008
 * @author Andreas Wilhelm <Andreas2209@web.de>
 * @copyright Andreas Wilhelm
 * @see http://avedo.net
 */
class CsvHandler
{
	/**
	 * @var String $file The filename of the forced file
	 * @access private
	 */
	private $file;
	
	/**
	 * @var FilePointer $fp The file handle object
	 * @access private
	 */
	private $fp;
	
	/**
	 * @var Array $data The data from the current file
	 * @access private
	 */
	private $data;

	/**
	 * Creates a new csv-file
	 *
	 * @access public
	 * @param String $path The path to the csv file
	 * @return void
	 */
	public function create($path)
	{
		// create file
		if( !file_exists($path) )
		{
			file_put_contents($path, '');
		}
		
		else
		{
			throw new Exception($path . ' already exists');
		}
	}

	/**
	 * Opens a csv-file (default: reading)
	 *
	 * @access public
	 * @param String $file The path to the csv file
	 * @param Integer $cols The number of columns in the csv file
	 * @param String $mod The working modificator
	 * @return void
	 */
	public function open($file, $cols, $mod = 'r')
	{
		// set path to file
		$this->file = $file;
		
		// open file
		$this->fp = fopen($this->file, $mod);
		
		// check result
		if( !$this->fp )
		{
			throw new Exception('Could not open ' . $file);
		}
		
		// read data from file into an array
		$this->data = $this->read($cols);
	}

	/**
	 * Locks the csv-file (default: LOCK_SH)
	 *
	 * @access public
	 * @param String $mod The working modificator
	 * @return void
	 */
	public function lock($mod = LOCK_SH)
	{
		// check result
		if( !flock($this->fp, $mod) )
		{
			throw new Exception('Could not lock file');
		}
	}

	/**
	 * gReads a line of csv-file
	 *
	 * @access public
	 * @param Integer $cols The number of columns in the csv file
	 * @return Array
	 */
	public function getLine($cols)
	{
		// read line into an array
		$line = fgetcsv($this->fp, 4096);
		
		// check result
		if( !$line )
		{
			throw new Exception('Could not read line');
		}
		
		// check num of fields
		if( count($line) != $cols )
		{
			throw new Exception('Line has a invalid format');
		}
		
		//return line-array
		return $line;
	}

	/**
	 * Writes a line into csv-file
	 *
	 * @access public
	 * @param Array $fields The names of the fields in the csv file
	 * @return void
	 */
	public function setLine($fields)
	{
		// write line into file
		$line = fputcsv($this->fp, 4096);
		
		// check result
		if(!$line)
		{
			throw new Exception('Could not write line');
		}
	}

	/**
	 * Adds a new line to csv-file
	 *
	 * @access public
	 * @param Array $fields The names of the fields in the csv file
	 * @return void
	 */
	public function add($fields)
	{
		// add new line to data-array
		array_push($this->data, $fields);
	}

	/**
	 * Reads the whole csv-file
	 *
	 * @access public
	 * @param Integer $cols The number of columns in the csv file
	 * @return Array
	 */
	public function read($cols)
	{
		// get the whole data
		while( !feof )
		{
			$data = $this->getLine($cols);
		}
		
		// return data-array
		return $data;
	}

	/**
	 * Edits an entry in the csv-file
	 *
	 * @access public
	 * @param Integer $row The row in the csv file
	 * @param Integer $col The column in the data row
	 * @param Integer $value The value which should be assign
	 * @return Array
	 */
	public function edit($row, $col, $value)
	{
		//check number of rows
		if( $row > count($this->data) )
		{
			throw new Exception("Line {$row} does not exist.");
		}
		
		// check num of fields
		if( $col > count($this->data[$row-1]) )
		{
			throw new Exception("Column {$col} does not exist.");
		}
		
		// edit field
		$this->data[$row-1][$col-1] = $value;
	}

	/**
	 * Saves whole data-array to file
	 *
	 * @access public
	 * @return void
	 */
	public function save()
	{
		// close csv-file
		$this->close();
	} 

	/**
	 * Closes csv-file
	 *
	 * @access public
	 * @return void
	 */
	public function close()
	{
		fclose($this->fp);
	} 
}

try
{
	$fp = new CsvHandler('test.csv');
	$fp->open();
	$fp->lock();
	$reply = $fp->getLine(4);
	print_r($reply);
	$fp->close();	
}

catch(Exception $e)
{
	echo "Error:<br />";
	echo "<b>" . $e->getLine() . "</b>" . ": " . $e->getMessage() . "<br />";
}	
	
?>
 
@xanthos

Mit deiner Hilfe lief das Skirpt jetzt seit ein paar Tagen ohne Probleme.
Jetzt hat der Kunde aufeinmal eine andere Inputcsv geschickt, mit z.B leeren Feldinhalten.
Nun verdoppelt
PHP:
$_line = preg_replace('/(?<!^|\,)\"(?!$|\,)/','""',$_line);
nicht mehr richtig. Siehe (Nach der Änderung -> Zeilenende)

Input.csv

Code:
"Feld1","Feld2","Feld3","Feld4","Feld5"
"","Data2 String ="333" test","Data3","Data4",""
"","Data2 test","Data3","Data4",""

Nach der Änderung:
Code:
"Feld1","Feld2","Feld3","Feld4","Feld5""
"","Data2 String =""333"" test","Data3","Data4","""
"","Data2 test","Data3","Data4","""

Jetzt stehe ich wieder auf dem Schlauch, wie der preg_replace geändert werden muss, damit sowas nicht passiert.
 
Dolphon, der Ausdruck passt immer noch. Wichtig ist, dass jede Zeile einzeln eingelesen wird (fgets()). Evt. ist hinter dem letzten "Feld" ein Leerzeichen. Versuche es also mal mit trim().

PHP:
$_line = preg_replace('/(?<!^|\,)\"(?!$|\,)/','""',trim($_line));
 
Also fgets wird bereits benutzt, und ein trim brachte auch keine Besserung.

Hier mal der Vollständige Code dazu:

PHP:
// Removing the quotes at the beginning and end of the parameter
$delimiterinput = trim($argv[1],"\"");
$delimiteroutput = trim($argv[2],"\"");
$inputdata = trim($argv[3],"\"");

// Open Inputfile (csv Format, header and fields in colums)
$open_old_csv = fopen($inputdata, "r") or die ("ERROR: cannot open file ".$inputdata."\r\n");

// Open temp. workfile
$open_tmp_csv = fopen($inputdata."tmp",'w')or die ("ERROR: cannot open file ".$inputdata."tmp \r\n");

// Loop over all lines
while($_line = fgets($open_old_csv,100000))
{
    // Double quotes within all of the fields which are enclosed by quotes.
	$_line = preg_replace('/(?<!^|\,)\"(?!$|\,)/','""',$_line);
    fputs($open_tmp_csv,$_line);
}
fclose($open_old_csv);
fclose($open_tmp_csv);
 
Bei mir ebenfalls!

Als Alternative:

Lies den gesamten Inhalt auf einmal ein (fread()) und verwende folgenden Ausdruck:

PHP:
$_line = preg_replace('/(?<!^|\,|\r\n)\"(?!$|\,|\r\n)/','""',$_line);
 
Zuletzt bearbeitet:
Komisch bei mir klappt es trotzdem nicht.
Ich probier einmal die alternative Methode.
 
Zuletzt bearbeitet:
Ich bekomm gleich die Krise.

Habe jetzt die Alternatvie benutzt. Jetzt ist die Ausgabe CSV richtig.
Allerdings ist nun die Ausgabe CSV der ersten Test Input falsch.

HIER EINMAL EINE ZUSAMMENFASSUNG:

test1.csv

Code:
"Feld1","Feld2","Feld3","Feld4"
"Data1","Data2: ,String="xyz" fertig","Data3","Data4"
"Data1","Data2: String="xyz" fertig","Data3","Data4"

test2.csv

Code:
"Feld1","Feld2","Feld3","Feld4","Feld5"
"","Data2 String ="333" test","Data3","Data4",""
"","Data2 test","Data3","Data4",""

CODE ALTERNATIV:

PHP:
// Removing the quotes at the beginning and end of the parameter
$delimiterinput = trim($argv[1],"\"");
$delimiteroutput = trim($argv[2],"\"");
$inputdata = trim($argv[3],"\"");

// Open Inputfile (csv Format, header and fields in colums)
$open_old_csv = fopen($inputdata, "r") or die ("ERROR: cannot open file ".$inputdata."\r\n");

// Open temp. workfile
$open_tmp_csv = fopen($inputdata."tmp",'w')or die ("ERROR: cannot open file ".$inputdata."tmp \r\n");

// Loop over all lines
while($_line = fread($open_old_csv,filesize($inputdata)))
{
    // Double quotes within all of the fields which are enclosed by quotes.
	$_line = preg_replace('/(?<!^|\,|\r\n)\"(?!$|\,|\r\n)/','""',$_line); 
    fputs($open_tmp_csv,$_line);
}
fclose($open_old_csv);
fclose($open_tmp_csv);


OUTPUT test1.csv
->falsch
Code:
"Feld1","Feld2","Feld3","Feld4""
""Data1","Data2: ,String=""xyz"" fertig","Data3","Data4""
""Data1","Data2: String=""xyz"" fertig","Data3","Data4"

OUTPUT test2.csv
-> richtig
Code:
"Feld1","Feld2","Feld3","Feld4","Feld5"
"","Data2 String =""333"" test","Data3","Data4",""
"","Data2 test","Data3","Data4",""




Bei der vorherigen Version des Skriptes ist es mit Fehlern genau anders herum.
 
So habs in per ini_set() oder auch direkt mit der php.ini versucht.
Das Resultat bleibt das gleiche. Keine Veränderung des Problems.
 
Zurück