preg_replace php-code einfügen
bert
- php
Guten Morgen,
ich habe eine auto_replace Funktion für mein CMS geschrieben, damit man beim einfügen neuer Artikel selbstdefinierte TAGs benutzen kann. Die sieht so aus:
function auto_replace($content) {
unset($search_for);
unset($replace_with);
$search_for = array();
$replace_with = array();
$search_for[] = '/\[hinfo\/(.*)\/\]/iU';
$replace_with[] = '<span class="hinfo_a">\1</span>';
echo preg_replace($search_for, $replace_with, $content);
}
Nun möchte ich als search_for folgenden TAG hinzufügen [news/(.*)/], welcher dann ersetzt wird durch den entsprechenden Newseintrag.
Habe für die News bereits ein Template, welches beispielsweise beim Newsarchiv genutzt wird. Alles was ich nun brauche, ist, dass der TAG ersetzt wird durch folgenden Code:
include("_db_sub_connect.php");
$newsquery = mysql_query("SELECT DATE_FORMAT(Datum, '%e.%c.%y') as Datum_tit, Inhalt, Titel, ID, Links, Subtitel, Kategorie, Pic_thumb, Pic, Pictext, Quelle, c FROM news WHERE ID='\1'");
include('_news_anzeigen.php');
Kann ich im auto_replace irgendwie diesen neuen php-Code aufrufen, ohne, dass dieser direkt beim Laden der Datei aufgerufen wird, die mein auto_replace Funktion enthält?
Komme auf keinen Weg, wie ich mit meinem TAG die News über mein Template laden kann.
Freue mich über jede Hilfe!
Gruß
Hi!
ich habe eine auto_replace Funktion für mein CMS geschrieben, damit man beim einfügen neuer Artikel selbstdefinierte TAGs benutzen kann. Die sieht so aus:
function auto_replace($content) {
unset($search_for);
unset($replace_with);
$search_for = array();
$replace_with = array();
Die beiden unset() sind unnötig. Variablen existieren innherhalb einer Funktion nicht vor ihrer ersten Verwendung. Du löschst also etwas nicht vorhandenes. Zudem wird durch das anschließende Zuweisen eines leeren Arrays bereits definitiv ein Wert gesetzt und etwas vorher drin stehendes verworfen.
> Habe für die News bereits ein Template, welches beispielsweise beim Newsarchiv genutzt wird. Alles was ich nun brauche, ist, dass der TAG ersetzt wird durch folgenden Code:
> Kann ich im auto\_replace irgendwie diesen neuen php-Code aufrufen, ohne, dass dieser direkt beim Laden der Datei aufgerufen wird, die mein auto\_replace Funktion enthält?
Wann soll er denn tatsächlich ausgeführt werden?
Du brauchst ja für deinen News-Tag eine Sonderbehandlung, indem du zum Beispiel die Funktion erweiterst. Da die jetzige Funktion etwas ausgibt sehe ich eigentlich kein Problem, wenn du den News-Code direkt ausführst und dessen Ergebnis ausgibst.
Lo!
Wann soll er denn tatsächlich ausgeführt werden?
Der News-Datensatz mit der ID, die angegeben ist, soll abgerufen werden und wie in der datei _news_anzeigen.php vorgegeben angezeigt werden.
Du brauchst ja für deinen News-Tag eine Sonderbehandlung, indem du zum Beispiel die Funktion erweiterst. Da die jetzige Funktion etwas ausgibt sehe ich eigentlich kein Problem, wenn du den News-Code direkt ausführst und dessen Ergebnis ausgibst.
Ich möchte, dass die Vorgabe aus meiner template Datei genutzt wird und nicht den gesamten code in die auto_replace Funktion einfügen, da man dann bei Änderungen immer darauf achten muss, beide Dateien einheitlich zu ändern. Daher soll der Code aus der Datei gelesen werden.
Also würde ich gerne folgendes schreiben:
$search_for[] = '/[news/(.*)/]/iU';
$replace_with[] = 'include("_db_sub_connect.php");$newsquery = mysql_query("SELECT DATE_FORMAT(Datum, '%e.%c.%y') as Datum_tit, Inhalt, Titel, ID, Links, Subtitel, Kategorie, Pic_thumb, Pic, Pictext, Quelle, c FROM news WHERE ID='\1'");
include("_news_anzeigen.php");';
Hi!
Du brauchst ja für deinen News-Tag eine Sonderbehandlung, indem du zum Beispiel die Funktion erweiterst. Da die jetzige Funktion etwas ausgibt sehe ich eigentlich kein Problem, wenn du den News-Code direkt ausführst und dessen Ergebnis ausgibst.
Ich möchte, dass die Vorgabe aus meiner template Datei genutzt wird und nicht den gesamten code in die auto_replace Funktion einfügen, da man dann bei Änderungen immer darauf achten muss, beide Dateien einheitlich zu ändern. Daher soll der Code aus der Datei gelesen werden.
Du hast dann ein Problem. Bei hinfo hast du einen String, der HTML-Code enthält und ergänzt werden soll, bei news übergibst du ebenfalls einen String, der aber PHP-Code enthält, der ausgeführt werden soll. Wie willst du beide String-Inhalte voneinander unterscheiden, oder besser: wie soll preg_replace() den Unterschied feststellen? Es gibt zwar den Modifizierer "e", mit dem preg_replace() PHP-Code evaluieren/ausführen kann, aber der nützt dir nur im news-Fall was. Für den hinfo-Fall musst du dann Ersetzungen ungefähr so notieren "?><span>\1</span><?php". Wenn du das "e" generell hinzufügst landest du nämlich im PHP-Modus, den du für Nicht-PHP-Code verlassen musst. So eine Lösung ist alles andere als elegant. Du könntest die Verarbeitung aufteilen in HTML-Ersetzungen und Code-Ersetzungen, die du jeweils getrennt bearbeiten lässt, also
$html_search_for, $html_replace_with und preg_replace() sowie
$code_search_for, $code_replace_with und preg_replace() mit Modifier e
Aber es geht meines Erachtens nach noch besser, wenn du Callbacks verwendest, denn Code sollte Code bleiben. Wenn du ihn in eienn String packst ist er schlecht wartbar. Für jede Ergänzung, für die du Code brauchst, erstellst du eine Callback-Funktion (bei der du die Hinweise zu preg_replace_callback() beachtest). $html_search_for und $html_replace_with wird wie bisher behandelt und zusätzlich erstellst du es $callback_search_for, $callback_replace_with (mit dem Namen der Funktion) und lässt es mit preg_replace_callback() bearbeiten.
Wenn dir schon PHP ab Version 5.3 zur Verfügung steht, kannst du auch mit anonymen Funktionen statt Callbacks arbeiten.
Lo!
Aber es geht meines Erachtens nach noch besser, wenn du Callbacks verwendest, denn Code sollte Code bleiben. Wenn du ihn in eienn String packst ist er schlecht wartbar. Für jede Ergänzung, für die du Code brauchst, erstellst du eine Callback-Funktion (bei der du die Hinweise zu preg_replace_callback() beachtest). $html_search_for und $html_replace_with wird wie bisher behandelt und zusätzlich erstellst du es $callback_search_for, $callback_replace_with (mit dem Namen der Funktion) und lässt es mit preg_replace_callback() bearbeiten.
Abgeänderte Funktion ist dann:
[..]
$code_search_for[] = '/\[news\/(.*)\/\]/iU';
$code_replace_with[] = 'include("_db_sub_connect.php");$newsquery = mysql_query("SELECT DATE_FORMAT(Datum, \"%e.%c.%y\") as Datum_tit, Inhalt, Titel, ID, Links, Subtitel, Kategorie, Pic_thumb, Pic, Pictext, Quelle, c FROM news WHERE ID=\"\1\"");include("_news_anzeigen.php");';
echo preg_replace($search_for, $replace_with, preg_replace_callback($code_search_for, $code_replace_with, $content));
Nun gibt er einfach [news/29/] aus, was er eigentlich ersetzen sollte..
nehme alles zurück.
bin noch am ausprobieren. war mal wieder zu voreilig.
melde mich aber bestimmt nachher nochmal.
danke!
also:
Ansatzweise funktioniert es jetzt wie folgt:
function _get_news_now($matches) {
include("_db_sub_connect.php");
$newsquery = mysql_query("SELECT DATE_FORMAT(Datum, '%e.%c.%y') as Datum_tit, Inhalt, Titel, ID, Links, Subtitel, Kategorie, Pic_thumb, Pic, Pictext, Quelle, c FROM news WHERE ID='$matches[1]'");
include("_news_anzeigen.php");
}
function auto_replace($content) {
$search_for = array();
$replace_with = array();
$code_search_for = array();
$code_replace_with = array();
$search_for[] = '/\[hinfo\/(.*)\/\]/iU';
$replace_with[] = '<span class="hinfo_a">\1</span>';
[..]
echo preg_replace($search_for, $replace_with, preg_replace_callback('/\[news\/(.*)\/\]/iU', '_get_news_now', $content));
}
Soweit, sogut.
Bleiben noch 2 Probleme:
1. Der Newsinhalt wird ganz am Anfang von $content eingefügt, steht also immer ganz oben auf der Seite, auch wenn der TAG erst später im Text auftaucht. Kann ich das trotz callback verhindern?
2. Wenn innerhalb der News TAGs wie etwa [hinfo/blabla/] auftauchen, sollen diese auch ersetzt werden. Dachte eigentlich, das wäre hier der Fall, da zunächst die callback aufgerufen wird und den code ersetzt und das Ergebnis dann mit dem normalen preg-replace "bearbeitet" wird.
Mein Bauchgefühl sagt mir irgendwie, dass die beiden Probleme zusammenhängen und man beides gleichzeitig beheben kann. Komme nur nicht drauf wie.
Danke nochmal für deine ausführliche Hilfe!
Hi!
- Der Newsinhalt wird ganz am Anfang von $content eingefügt, steht also immer ganz oben auf der Seite, auch wenn der TAG erst später im Text auftaucht. Kann ich das trotz callback verhindern?
Was hast du im PHP-Handbuch gelesen, soll die Callback-Funktion machen? Vermutlich, dass der Text zurückgegeben und nicht sofort ausgeben werden soll (was du vermutlich in der zweiten Inklude-Datei machst).
- Wenn innerhalb der News TAGs wie etwa [hinfo/blabla/] auftauchen, sollen diese auch ersetzt werden. Dachte eigentlich, das wäre hier der Fall, da zunächst die callback aufgerufen wird und den code ersetzt und das Ergebnis dann mit dem normalen preg-replace "bearbeitet" wird.
Wenn ... siehe 1.
Lo!
Was hast du im PHP-Handbuch gelesen, soll die Callback-Funktion machen? Vermutlich, dass der Text zurückgegeben und nicht sofort ausgeben werden soll (was du vermutlich in der zweiten Inklude-Datei machst).
richtig. ein einfaches "return include()" macht das selbe und gibt zusätzlich an der richtigen Position eine 1 aus (true).
Versuche also gerade, irgendwie den inhalt des includes, welches auch php-code enthält (nämlich Variablen), anstatt auszugeben über das return weiterzureichen.
Finde aber keinen Lösungsansatz. Brauche ich da etwa noch eine callback-Funktion.
Suche gerade irgendeine Funktion, die einfach statt include das Ergebnis in einer Variable speichert..
so klappts:
function _get_news_now($matches) {
include("_db_sub_connect.php");
$newsquery = mysql_query("SELECT DATE_FORMAT(Datum, '%e.%c.%y') as Datum_tit, Inhalt, Titel, ID, Links, Subtitel, Kategorie, Pic_thumb, Pic, Pictext, Quelle, c FROM news WHERE ID='$matches[1]'");
return include_in_var("_news_anzeigen.php", $newsquery);
}
hab mir eine Funktion gebastelt, die den Inhalt in einer Variable zurückgibt (include_in_var):
function include_in_var($page, $_newsquery) {
ob_start(); //startet Buffer
$newsquery = $_newsquery;
include($page); //datei.php ist jetzt im Buffer
$var=ob_get_contents(); //Buffer wird in $var geschrieben
ob_end_clean(); //Buffer wird gelöscht
return $var; //$var wird weiter verwendet
}
Danke für die Unterstützung!
Hi!
hab mir eine Funktion gebastelt, die den Inhalt in einer Variable zurückgibt (include_in_var):
Du kannst dir die Umstände mit der Ausgabepufferung sparen, wenn du eben keine echo-Anweisungen verwendest sondern das Ergebnis der Datenbankabfrage in einem String zusammenstellst und den zurückgibst. Das setzt aber auch voraus, dass du Codeteile nicht primär in Inklude-Dateien kapselst sondern in Funktionen.
Eine Funktion hat die Aufgabe mit den übergebenen Parametern ein Ergebnis zu erzeugen. Idealerweise erzeugt sie dabei keine Nebenwirkungen (side effects) oder ist von äußeren Gegebenheiten abhängig (wie globale Variablen).
Deine News-Abfragefunktion sollte nicht die Entscheidung vorwegnehmen, was mit der News passiert. Wenn du sie sofort ausgibst, ist eine Weiterverarbeitung unmöglich oder zumindest erschwert (siehe deine zusätzliche Ausgabepufferung). Also erstell dir eine Funktion, die einen Parameter entgegennimmt, der News-ID enthält. Als Ergebnis produziert sie einen String mit der News. Der Aufrufer der Funktion kann dann über die weitere Verwendung des Rückgabewertes entscheiden, so wie er es gerade braucht.
Lo!