php-resource




Archiv verlassen und diese Seite im Standarddesign anzeigen :
[PHP5] [Optimierung] Platzhalter durch Inhalt externe Datei ersetzen


 
Laire
15-02-2009, 20:59 
 
Hallo,

ich schreibe gerade an einem kleinen CMS System. Ich möchte es ermöglichen durch einen einfachen Text im Editor den Inhalt von externen Datein aus einem bestimmten Verzeichnis einzubinden.

Zur Erklärung:
- Die Dateien müssen im Verzeichnis includes liegen
- php Code soll nicht interpretiert werden
- Wenn die Datei nicht existiert soll eine Fehlermeldung kommen
- der Befehl zum einbinden ist: include[Dateiname]



// Überprüfung ob in dem Text ein include vorkommt
if(stripos($output, 'include[') !== FALSE){
//Wenn ja dann alle raussuchen
preg_match_all("/include\[(.*?)\]/U", $output, $include);
//Ergebnisse verarbeiten
foreach($include[0] as $key => $var){
//Pfad und Dateiname festlegen
$file = 'includes/'.$include[1][$key];
//Überprüfen ob Dateiname existiert
if(file_exists($file)){
//Wenn ja dann Inhatlt der Datei holen
$content = file_get_contents($file);
}else{
//Wenn nicht dann Fehlermeldung
$content = '<h1>Die eingebundene Datei exestiert nicht!</h1>';
}
//Ersetzten des include durch Dateiinhalt bzw. Fehlermeldng
$output = (str_replace($var, $content, $output));
}
}


Meine Fragen:
Macht es Sinn vorher zu Überprüfen ob es ein include gibt? Habe das eingebaut weil bei php.net folgendes steht über preg_match, gilt bestimmt auch für preg_match_all:
Verwenden Sie nicht preg_match(), wenn Sie nur überprüfen wollen, ob eine Zeichenkette in einer anderen Zeichenkette enthalten ist. Verwenden Sie dafür stattdessen die Funktionen strpos() oder strstr(), die das schneller erledigen.

Die Lösung funtioniert, aber würdet Ihr anders herangehen?

 
php_fussel
15-02-2009, 21:30 
 
Wenn Du ein "kleines" CMS programmieren willst, empfehle ich Dir eine template-Klasse ...

Gruß php_fussel

 
Laire
15-02-2009, 21:35 
 
Das ist doch schon erledigt... Ausserdem wird es kein öffentliches CMS sondern nur für eine Seite.

 
php_fussel
15-02-2009, 21:46 
 
Irgendwie ist es schwer verständlich, was Du bezweckst ...! Du schreibst, Du willst in einem Text vorkommende include()s raussuchen und diese dann durch externen Text aus einer Datei ersetzen oder was ...? Ich versteh nicht was das soll!

 
Laire
15-02-2009, 21:53 
 
Also,

das ganze CMS System ist nur für eine Seite. Es gibt bereits fertige Inhalte, die als html Datei vorliegen. Um nun ständiges Paste&Copy zu vermeiden kann man ganz einfach in dem online WYSIWYG Editor der Unterseiten include[Dateiname] eingeben und der Text wird ersetzt durch den Inhalt der Datei. Dieses ist nicht die include() Funktion von PHP.

Ich setzte das ein, da es an einigen Stellen zum Einsatz von Javascript kommt und die Struktur für die Elemente sehr genau sein müssen, was in dem WYSIWYG ziemlich blöd zu bearbeiten ist. An diese Dateien müssen auch evtl. andere Nutzer nicht ran, da sie einen festen Inhalt haben.

 
fireweasel
16-02-2009, 00:02 
 
Original geschrieben von Laire
Macht es Sinn vorher zu Überprüfen ob es ein include gibt?
1. Nein, weil Sinn nicht gemacht wird (http://www.schweikhardt.net/wider-die-sinnmacher.html) ... ;-)
2. Nein, weil file_get_contents() FALSE zurückliefert, wenn die Datei nicht existiert. Und diesen Rückgabewert würde ich abfragen. Dass man zu diesem Zweck file_get_contents() besser mit dem @-Operator versieht, weil sonst eventuell eine dämliche Warnung ausgegeben wird, ist zwar nicht besonders elegant -- aber wir spielen hier ja auch mit PHP und nicht mit einer seriösen Programmierumgebung. ;-)

Habe das eingebaut weil bei php.net folgendes steht über preg_match, gilt bestimmt auch für preg_match_all:

Verwenden Sie nicht preg_match(), wenn Sie nur überprüfen wollen, ob eine Zeichenkette in einer anderen Zeichenkette enthalten ist. Verwenden Sie dafür stattdessen die Funktionen strpos() oder strstr(), die das schneller erledigen.

Und was hat das mit dem Überprüfen der Existenz einer Datei zu tun?

Nebenbei ist dieser Hinweis unvollständig. Es gibt auch noch andere sinnvolle Anwendungen der preg_...()-Funktionen. Ein Beispiel: Solange PHP keine eingebauten Unicode-Strings (und dazu passende Funktionen) hat, ist die PCRE-Erweiterung beim Hantieren mit UTF-8-Zeichenketten doch sehr hilfreich.


preg_match_all("/include[(.*?)]/U", $output, $include);

Ja, wenn du dich beim Basteln von PCRE so ungeschickt anstellst, dann solltest du vielleicht tatsächlich dem Rat des PHP-Handbuchs folgen und nur strpos(), strstr() und Konsorten einsetzen. ;-)
Erst machst du den Regex mit "/U" UNGREEDY und dann drehst du den Effekt mit ".*?" wieder um ... "(.*)" ohne "/U" am Ende hätts sicher auch getan.

 
Laire
16-02-2009, 00:13 
 
Original geschrieben von Laire
Meine Fragen:
Macht es Sinn vorher zu Überprüfen ob es ein include gibt? Habe das eingebaut weil bei php.net folgendes steht über preg_match, gilt bestimmt auch für preg_match_all:


Die Lösung funtioniert, aber würdet Ihr anders herangehen?

War bezogen auf das stripos am Anfang, ich könnte das ja weglassen und gleich mit preg_match_all arbeiten.

Bei

preg_match_all("/include[(.*?)]/U", $output, $include);

hatte ich angenommen, das (.*?) steht einfach nur für "alle zeichen dazwischen"

 
fireweasel
16-02-2009, 01:28 
 
Original geschrieben von Laire
War bezogen auf das stripos am Anfang, ich könnte das ja weglassen und gleich mit preg_match_all arbeiten.

Ach sooo ...
In dem Fall ist ein davorgesetztes stripos() natürlich Quark. Im Falle des Nichtvorhandenseins von 'include[' ackert das erst den ganzen Text durch und das auch noch case-insensitive. Das Gleiche macht preg_match() doch auch, du solltest allerdings den Modifikator '/i' nicht vergessen, wenn du auch Großbuchstaben finden möchtest.

Bei

preg_match_all("/include[(.*?)]/U", $output, $include);

hatte ich angenommen, das (.*?) steht einfach nur für "alle zeichen dazwischen"
Also, ich sach ma so:
Das '.' steht für (fast) jedes beliebige Zeichen.
Das '*' steht für eine beliebige Anzahl (inklusive Null).
Das '?' steht (hier) für den kürzestmöglichen Teilstring, der auf das Suchmuster passt.
Wenn du das dämliche '/U' weglässt. Mit '/U' kehrt sich die Funktion des '?' um.

Und ich würde sogar soweit gehen, dir folgenden RegEx vorzuschlagen:
'/include\[[^\]]+\]/i'
Das findet 'include' (Groß-/Kleinschreibung egal),
gefolgt von einer '[',
gefolgt von mindestens einem (fast) beliebigen Zeichen[1], das aber kein ']' ist,
gefolgt von ']'.

--

[1] Du trägst ja hier Dateinamen ein. Und die sollten schon mindestens ein Zeichen haben.
[2] Ach, und wie immer den richtigen RegExp bitte über die Zitieren-Funktion kopieren. Sonst fehlen einige Backslashes. Gibts denn von dieser dämlichen Board-Software nicht mittlerweile eine aktualisierte Version, die Benutzer-Eingaben mit Verstand behandelt?


Alle Zeitangaben in WEZ +2. Es ist jetzt 17:15 Uhr.