Effizienteres PHP search-replace

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Effizienteres PHP search-replace

    Hallo,

    mich beschäftigt seit einigen Tagen folgendes Problem:

    Ca. 500 html-Dateien zu je 20kB sollen einen neuen Namen bekommen. Da die Seiten untereinander verlinkt sind, sollen auch die internen Links umbenannt werden. Meine bisherige Lösung hier als Schnipsel:

    $piold = Array mit den alten Datei/Linknamen
    $pinew = Array mit den neuen Datei/Linknamen
    $ext = Dateiendung z.B. ".htm"

    PHP-Code:
    function writePI($piold$pinew$ext) {
        for (
    $i=0$i<sizeof($piold); $i++) {
            
    $isopen = @fopen($piold[$i].$ext"r");
            if(
    $isopen$isdata=@fread($isopenfilesize($piold[$i].$ext));
            
    $isdata str_replace($piold$pinew$isdata);
            @
    fclose($isopen);
            
    $isopen = @fopen($pinew[$i].$ext"w");
            if(
    $isopen) @fwrite($isopen$isdata); 
            @
    fclose($isopen);
        }

    Ich weiss nicht wie str_replace intern arbeitet. Wenn die 20kB Datei, die ca. 10 Links enthält 500mal durchsucht wird um das search_and_replace durchzuführen scheint mir das nicht optimal. Vor allem, da diese Prozedur für alle 500 Dateien durchgeführt werden muss.

    Eine Idee wäre per regular Expression die Links in der Datei zu suchen und dann mit einem assoziativen Array direkt zu ersetzen:

    Die alten Links lauten abXXXXX.htm oder ab-XXXXX.htm oder acXXXXX.htm oder ac-XXXXX.htm, wobei XXXX alles Zahlen sind (mindestens 3). Das array würde dann z.B. ac-12345.htm => neuername.htm usw. beinhalten.

    Ist das machbar? Oder habt jemand einen anderen Vorschlag?

    Gruß...Lothar
    Zuletzt geändert von loebbeshop; 27.06.2003, 21:00.

  • #2
    Weiss jemand ob str_replace($searcharray, $replacearray, $text) beim Suchen ein Hash verwendet oder brute force?

    Die o.g. Routine kommt mir ziemlich zäh vor, will sagen das script führt bereits ab 50 Dateien zum Abbruch.

    Kommentar


    • #3
      Das hier wär einen Versuch wert:
      PHP-Code:
      // erst alle Dateien in ein Array laden
      // alte und neue Namen in eigene Arrays:

      $i=0;
      Schleife {
        
      $files_alt[$i] = implode(''file($name_alt));
        
      $namen_alt[$i] = preg_quote($name_alt);
        
      $namen_neu[$i] = $name_neu;
        
      $i++;
      }

      // ersetzen
      $files_neu preg_replace($namen_alt$namen_neu$files_alt);

      // neue Dateien schreiben; alte Dateien löschen
      foreach($files_neu as $i=>$data)
      {
        
      $fp fopen($namen_neu[$i], 'w');
        
      fputs($fp$data);
        
      fclose($fp);
        
      unlink($namen_alt[$i];
        
      $i++;

      siehe preg_quote und preg_replace.

      Wenn´s auch vielleicht nicht alles in einer Schleife geht wg. RAM-Problemen, so dürfte ein preg_replace doch schneller sein als 500mal str_replace.
      Zuletzt geändert von Titus; 28.06.2003, 08:58.
      mein Sport: mein Frühstück: meine Arbeit:

      Sämtliche Code-Schnipsel sind im Allgemeinen nicht getestet und werden ohne Gewähr auf Fehlerfreiheit und Korrektheit gepostet.

      Kommentar


      • #4
        Das Einlesen in ein grosses Array ist insofern problematisch, als das Skript auf unterschiedlichen gehosteten Servern lauffähig sein soll, unabhängig von der Dateizahl.

        Dennoch meinen Dank für die Idee. Ich bin erst seit 10 Tagen PHPler und lerne mit jedem Codeschnipsel dazu.

        Ich frage mich nach wie vor, wie das str_replace wohl das Suchen/Ersetzen abarbeitet. Wenn der zu durchsuchende Text pro Suchbegriff je einmal durchlaufen wird (also z.B. 500 mal für die 500 möglichen Suchbegriffe), dann lohnt sich sicher eine eigene Routine.

        Vielleicht könnte ich mit preg_split anhand der Suchwörter den Text in ein array zerlegen. Der Suchbegriff steht nun am Anfang eines jeden Arrayeintrags. Dann ersetze ich diesen mit dem neuen Wert aus einem Hash und füge per implode den Text wieder zusammen.´

        So loope ich zwar durch das Directory aber nicht mehr 500mal durch jedes File.

        Kommentar

        Lädt...
        X