Vinzenz Mai: csv- oder txt-Dateien mit den Filesystem Functions?

Beitrag lesen

Hallo Flo,

danke, dass Du Code veröffentlichst. Bitte fasse meine Anmerkungen als konstruktive Kritik auf, anhand derer Du Deine guten Ansätze ausbauen kannst.

Ich habe auch mal einige Klassen zum Thema CSV geschrieben. es gibt zwar keine Doku, aber ich poste sie mal und fragen beantworte ich gerne:

für einen Anwender (hier einen Programmierer, der Deine Klasse anwendet) ist die Dokumentation unverzichtbar. Unkommentierter Code, auch wenn er von ausgezeichneten Programmierern wie z.B. den Entwicklern von OpenSSH stammt, ist miserabler Code.

[code lang=php]
    abstract class Model2D extends Model {
        protected $idfield = -1;

statt einer hartcodierten -1 böte sich der Einsatz einer Klassenkonstanten an.

public function add($row) {

// [...]

if(count($row) > $this->rowlength) {
                $row = array_slice($row,0,$this->rowlength);

Ich erwarte hier eine Exception, nicht das stillschweigende Unterschlagen von Daten.

} else if(count($row) < $this->rowlength) {
                $row = array_pad($row, $this->rowlength, '');

Auch hier erwarte ich eine Exception, nicht ein Auffüllen mit Leerzeichen.
Wenn die Anzahl der Felder nicht stimmt, Pech gehabt: nette Mitteilung, wieviele Spalten erforderlich sind. Die Anwendung kann sich dann immer noch dazu entschließen, die Exception so zu behandeln, wie Du es hier tust.

[...]

class CSV extends Model2D {
        private $handle;
        private $delimiter = ",";
        private $flcaption = false;
        private $fields;

public function setDelimiter($delimiter) {
            $this->delimiter = $delimiter{0};
        }

Was ist, wenn der Delimiter ein Zeichen ist, das in UTF-8 o.ä. mit mehr als einem Byte codiert wird?

public function open() {

[...]

while(!feof($this->handle)) {
                $line = fgets($this->handle, 65526);
                if(trim($line) == "") continue;
                $line = str_replace(chr(10), '', $line);
                $line = str_replace(chr(13), '', $line);

Nein, natürlich nicht. Du machst die schönen Zeilenumbrüche in meinem Feld kaputt. Ich will die behalten, dafür gibt es ja ein weiteres Spezialzeichen (typischerweise doppelte Anführungszeichen). Denke an die Behandlung dieses Spezialzeichens im Feld.

$row = explode($this->delimiter, $line);

Deswegen darf das Trennzeichen bei Dir nicht im Feld vorkommen :-)

Hier noch ein Archivthread (ich steige weit hinten ein), der sich mit dem Thema CSV beschäftigte.

Ich wünsche mir,

- dass Du Deinen Code kommentierst,
 - dass Du Klassenkonstanten verwendest,
 - dass Feldwerte das Trennzeichen enthalten dürfen
   (benutze ein Texterkennungszeichen, in fgetcsv $enclosure),
 - dass Feldwerte das Zeilentrennzeichen enthalten dürfen
   (auch hier schlägt das Texterkennungszeichen zu),
 - dass nicht stillschweigend Daten verloren gehen können,
 - dass nicht stillschweigend unvollständige Daten hinzugefügt werden können.

Freundliche Grüße

Vinzenz

PS: Was macht Dein Notebook und XP SP3?