[PHP/MySQL] Wie am besten Lexikon mit Wörererkennung umsetzen?

BartTheDevil89

Devilution Media
ID: 87739
L
2 Mai 2006
3.960
103
Hallo,

ich habe mir vorgenommen ein Lexikon mit Begriffen zu erstellen. Also ein es wird ein Begriff eingetragen und dann ne Erklärung dazu.

Das möchte ich zum einen dann anzeigen lassen (ist ja nicht das Problem) aber zum anderen auch soll in Textstrings immer überprüft werden ob einer dieser Begriffe dir vorhanden und dieses Wort soll dann verlinkt werden.

Dafür jetzt die Frage, wie ich das am besten vom Datenbankaufbau mache, da es mir am liebsten wäre, wenn nicht nur das Wort selbst, sondern auch Varianten des Wortes erkannt werden. Also bei Ball zum beispiel auch Bälle. (muss die Varianten ja sicherlich dann mit in der Datenbank abspeichern)

Und dann natürlich auch wie ich am besten die Begriffe überprüfen....denn ich denke das einfachste wird es sein alle wörter die bekannt sind auszulesen in nen string zu laden und dann jedes wort zu überprüfen, ob es im String drinsteht.....denn mit ner jeweiligen Datenbankabfrage wird das ja wahrscheinlich nicht zu lösen sein, bzw. so serveraufwendig, dass es sich nicht lohnt.

Habt ihr Ideen, wie das am besten aufgebaut sein muss, dass die Serverlast so gering wie möglich ist?
 
Du machst es so ;)

Table Suchwörter

id wort textid
============
1 Ball 182
2 Bälle 182

Musste halt dann iwie immer wenn du neue Beiträge schreibst in die DB übernehmen aber das sollte ja kein Problem sein ;)
 
Du machst es so ;)

Table Suchwörter

id wort textid
============
1 Ball 182
2 Bälle 182

Musste halt dann iwie immer wenn du neue Beiträge schreibst in die DB übernehmen aber das sollte ja kein Problem sein ;)


Achso ja das sollte natürlich ne gute Idee sein. Einfach ne TAbelle mit ner ID und der Erläuterung.
Und dann die TAbelle wo die textid auf die jeweilige ID der Erkläuterung verweist.

Aber wie würdest du es beim überprüfen des Strings durchführen? Was würdest du da für ne Variante vorschlagen?

Sind andere einer anderen Meinung, wie man es noch serversparender durchführen kann? ;) Ich bin offen für jede Anregung...
 
Du leißt alle Keywords aus der Datenbank aus und ersetzt/ergänzt diese im eigentlichen Text einfach gegen ein Link oder was auch immer. Also einfach ne schleife wo du jedes Keyword durchgehst und dann mit preg_replace entsprechend ersetzt.

Das ganze ist natürlich nicht unbedingt Ressourcen schonend. Also wenn du viele Keywords und/oder Zugriffe hast dann heißt das Zauberwort caching. Die Kunst dabei ist nur den cache aktuell zu halten... ;) Das ganze kostet natürlich Speicherplatz, aber von nix kommt nix.
 
Du leißt alle Keywords aus der Datenbank aus und ersetzt/ergänzt diese im eigentlichen Text einfach gegen ein Link oder was auch immer. Also einfach ne schleife wo du jedes Keyword durchgehst und dann mit preg_replace entsprechend ersetzt.

Das ganze ist natürlich nicht unbedingt Ressourcen schonend. Also wenn du viele Keywords und/oder Zugriffe hast dann heißt das Zauberwort caching. Die Kunst dabei ist nur den cache aktuell zu halten... ;) Das ganze kostet natürlich Speicherplatz, aber von nix kommt nix.

Hi so ungefähr hab ich mir das schon gedacht und hab jetzt diese Variante hier gebaut:

PHP:
$teststr = "Ein Test mit vielen Höfen und auch Autos"; (nicht wundern ;))
$arr_schlagwoerter = array();
$arr_link = array();

$result = $db->query("SELECT bid,wort FROM table");
while($row = mysql_fetch_array($result)) {
$arr_schlagwoerter[] = $row['wort'];
$arr_link[] = "<a href='seite.php?bid=". $row['bid'] ."'>". $row['wort'] ."</a>";
}

$neuerstr = str_replace($arr_schlagwoerter, $arr_link, $teststr);

echo "$neuerstr";


In der TAbelle hab ich halt dann Test, Autos und Höfe drin um es zu testen.

Allerdings hab ich noch ein Problem:

1. Wenn das Wort in der Tabelle groß geschrieben ist und im String klein, funktioniert es nicht. -> Mit dem Versuch str_ireplace geht es nicht, da kein php 5 vorhanden
 
Daher hab ich auch preg_replace vorgeschlagen ;) Mit str_replace und co. kann das nicht gehen... schon allein die Groß- und Kleinschreibung ist ein Problem. Macht sich schlecht wenn plötzlich aus Auto auto wird. Oder wenn aus Autobahn plötzlich autobahn wird.

Von daher muss das ganze eher so aussehen:

PHP:
$DEIN_TEXT = preg_replace('~(^|\W)(suchwort)($|\W)~i','\\1<a href="">\\2</a>\\3',$DEIN_TEXT);
 
Daher hab ich auch preg_replace vorgeschlagen ;) Mit str_replace und co. kann das nicht gehen... schon allein die Groß- und Kleinschreibung ist ein Problem. Macht sich schlecht wenn plötzlich aus Auto auto wird. Oder wenn aus Autobahn plötzlich autobahn wird.

Von daher muss das ganze eher so aussehen:

PHP:
$DEIN_TEXT = preg_replace('~(^|\W)(suchwort)($|\W)~i','\\1<a href="">\\2</a>\\3',$DEIN_TEXT);

Versteh ich leider nicht ganz, wie du es meinst...:roll:
Hab ja die Variablen

$teststr = "Ein Test mit vielen Höfen und auch Autos";
$arr_schlagwoerter = array(); //Die Wörter
$arr_link = array(); //Durch was es ersetzt werden soll

Wie meinst du, sollten die in den preg_replace rein?

Und ich müsste dann bei $arr_link nurnoch den Link drin speichern, wohin das verlinken soll und den dann bei <a href="">\\2</a> zwischen den beiden "" reinsetzen, richtig? Denn das Wort wird über die Funktion wieder ausgegeben.
 
Ich würde an deiner stelle ganz einfach mit ner Schleife machen, ungefüähr so:

PHP:
$text = 'Dein Text';
$result = $db->query("SELECT suchwort, link FROM usw...");
foreach($result AS $daten) {
    $text =  preg_replace('~(^|\W)('.$daten['suchwort'].')($|\W)~i','\\1<a href="'.$daten['link'].'">\\2</a>\\3',$text);
}

Ansonsten musst du das ganze Suchmuster und das Ausgangsmuster jedesmal wieder in deinen Arrays speichern. Macht sich nicht so gut.

PHP:
Und ich müsste dann bei $arr_link nurnoch den Link drin speichern, wohin das verlinken soll und den dann bei <a href="">\\2</a> zwischen den beiden "" reinsetzen, richtig? Denn das Wort wird über die Funktion wieder ausgegeben.

Ja, siehe oben. Und ja das Wort wird automatisch eingesetzt. Weil ansonsten hast du das Problem das die Groß- und Kleinschreibung nicht hinhaut. (wie oben beschreiben) Z.B. bei dir steht in der Datenbank "auto" und der Text sieht so aus "Ein großes AUTO, und ein normales Auto und ein komisches AuTo". Dann würdest du ohne diese automatische einsetzten am ende "Ein großes auto, und ein normales auto und ein komisches auto" erhalten, was nicht unbedingt schön wäre.
 
Hi,

also versteh ich dein Prinzip richtig?

Du machst für jedes Wort, das in der Datenbank ausgelesen wird ne Überprüfung ob das in dem String drin ist?
Ist sowas nicht enorm aufwendig, wenn ich viele Wörter und auch ne ganze Menge Text habe?
 
Deswegen war ja auch die Rede von Caching :roll:

Ja, aber gehts denn nicht auch einfach so, wie ich es oben gemacht hab, halt nur mit dem anderen befehl?

Also aus:

$neuerstr = str_replace($arr_schlagwoerter, $arr_link, $teststr);

das hier?:

$neuerstr = preg_replace('~(^|\W)($arr_schlagwoerter)($|\W)~i','\\1<a href="$arr_link">\\2</a>\\3',$neuerstr);
:roll:
 
Du machst für jedes Wort, das in der Datenbank ausgelesen wird ne Überprüfung ob das in dem String drin ist?
Ist sowas nicht enorm aufwendig, wenn ich viele Wörter und auch ne ganze Menge Text habe?

Wie gesagt von nix kommt nix. Klar ist das aufwendig... ich hab ja geschreiben es ist nicht Ressourcen schonend. Die Frage ist was für Ressourcen du aufwenden willst. Entweder kostet das ganze CPU Zeit und Arbeitsspeicher (und das ab einer gewissen größe massiv), oder Speicherplatz.

Ja, aber gehts denn nicht auch einfach so, wie ich es oben gemacht hab, halt nur mit dem anderen befehl?

Also aus:

$neuerstr = str_replace($arr_schlagwoerter, $arr_link, $teststr);

das hier?:

$neuerstr = preg_replace('~(^|\W)($arr_schlagwoerter)($|\W)~i','\\1<a href="$arr_link">\\2</a>\\3',$neuerstr);
:roll:

Ähm ja ob du str_replace mit Arrays fütterst oder Strings ist das selbe. Ob da nun intern die Werte durchgegangen werden, oder du die Werte durch gehst macht kaum ein unterschied. Und ja man kann preg_replace auch mit Arrays aufrufen, dazu musst du aber die Muster in die Arrays packen.

Sprich die Array müssten dann so aussehen:
$arr_schlagwoerter[] = '~(^|\W)(Auto)($|\W)~i';
$arr_schlagwoerter[] = '~(^|\W)(Haus)($|\W)~i';
usw... daher find ich eine Schleife bei weitem übersichtlicher.
 
Achso ja stand irgendwie auf der Leitung^^;)....also die Variante funktioniert auf jedenfall und läuft auch gut.

Allerdings dann gleich die nächste Frage:

Denn wie ja schon festgestellt, ist das ganze recht serveraufwendig...daher jetzt zum caching. Wie würdet ihr rangehen, was würdet ihr wo cachen, etc.....also ihr seit wieder gefragt und ich freue mich auf eure ideen. ;)