BBCodes ersetzen funktioniert nur einmal

Stelo

Erfahrenes Mitglied
Heyho,

ich arbeite gerade an einem kleinen Forum
Aus einem Tut hab ich folgendem Code um die BBCodes zu ersetzen:
PHP:
<?php

$text = preg_replace("/\[ B\](.*)\[ \/B\]/Usi", "<b>\\1</b>", $text);
$text = preg_replace("/\[ I\](.*)\[ \/I\]/Usi", "<i>\\1</i>", $text);
$text = preg_replace("/\[ U\](.*)\[ \/U\]/Usi", "<u>\\1</u>", $text);
$text = preg_replace("/\[ COLOR=(.*)\](.*)\[\/COLOR\]/Usi", "<font color=\"\\1\">\\2</font>", $text);

$text = preg_replace_callback("/\[ URL=(.*)\](.*)\[ \/URL\]/Usi", 'linkLenght', $text);
$text = preg_replace_callback('#(( |^)(((ftp|http|https|)://)|www.)\S+)#mi', 'linkLenght', $text);


// Prüft die Linklänge und passt sie gegebenenfalls an
    // wird für preg_replace_callback definiert
    function linkLenght($treffer)
    {
        // $treffer[1] ist die URL
        $url = trim($treffer[1]);
        // $treffer[2] ist der Ausgabename
        // wurde kein Name angegeben, wird die URL als Name gewählt
        if(strlen(trim($treffer[2]))!=0)
            $linkname = $treffer[2];
        else
            $linkname = $treffer[1];
        // legt eine maximale Länge von 50 Zeichen fest
        // Ausnahme bei [ img]-Tags
        if(strlen($linkname)>50 AND !substr_count(strtolower($linkname), '[ img]') AND !substr_count(strtolower($linkname), '[ /img]'))
            $linkname = substr($linkname, 0, 45-3)."...".substr($linkname, -5);
        // Rückgabelink
        $ergebnis = "<a href=\"".$url."\" target=\"_blank\">".$linkname."</a>";
        return $ergebnis;
    }

    



$text = preg_replace_callback("/\[img\](.*)\[\/img\]/Usi", 'picSize', $text);
// Prüft die Bildausmaße und passt sie gegebenenfalls an
    // wird für preg_replace_callback definiert
    function picSize($treffer)
    {
    // falls keine gültige Adresse angegeben wurde, wird die Fehlermeldung unterdrückt
        $size = @getimagesize($treffer[1]);
    if ($size[0] > 400) {
        $width = 400;
        // Höhe berechnen
        $height = ($size[1]/$size[0])*$width;
           return " <img src=\"".$treffer[1]."\" width=\"".$width."\" height=\"".$height."\" border=\"0\"> ";
    }
    else
        return " <img src=\"".$treffer[1]."\" border=\"0\"> ";
    }
    

        $text = str_replace(':)',"<img src=\"http://luxurystables.lu.funpic.de/images/1.gif\">", $text);
        $text = str_replace('=)',"<img src=\"http://luxurystables.lu.funpic.de/images/3.gif\"> ", $text);
        $text = str_replace('=)',"<img src=\"http://luxurystables.lu.funpic.de/images/3.gif\">", $text);
        $text = str_replace(':P',"<img src=\"http://luxurystables.lu.funpic.de/images/4.gif\">", $text);
        $text = str_replace(';)',"<img src=\"http://luxurystables.lu.funpic.de/images/5.gif\">", $text);
        $text = str_replace(':D',"<img src=\"http://luxurystables.lu.funpic.de/images/6.gif\">", $text);
        $textr = str_replace(':(',"<img src=\"http://luxurystables.lu.funpic.de/images/7.gif\">", $text);
       
        return $text;

?>

Wenn ich nun die Posts aus der Datenbank auslese und es gibt nur einen Post funktioniert alles.
Gibt es nun 2 Posts, dann kommt folgende Fehlermeldung:
Fatal error: Cannot redeclare linklenght() (previously declared in /var/www/web46/files/members/pageersetzen.php:14) in /var/www/web46/files/members/pageersetzen.php on line 31
Obwohl es in keinem der Posts einen Link gibt, der gekürtzt werden müsste.

Hat jemand eine Idee woran das liegt und vllt. eine Lösung? Wäre echt toll ...

Danke schön schon mal! :)
 
Ich glaub, ich weiß jetzt woran das liegt.

Ich include die Datei in einer while Schleife, wenn es nun 2 od. mehr einträge gibt, wird die Funktion mehr mals aufgerufen und das gibt dann Fehler.
Kann ich das denn irgendwie unterdrücken?
Dann wenn ich die DAtei vor der while Schleife include, gibt es ja die Variable noch nicht ...
 
Hallo!

Direkt untertrücken geht nicht.. wohl aber mithilfe einer Hilfsvariable z.B. so

PHP:
$firstpost = true;
while(...)
{
  if($firstpost) include 'includedatei.php';
  // hier restlichen code ausführen
  $firstpost = false;
}


edit:
- mir ist gerade aufgefallen das löst dein Problem nicht ... ^^ warte kurz, ich helf dir schnell ...

edit 2:
So wie die Include-Datei im Moment von dir gepostet ist kann das nicht funktionieren ... es fehlt zumindest eine geschwungene Funktionsklammer irgendwo im Code - kannst du das bitte prüfen?


edit 3: Ich hab's dir jetzt zwar schon im ICQ erklärt, aber sollten noch weitere User fragen zu diesem Thema haben, hier die Lösung..

Wir verwenden folgende Vorgangsweise:
- Nimm die Funktionen in der bestehenden Include-Datei, und schneide diese dort raus -- gib sie in eine eigene Include-Datei
- Jetzt sind Funktionen und Code-Bearbeitung voneinenader getrennt, um die BB-Tags jetzt parsen zu können, verwenden wir eine ähnliche schleife wie diese

PHP:
include 'datei_mit_funktionen.php';
while(...)
{
  include 'datei_ohne_funktionen_auch_alte_datei_genannt.php';
  // ... hier findet die eigentliche verarbeitung statt
}

so treten auch DIESE fehlermeldungen nicht mehr auf ^^

Schöne Grüße!
 
Zuletzt bearbeitet:
Morgen!
Für mich sieht das ganze nach einer sehr fehleranfälligen Lösung aus. Ich würde das ganze als erstes in eine statische Klasse Packen um das Wiederverwenden zu erleichtern. Dann muss man sich überlegen, dass ein User beim verschachteln der BB-Tags auch Fehler machen kann, sodass die Ausgabe auch fehlerhaft wird. Wie man dem vorbeugen kann steht hier.
Die Klasse würde ich wie folgt unterteilen:
  • run()
  • add_tag()
  • parse_general()
  • parse_single_tag()
  • parse_multi_tag()
  • parse_links()
  • parse_mail()
  • parse_url()
  • parse_quotes()
  • parse_align()
  • parse_code()
  • parse_img()
  • parse_list()
  • parse_webcode() oder parse_html()
  • parse_smilies()
Wie du schon siehst soll die Klasse an sich statisch sein. Jedoch hat sie auch eine gewisse Dynamik, da man mit der Methode add_tag() ganz einfach die Klasse erweitern kann. Die Methode run() ruft alle anderen Methoden der Klasse auf, sodass man dann nur noch BbParse::run($str) aufrufen muss und der String $str wird geparst.

So eine Klasse dauert lange zu programmiern und ist sehr schwierig. Jedoch ist es eine gute Übung und zudem kannst du sie deinen Vorstellungen anpassen.

MfG, Andy
 
Zuletzt bearbeitet von einem Moderator:
Zurück