Elegante Möglichkeit das Problem der fehlenden Mehrfachvererbung zu umgehen

Hi,

ich hoffe auch den Leuten von PHP ist Mehrfachvererbung ein Begriff.
Aber man merkt ja bekanntlich erst wie schön solche Dinge sind, wenn Sie
nicht mehr zur Verfügung stehen... :)

Aber nun meine Situation:

a) Ich habe eine Klasse zur Definierung einer Tabelle mit beliebig
vielen Spalten und beliebig vielen Zeilen.

Beispiel:
<?php
$table = new Datatable();
$table->addColumn("SpalteA");
$table->addColumn("SpalteB");

$table->addRow(array("SpalteA" => "WertA1", "SpalteB" => "WertB1"));
$table->addRow(array("SpalteA" => "WertA2", "SpalteB" => "WertB2"));
?>

b) Ich habe eine Klasse, die ein XML Node repräsentiert und die man als
Childs an andere XML Nodes anhängen kann.

Beispiel:
<?php
$node = new XmlNode("br");
$anderer_node->addChild($node);
?>

c) Nun will ich der Datentabelle auch die Möglichkeit geben, sich zeigen
zu können. Dafür gibt es verschiedene Formate wie .csv oder aber auch
als HTML Tabelle, die ich auch gerne mit verschiedenen Klassen
implementieren will (so kann ich neue Formate einfach durch neue Klassen
hinzufügen, die von der Datentabelle abgeleitet sind). Das Problem
besteht nun aber darin, dass diese Klasse alle Methoden benötigt, um die
Datentabelle zu definieren, aber selbst von XML Node abgeleitet werden
muss um als XML Node Objekt angehängt werden zu können (Datentabelle
selbst wäre dann der <table> Tag). Daher müsste ich meine HTML
Tabellenklasse von der Datentabelle, aber auch vom XML Node ableiten,
was in PHP nicht möglich ist.

Beispiel wie das wäre:
<?php
class HtmlDatatable extends Datatable, XmlNode
{
...
}

$htmltable = new HtmlDatatable();
$htmltable->addColumn("SpalteA");
$htmltable->addColumn("SpalteB");

$htmltable->addRow(array("SpalteA" => "WertA1", "SpalteB" => "WertB1"));
$htmltable->addRow(array("SpalteA" => "WertA2", "SpalteB" => "WertB2"));

$anderer_node->addChild($htmltable);
?>

Die Frage ist jetzt, wie umgeht man die fehlende Mehrfachvererbung am
elegantesten, dass man trotzdem noch flexible neue Formate zur
Anzeige/Ausgabe hinzufügen kann ohne bestehende Klassen ändern zu müssen
und trotzdem die Tabellen so unkompliziert wie möglich erstellen und
ausgeben kann?

--
Mit freundlichen Grüßen,
Christoph Herrmann

http://dragonprojects.de/
Christoph Herrmann [ Mi, 19 September 2007 16:32 ] [ ID #1824435 ]

Re: Elegante Möglichkeit das Problem der fehlenden Mehrfachvererbung zu umgehen

Christoph Herrmann schrieb:
> Hi,
>
> ich hoffe auch den Leuten von PHP ist Mehrfachvererbung ein Begriff.
> Aber man merkt ja bekanntlich erst wie schön solche Dinge sind, wenn Sie
> nicht mehr zur Verfügung stehen... :)

Ja. Die fehlende Mehrfachvererbung versucht man mit Interfaces zu
kompensieren. Wobei die schwache Typisierung von PHP da wieder riesige
Löcher reißt.

> Aber nun meine Situation:
>
> a) Ich habe eine Klasse zur Definierung einer Tabelle mit beliebig
> vielen Spalten und beliebig vielen Zeilen.
....
> b) Ich habe eine Klasse, die ein XML Node repräsentiert und die man als
> Childs an andere XML Nodes anhängen kann.
....
> c) Nun will ich der Datentabelle auch die Möglichkeit geben, sich zeigen
> zu können. Dafür gibt es verschiedene Formate wie .csv oder aber auch
> als HTML Tabelle, die ich auch gerne mit verschiedenen Klassen
> implementieren will (so kann ich neue Formate einfach durch neue Klassen
> hinzufügen, die von der Datentabelle abgeleitet sind). Das Problem
> besteht nun aber darin, dass diese Klasse alle Methoden benötigt, um die
> Datentabelle zu definieren, aber selbst von XML Node abgeleitet werden
> muss um als XML Node Objekt angehängt werden zu können (Datentabelle
> selbst wäre dann der <table> Tag). Daher müsste ich meine HTML
> Tabellenklasse von der Datentabelle, aber auch vom XML Node ableiten,
> was in PHP nicht möglich ist.

Ich denke bei deiner Beschreibung nicht an Vererbung, sondern eher an
das Decorator-Muster.
http://de.wikipedia.org/wiki/Decorator

So kannst du der Tabelle gleich mehrere Algorythmen zur Darstellung
mitgeben. Ganz ohne Vererbung.

XmlNode, HtmlNode und cvs sind dann nur dekorierer für Datatable.
Harald Stowasser [ Mi, 19 September 2007 17:12 ] [ ID #1824441 ]

Re: Elegante Möglichkeit das Problem der fehlenden Mehrfachvererbung zu umgehen

Hallo Christoph,

Christoph Herrmann schrieb:

> c) Nun will ich der Datentabelle auch die Möglichkeit geben, sich zeigen
> zu können. Dafür gibt es verschiedene Formate wie .csv oder aber auch
> als HTML Tabelle, die ich auch gerne mit verschiedenen Klassen
> implementieren will (so kann ich neue Formate einfach durch neue Klassen
> hinzufügen, die von der Datentabelle abgeleitet sind). Das Problem
> besteht nun aber darin, dass diese Klasse alle Methoden benötigt, um die
> Datentabelle zu definieren, aber selbst von XML Node abgeleitet werden
> muss um als XML Node Objekt angehängt werden zu können (Datentabelle
> selbst wäre dann der <table> Tag). Daher müsste ich meine HTML
> Tabellenklasse von der Datentabelle, aber auch vom XML Node ableiten,
> was in PHP nicht möglich ist.
> [...]
> Die Frage ist jetzt, wie umgeht man die fehlende Mehrfachvererbung am
> elegantesten, dass man trotzdem noch flexible neue Formate zur
> Anzeige/Ausgabe hinzufügen kann ohne bestehende Klassen ändern zu müssen
> und trotzdem die Tabellen so unkompliziert wie möglich erstellen und
> ausgeben kann?
>

Naja ich denke mal, dass dir für sowas auch die Leute von nebenan in der
C++ Gruppe (oder auch andere Sprachen die Mehrfachvererbung
unterstützen) auf die Finger hauen würden.
Ich würde das folgendermaßen lösen. Stichwort ist MVC (Model View
Control), wobei hier der Controller wegfällt. Dein Datatable ist das
Model hier musst du noch folgende Methoden implementieren:
1. getColCount() //gibt die Anzahl der Spalten zurück
2. getRowCount() //gibt die Anzahl der Zeilen zurück
3. getValueAt(int row, int col) //gibt das Objekt an der Zeile row und
der Spalte col zurück
Danach erstellst du deinen View. Dies könnte dann so aussehen:

<?php
class HTMLDatatableView extends XMLNode
{
private $model;

public function __construct(Datatable $model)
{
parent::__construct("table");
$this->model = $model;
createContent();
}

private function createContent()
{
for($i=0;$i<$this->model->getRowCount();i++)
{
$tr = new XMLNode("tr");

for($j=0;$j<$this->model->getColCount();$j++)
{
$td = new XMLNode("td");
$val = $this->model->getValueAt($i,$j);
//Hier kann ich nur raten wie deine Methode heißt
$td->setInnerText($val);
$tr->addChild($td);
}
$this->addChild($tr);
}
}
}
?>
So jetzt sind wir fertig und haben eine saubere Trennung zwischen den
Daten und der Darstellung. Jetzt kannst du auch eine Factory schreiben,
die dir einmal den Datatable anlegt und musst dies nicht für HTML, CSV,
.... jedesmal machen. Das wäre auch mit deiner Lösung nicht gegangen ;)

mfg
Andreas
Andreas.Eberhoefer [ Mi, 19 September 2007 18:13 ] [ ID #1824443 ]

Re: Elegante Möglichkeit das Problem der fehlenden Mehrfachvererbung zu umgehen

Harald Stowasser schrieb:
> Ich denke bei deiner Beschreibung nicht an Vererbung, sondern eher an
> das Decorator-Muster.
> http://de.wikipedia.org/wiki/Decorator
>
> So kannst du der Tabelle gleich mehrere Algorythmen zur Darstellung
> mitgeben. Ganz ohne Vererbung.
>
> XmlNode, HtmlNode und cvs sind dann nur dekorierer für Datatable.

An dieses Muster hab ich gar nicht mehr gedacht, hatte bisher mehr das
Komposite Muster vor Augen (ich liebe Muster ^^). Da hätte ich dann die
Ausgabe per Memberobjekt gewechselt.

Aber du hast natürlich recht, sowohl Kombosite als auch
Mehrfachvererbung haben den gravierenden Nachteil, dass nur ein
Algorithmus gleichzeitig gewählt werden könnte. Wobei mir jetzt noch
kein Fall einfällt, bei dem ich das gleichzeitig brauchen würde. :)

Wüsste jetzt nur nicht, wie ich das Programmiertechnisch umsetzen
könnte, aber da muss ich erstmal das Muster nochmal gründlich
durchnehmen, hab viele erstmal nur angelesen in meinem Buch.

--
Mit freundlichen Grüßen,
Christoph Herrmann

http://dragonprojects.de/
Christoph Herrmann [ Mi, 19 September 2007 18:22 ] [ ID #1824444 ]

Re: Elegante Möglichkeit das Problem der fehlenden Mehrfachvererbung zu umgehen

Andreas Eberhöfer schrieb:
> Naja ich denke mal, dass dir für sowas auch die Leute von nebenan in der
> C++ Gruppe (oder auch andere Sprachen die Mehrfachvererbung
> unterstützen) auf die Finger hauen würden.
> Ich würde das folgendermaßen lösen. Stichwort ist MVC (Model View
> Control), wobei hier der Controller wegfällt. Dein Datatable ist das
> Model hier musst du noch folgende Methoden implementieren:

Naja, aber habe ich kein MVC durch die Vererbung? Ich hab eine
Basisklasse, mit der man das Datenmodell erstellt und von dieser leite
ich die View Klasse ab, die dann von der Basisklasse die Modell Schicht
bekommt und zusätzlich seinen Anteil in Form des Views hinzugibt.
Vielleicht versteh ich das MVC Konzept noch nicht richtig, aber für mich
ist das eine schöne Trennung von Modell und View in zwei verschiedene
Klassen.

*nach etwas Überlegung* Ok, so schön wäre die Trennung doch nicht
gewesen. In deiner Version kann ich mein Objekt der Datentabelle dem
HTML View geben und danach dem View für .csv Format, also völlig frei
die Daten verschieden Anzeigen. Wäre auf jeden Fall mit Vererbung nicht
möglich gewesen, sobald ich mehrere Formate "gleichzeitig" erstellen will.

> 1. getColCount() //gibt die Anzahl der Spalten zurück
> 2. getRowCount() //gibt die Anzahl der Zeilen zurück
> 3. getValueAt(int row, int col) //gibt das Objekt an der Zeile row und
> der Spalte col zurück

Puh, das würde unter PHP bei einer Tabelle mit 10 Spalten und 100 Zeilen
1000 Methodenaufrufe mindestens bedeuten... :) Aber das wäre sicherlich
eine der saubersten Lösungen, da Sie für den View die komplette
Datenhaltung des Modells verbergt.

> Danach erstellst du deinen View. Dies könnte dann so aussehen:
>
> <?php
> class HTMLDatatableView extends XMLNode
> {
> private $model;
>
> public function __construct(Datatable $model)
> {
> parent::__construct("table");
> $this->model = $model;
> createContent();
> }
>
> private function createContent()
> {
> for($i=0;$i<$this->model->getRowCount();i++)
> {
> $tr = new XMLNode("tr");
>
> for($j=0;$j<$this->model->getColCount();$j++)

*anmerk* da jede Zeile die gleiche Anzahl an Spalten hat, wäre es
schlecht innerhalb der Schleife den Counter zu holen. ;) Hätten nicht
alle Zeilen die gleiche Anzahl an Spalten, komme ich hier eh nicht sehr
weit, weil dann wird es glaub etwas komplexer, da ich Zeilen verbinden
muss innerhalb der HTML Tabelle, was ich mit Sicherheit nicht brauche.

> {
> $td = new XMLNode("td");
> $val = $this->model->getValueAt($i,$j);
> //Hier kann ich nur raten wie deine Methode heißt
> $td->setInnerText($val);
> $tr->addChild($td);
> }
> $this->addChild($tr);
> }
> }
> }
> ?>
> So jetzt sind wir fertig und haben eine saubere Trennung zwischen den
> Daten und der Darstellung. Jetzt kannst du auch eine Factory schreiben,
> die dir einmal den Datatable anlegt und musst dies nicht für HTML, CSV,
> ... jedesmal machen. Das wäre auch mit deiner Lösung nicht gegangen ;)

Die Lösung ist ja mal einfach und vor allem so schön sauber. :) Und für
mich vor allem auf Anhieb verständlich. Ich erstell mir eine
Datentabelle und gebe diese den verschiedenen View Klassen zur Ausgabe.
Die Datentabelle baue ich dann am besten auf ein Interface auf und alle
Views auf ein gemeinsames Interface. So kann man beliebig beide
Schichten austauschen (ich glaub ich hab den Sinn des MVC Prinzips
gerade verstanden :) ).

--
Mit freundlichen Grüßen,
Christoph Herrmann

http://dragonprojects.de/
Christoph Herrmann [ Mi, 19 September 2007 18:56 ] [ ID #1824448 ]

Re: Elegante Möglichkeit das Problem der fehlenden Mehrfachvererbung zu umgehen

..oO(Christoph Herrmann)

>Andreas Eberhöfer schrieb:
>
>> 1. getColCount() //gibt die Anzahl der Spalten zurück
>> 2. getRowCount() //gibt die Anzahl der Zeilen zurück
>> 3. getValueAt(int row, int col) //gibt das Objekt an der Zeile row und
>> der Spalte col zurück
>
>Puh, das würde unter PHP bei einer Tabelle mit 10 Spalten und 100 Zeilen
>1000 Methodenaufrufe mindestens bedeuten... :)

Niemand zwingt Dich, jeden Wert einzeln abzufragen. Ich habe etwas
ähnliches in meinem Framework, da kann das Datenobjekt die gesamten
Daten in einem Rutsch als mehrdimensionales Array an den Viewer
zurückgeben. Oder z.B. auch zeilen- bzw. spaltenweise, je nach
Möglichkeiten und Anforderungen.

Micha
Michael Fesser [ Mi, 19 September 2007 20:25 ] [ ID #1824458 ]

Re: Elegante Möglichkeit das Problem der fehlenden Mehrfachvererbung zu umgehen

Michael Fesser schrieb:
> .oO(Christoph Herrmann)
>
>> Andreas Eberhöfer schrieb:
>>
>>> 1. getColCount() //gibt die Anzahl der Spalten zurück
>>> 2. getRowCount() //gibt die Anzahl der Zeilen zurück
>>> 3. getValueAt(int row, int col) //gibt das Objekt an der Zeile row und
>>> der Spalte col zurück
>> Puh, das würde unter PHP bei einer Tabelle mit 10 Spalten und 100 Zeilen
>> 1000 Methodenaufrufe mindestens bedeuten... :)
>
> Niemand zwingt Dich, jeden Wert einzeln abzufragen. Ich habe etwas
> ähnliches in meinem Framework, da kann das Datenobjekt die gesamten
> Daten in einem Rutsch als mehrdimensionales Array an den Viewer
> zurückgeben. Oder z.B. auch zeilen- bzw. spaltenweise, je nach
> Möglichkeiten und Anforderungen.

Ich hab diese Schnittstelle schon extra so gewählt. Ich würde halt ein
Interface mit den oben genannten Methoden definieren. Der View bekommt
dann dieses Interface übergeben. Damit kannst du dann auch folgendes
bauen, was mit deiner Lösung (mehrdimensionales Array) wieder wesentlich
langsamer ist, weil man erst die Daten kopieren muss.
Angenommen ich habe eine Liste mit meinen Kunden. Meine Kunden werden
durch die Klasse Kunde repräsentiert, diese hat die Attribute
kudennummer, vorname, nachname, ort. Jetzt kann ich eine Klasse
KundenTableModel erstellen, die dann so aussieht:

<?php
class KundenTableModel implements TableModel
{
private $kunden;

public function __construct($kunden)
{
$this->kunden = $kunden;
}

public function getColCount()
{
return 4;
}

public function getRowCount()
{
return count($this->kunden);
}

public function getValueAt($row,$col)
{
$kunde = $this->kunden[$row];

switch($col)
{
case 0: return $kunde->getKundenNummer();
case 1: return $kunde->getVorname();
case 2: return $kunde->getNachname();
case 3: return $kunde->getOrt();
default: return "Fehler";
}
}
}
?>

Ich denke mir einfach mal, das es besser ist die Schnittstellen so
schlank wie möglich zu halten. Mit dem Overhead beim Funktionsaufruf
kann ich recht gut leben, wobei ich den auch nicht für so groß halte.

mfg Andreas
Andreas.Eberhoefer [ Mi, 19 September 2007 21:08 ] [ ID #1824462 ]

Re: Elegante Möglichkeit das Problem der fehlenden Mehrfachvererbung zu umgehen

Andreas Eberhöfer schrieb:
> Ich denke mir einfach mal, das es besser ist die Schnittstellen so
> schlank wie möglich zu halten. Mit dem Overhead beim Funktionsaufruf
> kann ich recht gut leben, wobei ich den auch nicht für so groß halte.

ich bin kein Freund von High Performance Anwendungen (wer das ist, wird
sicherlich kein PHP benutzen). Aus dem Grunde finde ich die Lösung auch
wesentlich besser. Gerade weil es egal ist, wie die Objektklasse Ihre
Daten speichert und es somit auf vielfältige Weise einsetzbar ist.

Natürlich sollte die Performance nicht ins unermäßliche sinken, aber ich
denke es gibt wichtigere Orte, wo man sparen sollte als an der
Sauberkeit der Schnittstellen. :)

--
Mit freundlichen Grüßen,
Christoph Herrmann

http://dragonprojects.de/
Christoph Herrmann [ Mi, 19 September 2007 23:03 ] [ ID #1824467 ]

Re: Elegante Möglichkeit das Problem derfehlenden Mehrfachvererbung zu umgehen

Am 19.09.2007 17:12 Uhr schrieb "Harald Stowasser":
>
> Ich denke bei deiner Beschreibung nicht an Vererbung, sondern eher an
> das Decorator-Muster.
> http://de.wikipedia.org/wiki/Decorator
>

Ich denke dabei eher an das Builder-Muster:
http://de.wikipedia.org/wiki/Erbauer

Ein weiterer interessanter Artikel dazu:
http://www.javaworld.com/javaworld/jw-01-2004/jw-0102-toolbo x.html


Ein Dekorierer soll ja eher eine Klasse für einen Spezialfall erweitern,
nicht Darstellung und Implementierung trennen, so wie es der Erbauer macht.


migg
Michael Dreher [ Do, 27 September 2007 14:59 ] [ ID #1830939 ]

Re: Elegante Möglichkeit das Problem der fehlenden Mehrfachvererbung zu umgehen

Michael Dreher schrieb:

> Am 19.09.2007 17:12 Uhr schrieb "Harald Stowasser":
>> Ich denke bei deiner Beschreibung nicht an Vererbung, sondern eher an
>> das Decorator-Muster.

... Reihenfolge des Posts geändert..

> Ein Dekorierer soll ja eher eine Klasse für einen Spezialfall erweitern,
> nicht Darstellung und Implementierung trennen, so wie es der Erbauer macht.

ähhm das stimmt so nicht.
Der Erbauer trennt nicht Darstellung und Implementierung, sondern die
Konstruktion von der Repräsentation. Wobei mit Repräsentationen *nicht*
die Darstellung gemeint ist.

Auch hat der Decorator nichts mit /Spezialfällen/ zu tun. In Java z.B.
hast du fast immer mindestens einen Dekorator 'um' ein File-Objekt.
Hosen und Pullover sind heutzutage auch fast immer irgendwie Dekoriert.
Sogar Liebestöter-Unterhosen haben ein Feinrip-Dekor. Und Pizzas die
nicht mit einer Fleischinstanz dekoriert sind kommen mir nicht ins Haus!

Der Builder währe hier eher für die Konstruktion des Komplexen Objektes
'Tabelle' zuständig.

> Ich denke dabei eher an das Builder-Muster:
> http://de.wikipedia.org/wiki/Erbauer
>
> Ein weiterer interessanter Artikel dazu:
> http://www.javaworld.com/javaworld/jw-01-2004/jw-0102-toolbo x.html

Der Artikel hat nicht Viel mit dem Builder gemein. Der Exporter dort ist
kein Builder, sondern ein Strategie-Muster, da
public void export( Exporter builder ) mit einem konkretem
Strategie-Objekt konfiguriert wird, und die Exporter nur die Algorithmen
implementieren.

Das Beispiel ist somit eher die Kombination von Strategie und Erbauer.

Fazit:

* Es ist offen ob der OP überhaupt einen Erbauer haben möchte.
Grundsätzlich finde ich Erbauer toll ;-)
* Strategie und Decorator sind sich ziemlich ähnlich. Das Beispiel auf
javaworld kann auch mit Decoratoren verwirklicht werden.
* Ich dachte deshalb an Decoratoren, weil die den /Modifikatoren/ aus
Template-Sprachen ähnlicher sind. (wie z.B. bei Smarty[1])



*wink*
Harald.


[1]http://smarty.php.net/manual/de/language.modifiers.php
Harald Stowasser [ Do, 27 September 2007 16:25 ] [ ID #1830949 ]

Re: Elegante Möglichkeit das Problem der fehlenden Mehrfachvererbung zu umgehen

Harald Stowasser schrieb:
> ...
> Fazit:
>
> * Es ist offen ob der OP überhaupt einen Erbauer haben möchte.
> Grundsätzlich finde ich Erbauer toll ;-)
> * Strategie und Decorator sind sich ziemlich ähnlich. Das Beispiel auf
> javaworld kann auch mit Decoratoren verwirklicht werden.
> * Ich dachte deshalb an Decoratoren, weil die den /Modifikatoren/ aus
> Template-Sprachen ähnlicher sind. (wie z.B. bei Smarty[1])

Ich wüsste nicht, was für Vorteile mir ein Erbauer hier bringen würde.
Aber die bisher beste Lösung und die ich auch verwenden werden ist die
vom anderen Thread (keine Ahnung, welchem Muster dies entsprechen würde,
aber es löst mein Problem auf die einfachste, eleganteste und
flexibelste Weise, also was will ich mehr ^^):

Klasse Datatable zur Definition der Datenstruktur. Ein Objekt mit den
Definierten Daten übergebe ich dann einer View Klasse/Funktion, die die
Daten über eine definierte Schnittstelle ausliest und das Format für das
die Klasse/Funktion gedacht ist zurück gibt.

Als Beispiel:
<?php
$datatable = new Datatable();
$datatable->addColumn("Name", new StringFormatter());
$datatable->addColumn("E-Mail", new EmailFormatter());

$datatable->addRow(array("Name" => "Christoph", "E-Mail" =>
"herrmann [at] dragonprojects.de"));
$datatable->addRow(array("Name" => "Bla", "E-Mail" =>
"beispiel [at] bla.de"));

print DatatableToHtml($datatable);
print DatatableToCsv($datatable);
?>

Vorteil:
- verschiedenen Datenklassen möglich, die die Datenstruktur
definieren und über ein Interface Zugriff darauf bieten
- verschiedene unabhängige Ausgabeformate möglich mit dem selben
Objekt einer Datenstruktur, die beliebig hinzugefügt oder gewechselt
werden können
- unabhängige Erweiterung von Datenstrukturklassen oder
Ausgabeformate ohne die jeweils anderen ändern zu müssen

Nachteile sehe ich noch keine, höchstens dass meine Formatter etwas
anders umgesetzt werden müssen, dass die sich dem Ausgabemedium
anpassen. Aber dies mache ich dann wenn ich es benötige. Bisher sind die
Formatter nur für die HTML Ausgabe relevant, CSV wird eh ohne
Formatierung ausgegeben, also die Daten als solche.

--
Mit freundlichen Grüßen,
Christoph Herrmann

http://dragonprojects.de/
Christoph Herrmann [ Do, 27 September 2007 17:01 ] [ ID #1830953 ]
PHP » de.comp.lang.php.misc » Elegante Möglichkeit das Problem der fehlenden Mehrfachvererbung zu umgehen

Vorheriges Thema: was stoppt das script?
Nächstes Thema: fwrite wird immer langsamer