Hallo!
Lazy-Irgendwas bedeutet, dass das Programm "zu faul" ist, dieses Irgendwas sofort zu tun. Stattdessen wartet es damit, bis es wirklich notwendig ist, also wenn eine konkrete Anforderung nach den Daten besteht. Wenn es Glück hat, nimmt der Programmfluss einen anderen Verlauf, bei dem die Daten doch nicht benötigt werden, und es hat sich die Arbeit gespart.
Das klingt nett, aber sehe ich es dann richtig, dass Lazy-Fetch vor allem Performance-Vorteile mit sich bring?
Dann wäre das Einschalten des Ausgabepuffers die erste Amtshandlung der Ausgabelogik, und das stünde dann zwischem dem Erzeugen des Flags und seiner ersten Anwendung. Gut, das ist jetzt auch kein großer Abstand, aber wir nehmen einfach mal an, dass das Programm später erweitert wird und sich der Abstand dadurch vergrößert. Oder dir fällt auf, dass die Abfrage doch schon weiter oben benötigt wird, oder oder oder. Jedenfalls willst du doch eine klare Trennung, auch um damit Erfahrung zu sammeln, und da kannst du ruhig mal konsequent sein, auch wenn dir das redundant vorkommt. Dieser kleine Zusatzschritt bringt deinen Server nicht um - er wird nicht mal messbar sein.
Da gebe ich dir absolut Recht. Ich war nur davon ausgegangen, dass das so nicht sein könnte, weil ich nur die Redundanz, nicht aber die Vorteile daraus gesehen habe. Inzwischen bin ich überzeugt. :-)
Zusammenfassend, deine Ausgabe beginnt also damit, gepuffert den Hauptinhalt zu erzeugen, der später an der gewünschten Stelle in den Rest der Seite eingefügt wird.
Genau so.
Ist das komplett unsinnig?
Nö. Das könnte im Gegenteil sogar vorteilhaft, weil du damit das Wesentliche zuerst machst und "der unbedeutende Rest" irgendwo hinten steht. Allerdings erhöht sich damit auch die Komplexität wieder ein wenig, einerseits durch die zusätzliche Pufferung und andererseits durch die nicht mehr lineare Reihenfolge beim Erstellen der Ausgabe. Doch das würde ich jetzt nicht überbewerten wollen, weil es mir nicht als ein wirklicher Nachteil erscheint.
Danke für deine Einschätzung. Ich sehe das ähnlich: Der Nutzen, dass der Hauptinhalt separat vom „unbedeutenden Rest“ steht ist mir mehr wert als eine lineare Reihenfolge.
Wenn ich so darüber nachdenke, wäre es vermutlich zumindest ein Ansatz, das Konzept aus der Template-Datei konsequent anzuwenden und die „Datei für’s Seitenspezifische“ möglichst unter der Verwendung der von dir verlinkten alternativen Syntax nach Eingabe und Verarbeitung zu trennen. Klingt das vernünftig?
Du meinst, statt einen großen, mehrzeiligen String mit Platzhaltern zu erstellen, die in einem zweiten Schritt mit printf() ersetzt werden, lieber gleich HTML erzeugen, in das die Werte eingefügt werden? Hat zumindest den Vorteil, dass ein Editor oder eine IDE das HTML als solches erkennen können, und dafür Syntax-Unterstützung anbieten können. Wie es mit der Übersicht aussieht, muss man sehen. Einerseits kommt der die Ausgabe eines Wertes genau an die Stelle, an der er stehen soll, andererseits ist bei der Platzhaltergeschichte das Drumherum besser lesbar, weil da nur ein kleines %s steht und der HTML-Code nicht durch PHP-Code zerrissen wird. Da muss man fallweise entscheiden, was der bessere Kompromiss ist. Wenn so ein HTML-Tag mit mehreren Attributen drin mehrfach durch PHP-Code unterbrochen wird, bekommt nicht nur die Syntaxunterstützung ein Problem, die Teile auseinanderzuhalten, auch das Auge des Betrachters. Sowas würde ich dann eher einzeln einem printf() zum Zusammenbauen übergeben. Nur-HTML-Blöcke stehen besser für sich zwischen ?> und <?php.
Gestern hatte ich eine Idee, welchen Mittelweg ich hier für meine Zwecke momentan für am besten geeignet halte. Besonders gefällt mir, dass die Vorteile von HTML gespickt mit PHP-Ausgaben mit denen von Platzhaltern und printf()
kombiniert werden:
/* Verarbeitung: Datenbank lesen und schreiben, Ergebnisse von Abfragen in Arrays kopieren (z.B. $accounts), Kontrollvariablen setzen
Verarbeitungsschritte … */
/*************** Ausgabe: ****************/
// Wurde ein Konto zum Löschen markiert?
if ($confirm_delete_account): ob_start(); ?>
<p>Wirklich das Konto %1$s löschen? (Besitzer: %2$s)</p>
<form action="index.php?view=manage_accounts" method="post">
<fieldset>
<input type="hidden" name="account_id" value="%3$s" />
<button name="confirm" value="ok" type="submit">Ja</button>
<button name="confirm" value="" type="submit">Nein</button>
</fieldset>
</form>
<?php o($_POST['delete_account_name'], $_POST['delete_account_owner_name'], $_POST['delete_account_id']);
endif;
if ($accounts_exist):
echo '<table>';
ob_start();
foreach ($accounts as $account):?>
<tr>
<td>%1$s</td>
<td>%3$s (%4$s)</td>
<td>
<form action="index.php?view=manage_accounts" method="post">
<fieldset><input type="hidden" name="delete_account_id" value="%2$s" />
<input type="hidden" name="delete_account_name" value="%1$s" />
<input type="hidden" name="delete_account_owner_name" value="„%4$s“" />
<input type="submit" value="entfernen" /></fieldset>
</form>
</td>
</tr>
<?php o($account['account_name'], $account['account_id'], $account['owner_id'], $account['owner_name']);
endforeach;
echo '</table>';
else:
echo '<p>Keine Konten</p>';
endif;
Die dazugehörige Funktion o:
function o ()
{
$format = ob_get_contents();
ob_end_clean();
$args = array();
foreach (func_get_args() as $arg)
{
if (is_array($arg) && isset($arg[0]))
{
if (isset($arg[1]) && $arg[1] == false)
{
$args[] = $arg[0];
}
else
{
$args[] = htmlspecialchars($arg[0]);
}
}
elseif(!is_array($arg))
{
$args[] = htmlspecialchars($arg);
}
else
{
$args[] = 'Ungültiger Parameter übergeben!';
}
}
vprintf($format, $args);
}
Das HTML steht also gespickt mit Platzhaltern und eingebettet in die alternative Kontrollstruktursyntax außerhalb von PHP-Tags. Allerdings landet jeder einzelne HTML-Bereich in einem eigenen Ausgabepuffer. Die Ausgabefunktion o()
füttert vprintf()
mit dem HTML-Platzhalter-Mix als $format
und nimmt als Parameter entgegen, wodurch die Platzhalter ersetzt werden sollen. Werden Arrays übergeben, so kann auch festgelegt werden, ob der Parameter noch für den HTML-Kontext behandelt werden muss.
Entschuldige bitte, wenn ich so „unmündige“ Fragen nach richtigem und falschem Vorgehen stelle, aber ich habe das Gefühl, noch einige grundlegend falschen Vorstellungen über eine ordentliche Struktur zu haben …
Entwicklungspotential zu haben ist für mich kein Grund, um Entschuldigung zu ersuchen. Das hat doch jeder.
Freut mich, dass du das so siehst. :-)
Vor allem frage ich mich immer wieder Folgendes: Im Moment reden wir nur über die Ausgabe von HTML - ein Kontext, in dem es mich auch überzeugt, dass eben PHP- und HTML-Code nicht völlig zu trennen sind. Aber angenommen (rein hypothetisch, habe ich nicht vor), ich wollte mir genauso die Möglichkeit offen halten, zur Ausgabe beispielsweise ein Bild zu erzeugen. Das würde doch bedeuten, dass das, was mein Verarbeitungs-Part an die Ausgabe weitergibt, völlig frei von jeglicher HTML-Auszeichnung sein müsste. Allerdings ist doch genau das scheinbar weder sinnvoll noch unbedingt notwendig.
Ein Bild hat keinen HTML-Code. Aber wenn du es erst erzeugen musst, dann doch aus dem Grund, dass es aus mehreren Teilen zusammenzusetzen ist - beispielsweise ein Hintergrund und individuelle Schrift drauf - oder durch Bearbeitung aus einem anderen Bild entstehen soll - wie zum Beispiel bei einer Verkleinerung. Auch hier kann man das EVA-Prinzip anwenden, wenn es sich lohnt. Der größte Teil wird jedoch der Verarbeitung zuzuordnen sein und die Ausgabe beschränkt sich auf ein oder mehrere header()-Aufrufe und ein imagejpeg() und Konsorten. Da würde ich einfach nur die einzelnen Bildverarbeitungsschritte kennzeichnen und wenn es hilfreich erscheint Berechnungen in Funktionen auslagern.
Was ich meinte ging in eine etwas andere Richtung - ich versuch’s nochmal besser zu erklären:
Angenommen, ich möchte eine Liste darstellen. Dann sollte meine Verarbeitung doch ein Array mit Listenelementen liefern. Und diese Listenelemente sollten doch frei von irgendwelcher Auszeichnung wie z.B. <li>
sein, um zu ermöglichen, dass ich die Listenelemente nicht nur in einem HTML-Dokument ausgeben kann, sondern meine Ausgabe z.B. auch ein Bild erzeugen kann, auf welchem die Liste abgebildet ist oder ein RSS-Feed, welches nur die ersten paar Listenelemente will, diese jedoch auch frei von irgendwelchen HTML-Elementen, da die Listenelemente vielleicht als Aufzählung dargestellt werden sollen etc.
Solche (für mich momentan hypothetischen) Anwendungsfälle sind es, an die ich denke, wenn ich davon spreche, dass in bestimmten Fällen Verarbeitung und Ausgabe doch völlig und nicht nur „so gut wie möglich“ getrennt sein müssten.
Ich hoffe, ich rede keinen völligen Blödsinn - bin in dieser Hinsicht etwas verwirrt.
Nun, dann hoffe ich doch, noch ein paar weitere Klarheiten beseitigt zu haben. (Das hab ich grad mit einem schelmischen und einem ernsten Auge gesagt, denn je weiter man in den Ozean abtaucht, desto mehr erkennt man von seiner unendlich erscheinenden Komplexität und dem eigenen Unvermögen, alles ergründen zu können.)
Ich denke, du hast erfolgreich einige Klarheiten beseitigt und einige geschaffen. Aber so ist es wahrscheinlich immer, da das Verständnis des Einen immer auch Fragen nach vielen andern mit sich bringt.
Hübsche Ozean-Metapher - ich mag da auch Sokrates ganz gern: Ich weiß, dass ich nicht weiß.
Schönen Sonntagabend noch,
Claudius