Robert Bienert: Suche

Beitrag lesen

Hallo Janine!

[…] Suchindex […]

wie sollte ich am besten die Daten dadrin abspeichern?

  1. ein Array, wo die Indexe das Suchwort sind und die Werte den Pfad zur Seite enthalten?
    z.B.

$suche = array();

$suche['xyz'] = '/ordner1/datei1.htm;/ordner2/datei2.htm;/datei3.htm';
$suche['zyx'] = '/datei4.htm';

  
Bei dieser Lösung empfehle ich, den Suchindex in eine separate Datei zu schreiben und diese im Suchscript einzubinden. Der Vorteil daran ist, dass die Suche im Index sehr einfach zu bewerkstelligen ist, man muss sich z.B. nicht ein Dateiformat erfinden und dafür einen Parser schreiben:  
  
~~~php
  
if ([link:http://www.php.net/manual/function.array-key-exists.php@title=array_key_exists]($_REQUEST['suchbegriff'], $suche))  
    echo 'Ergebnis: <a href="' .  
        [link:http://www.php.net/manual/function.htmlspecialchars.php@title=htmlspecialchars]($suche[suchbegriff]) . '">' .  
        htmlspecialchars($suche[suchbegriff]) . '</a>';  

Allerdings hat dein Ansatz oben den (kleinen) Nachteil, dass der Wert zu einem bestimmten Schlüssel im Grunde eine Art serialisiertes Array darstellt, was passiert z.B., wenn eine Datei ein ';' im Namen trägt? Da wäre so etwas praktikabler:

  
$suche['xyz'] = array('/ordner1/datei1.htm', '/ordner2/datei2.htm',  
                      '/datei3.htm');  
  
// bzw.  
$suche['xyz'][] = '/ordner1/datei1.htm';  
// …  
$suche['xyz'][] = '/ordner2/datei2.htm';  
// …  
$suche['xyz'][] = '/datei3.htm');  

Ein weiterer Nachteil dieser Lösung ist, dass der komplette Suchindex von PHP in den Speicher geladen wird, obwohl sehr wahrscheinlich nur ein geringer Teil seines Inhaltes benötigt wird.

  1. als *.ini-Datei?

Analog zu obigem, also z.B. in dieser Art:

xyz=/ordner1/datei1.htm;/ordner2/datei2.htm;/datei3.htm

bzw.

xyz=/ordner1/datei1.htm
xyz=/ordner2/datei2.htm
xyz=/datei3.htm

Falls du parse_ini_file verwenden möchtest, achte darauf, dass die Dateinamen einige Zeichen nicht enthalten dürfen. Der obere Ansatz in meinem Beispiel enthielte dann nur /ordner1/datei1.htm, weil das ';' als Kommentarzeichen benutzt wird. Allerdings wird auch hierbei – unter Verwendung von parse_ini_file – der komplette Index in den Speicher geladen. Da wäre es durchaus sinnvoller, den Index zeilenweise zu lesen, da du dann auch in jeder Zeile entscheiden kannst, ob sie relevant ist:

  
if (($fh = [link:http://www.php.net/manual/function.fopen.php@title=fopen]('/pfad/zum/suchindex', 'r')) === FALSE)  
    die 'Suche außer Betrieb';  
  
$line = [link:http://www.php.net/manual/function.fgets.php@title=fgets]($fh);  
  
// diese Variablen brauchen wir bei jedem Schleifendurchlauf:  
$del = 0;     // Position des Trennzeichens '='  
$key = '';    // Schlüssel  
$val = '';    // passender Wert  
  
while ($line !== FALSE) {  
    if (! ($line{0} == '#' or $line{0} == ';'  
        /* oder weitere Kommentarzeichen */ ))  
    {  
        if (($del = [link:http://www.php.net/manual/function.strpos.php@title=strpos]($line, '=')) !== FALSE) {  
            if (($key = [link:http://www.php.net/manual/function.substr.php@title=substr]($line, 0, $del)) == $_REQUEST['suchbegriff'])  
            {  
                $val = htmlspecialchars(substr($line, $del+1));  
                echo 'Ergebnis für <b>' .  
                    htmlspecialchars($_REQUEST['suchbegriff']) .  
                    "</b>: <a href=\"$val\">$val</a>";  
            }  
        }  
    }  
  
    $line = fgets($fh);  
}  
  
[link:http://www.php.net/manual/function.fclose.php@title=fclose]($fh);  

  1. oder eien andere Möglichkeit?

Naja, sonst fällt mir nur noch die Verwendung einer Datenbank ein.

Hm, SQLite ist natürlich auch schön klein und schlank, aber MySQL halte ich in diesem Fall für ein bisschen überdimensioniert.

unterstützt SQLite eigentlich die Volltextsuche?
ich werde auch sqlite.org nicht ganz schlau

Oh, gute Frage. In der SQLite-Dokumentation des Befehls SELECT ist leider keine Rede von LIKE, damit wäre eine Volltextsuche sehr einfach (aber nicht unbedingt performant) möglich:

SELECT Datei FROM Suchindex WHERE stichwort LIKE '%SuchBegriff%'

wobei SuchBegriff dort der eingefügte Suchbegriff ist (Escaping nicht vergessen).

der Vorteil von SQLite gegenüber MySQL wäre, dass ich die Datenbank einfach mit per FTP hochladen könnte

So sieht es aus. Ich habe mir mal die Seite http://www.sqlite.org/ angeschaut und festgestellt, dass diese Datenbank-Engine richtig schick ist.

Viele Grüße,
Robert