PHP Script Volltextsuche Werte und Implode für MySQL

ben78

Mitglied
Hi Tutorials-Leutz,

ich bin's mal wieder und freu mich schon auf Antworten von Euch, die mir weiterhelfen können.

Also folgendes, ich bin gerade dabei eine Volltextsuche in PHP für meine Website zu basteln. Und noch mal für alle, ich bin immer noch ein absoluter Anfänger in stuff PHP...ich bin jedem Dankbar, der mir das so erklären kann, dass es sogar der dümmste Esel ( wie z. B. ich in Sachen PHP ) verstehen kann...BIG THX @ All :confused:

In meinem Skript (PHP) für die Volltextssuche findet sich folgender Abschnitt:

Code:
$locData = array();
foreach ($inWords as $locKey => $locVal)
  {
      if (strlen($locVal) > 32)

Jetzt weiss ich nicht, wie ich für $inWords die Werte herbekommen soll. Ich weiss nur folgendes aber kann mir nichts darunter vorstellen:

"in $inWords sind alle Wörter des Datensatzes vorhanden".

Ich bin gerade auch dabei herauszufinden, wie und welche Daten ich per implode in das Array einfügen kann bzw. muss. Und ist es richtig, dass die Daten dann zwischen die beiden Klammern gehören
Code:
$locData = array(D A T E N);
?
Kann mir aber nicht vorstellen, dass damit die CSV Produktdatensätze gemeint sind oder?...die stecken doch alle in der MySQL Tabelle, wenn mich nicht alles täuscht
 
Moin Ben,

das ist jetzt ein wenig schwer verständlich...zeig doch mal etwas mehr von dem Code.

Nur soviel: Die Daten müssten so in den Array:

Code:
$locData = array('D','A','T','E','N');

Das gäbe einen Array mit 5 Elementen(jeweils eines für jeden Buchstaben)
Die Gänsefüsschen müssen notiert werden, wenn es sich um Zeichenketten handelt.
 
Sorry, aber ich versteh wirklich nicht wie du dir das vorstellst. Diese 5 Zeilen wild aus einem Code gerissen können alles mögliche bedeuten.

Woher kommt $inWords?
Was kommt nach dem if? Hast du dort ein Problem?
Was soltle in $locData am schluss stehen und woher kommen die Daten?
 
Erst mal vielen Dank!

wenn ich meine Frage(n) zu verwirrend gestellt habe, dann liegt das daran, dass in Sachen PHP noch ein schrecklicher Anfänger bin.

Ich habe eine MySQL Datenbank mit einer Tabelle in der Produktdatensätze gespeichert sind. Am Ende sollen ca. 500.000 Datensätze in die Tabelle. Damit diese nicht lahmgelegt wird, sollte man hiervon absehen, habe ich mir sagen lassen:

Code:
$sql = "select * from test where Bezeichnung like '%" . $suchwort . "%' or Beschreibung like '%" . $suchwort . "%' or Marke like '%" . $suchwort . "%'";

Stattdessen soll ja auf die Variante der Volltextsuche gegriffen werden. Damit zum einen auch die Suchabfrage nicht zu lange dauert.

Hier mal mein Script.

PHP:
<?php
error_reporting(E_ALL);

// Zum Aufbau der Verbindung zur Datenbank
define ( 'MYSQL_HOST', '' );
define ( 'MYSQL_BENUTZER', '' );
define ( 'MYSQL_KENNWORT', '' );
define ( 'MYSQL_DATENBANK', '' );

$db_link = mysql_connect (MYSQL_HOST, MYSQL_BENUTZER, MYSQL_KENNWORT);

mysql_set_charset('utf8',$db_link);

$db_sel = mysql_select_db( MYSQL_DATENBANK )
or die("Auswahl der Datenbank fehlgeschlagen");

$suchwort = mysql_real_escape_string($_POST['suche']);

$sql = "

SELECT ca_id AS st_doc_id, 
           st_id, 
           'article' AS st_type, 
           CONCAT(ca_title, ' ', ca_text, ' ', ca_category) AS search_data 
      FROM cms_article 
 LEFT JOIN search_time 
        ON st_doc_id = ca_id 
       AND FIND_IN_SET('article', st_type) 
     WHERE FIND_IN_SET('approved', ca_status) 
       AND (   st_id IS NULL 
            OR ca_date > st_date 
           ) 
  ORDER BY ca_date";
 

$locSearch[] = "=Ã?=i";
  $locSearch[] = "=ä|�=i";
  $locSearch[] = "=ö|�=i";
  $locSearch[] = "=ü|�=i";
  $locSearch[] = "=á|à |â|�|�|�=i";
  $locSearch[] = "=ó|ò|ô|�|�|�=i";
  $locSearch[] = "=ú|ù|û|�|�|�=i";
  $locSearch[] = "=é|è|ê|�|�|�|ë=i";
  $locSearch[] = "=Ã|ì|î|Ã?|Ã?|Ã?|ï=i";
$locSearch[] = "=ñ=i";
 $locSearch[] = "=ç=i";
 $locSearch[] = "=([0-9/.,+-]*\s)=";
 $locSearch[] = "=([^A-Za-z])=";
 $locSearch[] = "= +=";
     
 $locReplace[] = "ss";
 $locReplace[] = "ae";
 $locReplace[] = "oe";
 $locReplace[] = "ue";
 $locReplace[] = "a";
 $locReplace[] = "o";
 $locReplace[] = "u";
 $locReplace[] = "e";
 $locReplace[] = "i";
 $locReplace[] = "n";
 $locReplace[] = "c";
 $locReplace[] = " ";
 $locReplace[] = " ";
 $locReplace[] = " ";
 
 $outString = trim(strtolower(stripslashes(strip_tags($inString))));
 $outString = preg_replace($locSearch, $locReplace, $outString );



// in $inStopwords ist ein numerisch indiziertes Array mit allen Stoppworten
  
  $locSearch[] = "=(\s[A-Za-z]{1,2})\s=";
  $locSearch[] = "= " . implode(" | ", $inStopwords) . " =i";
  $locSearch[] = "= +=";
  
  $locReplace[] = " ";
  $locReplace[] = " ";
  $locReplace[] = " ";
 
 $outString = " " . str_replace(" ", "  ", $inString) . " ";
 $outString = trim(preg_replace($locSearch, $locReplace, $outString));


// in $inWords sind alle Wörter des Datensatzes vorhanden
  // in $inStType ist der aktuelle Wert der Spalte 'st_type' enthalten
  // in $inStDocId ist der aktuelle Wert der Spalte 'st_doc_id' enthalten
 
  $locData = array();
  
  foreach ($inWords as $locKey => $locVal)
  {
      if (strlen($locVal) > 32)
     {
         $locVal = substr($locVal, 0, 32);
     }
     
     $locSwId = fetchWordId($locVal);  // holt Schlüssel bzw. speichert Wort neu in Datenbank
     
     if (isset($locData[$locSwId]))
     {
         $locData[$locSwId]["si_count"] = $locData[$locSwId]["si_count"] + 1;
     }
     else
     {
         $locData[$locSwId]["si_sw_id" ] = $locSwId;
         $locData[$locSwId]["si_type"  ] = $inStType;
        $locData[$locSwId]["si_doc_id"] = $inStDocId;
         $locData[$locSwId]["si_count" ] = 1;
     }
 }
 
sort($locData);
?>
 
Mal vornweg. Du hast in deinem SQL WHERE-Bedinungen im JOIN-Teil. Solltest du nicht.
Entweder eine Unterabfrage oder den Teil in die vorhende-WHERE-Sektion verscheiben
SQL:
AND FIND_IN_SET('article', st_type)

FIND_IN_SET() in einer WHERE macht mMn nicht viel sinn. Nimm einen einfachen Vergleich
SQL:
ca_status = 'approved'

Zu deinem eigentlichen Problem.
Aus diesem SQL irgendwie alle Wörter rauskreigen. Welche Felder sollens den sein?
Was willst du dals Resultat?
Bitte genau beschreiben, sonst gibts weider einen Missverständnissalat wie da http://www.tutorials.de/forum/php/354258-datenbank-html-suche-php-verbinden.html
 
Zuletzt bearbeitet von einem Moderator:
volltext suche php und mysql

Hi Tutorialsler,

Ich habe folgendes PHP Skript:


PHP:
<?PHP
Verbindung etc.
.
.
.
error_reporting(E_ALL);

// Zum Aufbau der Verbindung zur Datenbank
define ( 'MYSQL_HOST', '' );
define ( 'MYSQL_BENUTZER', '' );
define ( 'MYSQL_KENNWORT', '' );
define ( 'MYSQL_DATENBANK', '' );

$db_link = mysql_connect (MYSQL_HOST, MYSQL_BENUTZER, MYSQL_KENNWORT);

$db_sel = mysql_select_db( MYSQL_DATENBANK )
or die("Auswahl der Datenbank fehlgeschlagen");

$suchwort = mysql_real_escape_string($_POST['suche']);

$sql = "SELECT * FROM beauty WHERE MATCH(Bezeichnung, Beschreibung, Marke) AGAINST('" . $suchwort . "')";

$db_erg = mysql_query( $sql );
if ( ! $db_erg )
{

die('Ungültige Abfrage: ' . mysql_error());
}
$anzahl = mysql_num_rows($db_erg);
echo "Suchergebnisse: $anzahl";

echo '<table border="1" style="border-collapse:collapse">';
while ($zeile = mysql_fetch_array( $db_erg, MYSQL_ASSOC))

{
echo "<tr class='tabelle'>";
echo "<td class='bild'><img src='". htmlspecialchars($zeile['Abbildung']) . "' /></td>";
echo "<td class='title'>". $zeile['Bezeichnung'] . "</td>";
echo "<td class='body'>". $zeile['Beschreibung'] . "</td>";
echo "<td class='marke'>". $zeile['Marke'] . "</td>";
echo "<td class='preis'>". $zeile['Preis'] . " &euro;</td>";
echo "<td class='bestellen'><a href='". htmlspecialchars($zeile['Anbieter']) . " title='zur Bestellung'>Schicken lassen</a></td>";

echo "</tr>";
}
echo "</table>";
mysql_free_result( $db_erg );

if ( $db_link )
{
echo 'Verbindung erfolgreich: ';
echo $db_link;
}

else
{
	
// hier sollte dann später dem Programmierer eine
// E-Mail mit dem Problem zukommen gelassen werden
die('keine Verbindung möglich: ' . mysql_error());
}
mysql_close($db_link );
?>

Hierzu folgender HTML-Code:
HTML:
<form action="./mysql/search-fulltext1.php" method="post">
						<div id="search-mysql">
							<input type="text" name="suche" size="20" onfocus="if (this.value =='Produktfinder') { this.value=''}" onblur="if (value == '') {value='Produktfinder'}" value="Produktfinder" />
							<input type="submit" value="GO">
							<select name="suche"> <option value="" SELECTED >Marke</option><option>Cartier</option><option>Ralph Lauren</option><option>Christian Dior</option></select>
							<input type="submit" value="GO">
						</div>
					</FORM>




Mein Ziel ist eine einfache Volltext suche bei der der User anhand eines beliebigen Suchbegriffes im Textfeld und obligatorisch eine Marke aus dem Sprungmenü auswählen und danach suchen kann. z.B. Textfeld: "Sportschuhe" Sprungmenü: "adidas"(obligatorisch). Das probiere ich jetzt schon trotz des vielen Lesens in diversen Seiten seit ca. 2 Wochen.:mad::mad::mad:. Das kann doch nicht so schwer sein! Mich würde auch interessieren, wie ich mittels PHP die Spalte "Marke" aus Meiner MySQL-Tabelle ins Sprungmenü hauen kann
 
Zuletzt bearbeitet:
Moin :)

@ben78: Es wäre von dir entgegenkommend, uns nicht alle zwei Tage mit einem weiteren neuen Thema bzgl. der Volltextsuche zu beglücken, sondern deine "Entwicklungsstufen" zentral in einem Thema festzuhalten.

So haben die Hilfeleistenden alles direkt im Überblick, und müssen sich nicht durch "X"-Themen wurschteln, um den Faden aufzunehmen.

Aus diesem Grund hab ich deine letzten beiden Themen an dieser Stelle zusammengeführt, und möchte dich darum bitten, dein Projekt hier fortzusetzen, anstatt es häppchenweise auf unzählige Themen im PHP-Board zu verteilen.

Vielen Dank!

mfg Maik
 
Ersmal DANKE!

Jetzt habe ich folgenden Code im Skript. Schaut das jetzt besser aus? ich lese mich auf diversen Seiten dumm und dämlich, komme aber nicht weiter.

PHP:
$suchwort = mysql_real_escape_string($_POST['suche']);
$marke = mysql_real_escape_string($_POST['hersteller']);
 
$sql = "SELECT * FROM test WHERE MATCH(Bezeichnung, Beschreibung, Marke) AGAINST('" . $suchwort . "') AND MATCH Marke AGAINST ('" . $marke . "')";
 
if ($marke) $sql = $sql." AND Marke = $marke";
 
 
$db_erg = mysql_query( $sql );

Dazu folgendes Skript mit den Formularfeldern.

PHP:
$sql = "SELECT DISTINCT Marke FROM test ORDER BY Marke";

if ($db_erg = mysql_query( $sql ))
{
 echo '<form action="./mysql/search-fulltext1.php" method="post">';
 echo '<div id="search-mysql">';
 echo '<input type="text" name="suche" size="20" ';
 echo "onfocus=\"if (this.value =='Produktfinder') { this.value=''}\" ";
 echo "onblur=\"if (value == '') {value='Produktfinder'}\" value=\"Produktfinder\" />";
 echo '<select name="hersteller">';
 echo '<option value="">Marke</option>';
 while ($row = mysql_fetch_array( $db_erg))
 {
  echo '<option value="' . $row["Marke"] . '">' . $row["Marke"] . '</option>'; 
 }
 echo '</select>';
 echo '<input type="submit" value="GO">';
 echo '</div></FORM>'

Wenn ich aus dem Sprungmenü eine Marke auswähle und dabei das Textfeld für die Sucheingabe frei lasse, dann auf GO klicke, kommt folgende Fehlermeldung:

Ungültige Abfrage: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'adidas' at line 1 Was ist denn da Syntax-technisch falsch? ich schaue schon die ganze zeit drauf... - Als Anfänger versteht sich -...und komme aber nicht drauf.

LINE 1 =
PHP:
$sql = "SELECT * FROM test WHERE MATCH(Bezeichnung, Beschreibung, Marke) AGAINST('" . $suchwort . "') AND MATCH Marke AGAINST ('" . $marke . "')";

...UND

Wenn ich in das Suchfeld ein Suchbegriff eingebe und das Sprungmenü unberührt lasse, erscheint nach klicken auf GO komischer Weise folgende Meldung, obwohl ich...

Code:
ALTER TABLE test ADD FULLTEXT (Bezeichnung, Beschreibung, Marke);

...bereits ausgeführt habe.

Ungültige Abfrage: Can't find FULLTEXT index matching the column list

Was mache ich diesmal wieder falsch?

Ich vergammle schon so seit ca. 9 Std. lesend und testend vor mich hin. Ich bin Fix und Foxi...I kann nimmer :o
 
Zuletzt bearbeitet:
Zurück