12. februar 2009 - 15:40Der er
14 kommentarer og 2 løsninger
Problemmer med MySQL query
I sin tid lavede jeg et søge script som virkede ret godt (syntes jeg). Men jeg nu har jeg opdaget et problem når man søger på " " (mellemrum) opstår der fejl.
Du kunne tjekke hvad din variable indeholder, bla om den er tom. I den forbindelse kan du jo bruge trim() til at fjerne mellemrum først og sidst i variablen.
Dernæst har du en fejl i din sql, det hedder WHERE og ikke WHER
Nej jeg må indrømme at jeg ikke har mulighed, eller gider, hente en zip fil. Kan du ikke poste lidt af koden omkring der hvor din søgning bliver udført her ?
Nej det gør jeg ikke, men jeg er ved at lære de forskellige funktioner. Det virker bare absurd for mig at skrive koden ind, da der er mange kommentarer. Men jeg skal da prøve ... meddelelser følger
________Siden som viser hvad brugeren søgte efter________
/********************************************************* | | | Her findes MySQL forspørgelsen | | | *********************************************************/
if (!isset($_GET['search'])) { $query = "SELECT * FROM kogebogen ORDER BY navn"; }
else { //////////////////////////// // findes ingen søgetekst // //////////////////////////// if ($_GET['search'] == "" || $_GET['search'] == "Søgetekst") { $query = "SELECT * FROM kogebogen WHERE ( AND "; }
//////////////////////////// // findes søgetekst // //////////////////////////// else { $tekst = $_GET['search']; include "MySQL/Soege-script/tekst.php"; $query = $sql; $query = substr($query,0,(strLen($query)-21));//Sletter intil WHERE slut }
//////////////////////////// // findes bio ja / nej // //////////////////////////// if ($_GET["bio"] == "ja" || $_GET["bio"] == "nej") { if (preg_match("/WHERE \( AND $/", $query)) { $query = substr($query,0,(strLen($query)-5));//Sletter intil AND slut } $query .= "(hm='".$_GET["bio"]."') AND "; //Tilføjer bio hvis }
//////////////////////////// // findes ingen bruger tx // //////////////////////////// if ($_GET['Bruger'] == "" || $_GET['Bruger'] == "Bruger") { $query .= ""; }
//////////////////////////// // findes bruger tekst // //////////////////////////// else { if (preg_match("/WHERE \( AND $/", $query)) { $query = substr($query,0,(strLen($query)-5));//Sletter intil AND slut } $bruger = $_GET['Bruger']; include "MySQL/Soege-script/bruger.php"; $query .= $tosql; }
//////////////////////////// // findes ingen land text // //////////////////////////// if ($_GET['Oprindelse'] == "" || $_GET['Oprindelse'] == "Oprindelse") { $query .= ""; }
//////////////////////////// // findes land tekst // //////////////////////////// else { if (preg_match("/WHERE \( AND $/", $query)) { $query = substr($query,0,(strLen($query)-5));//Sletter intil AND slut } $oprindelse = $_GET['Oprindelse']; include "MySQL/Soege-script/oprindelse.php"; $query .= $tresql; }
//////////////////////////// // ingen rigtig søgning // //////////////////////////// if (preg_match("/WHERE \( AND $/", $query)) { $query = "SELECT * FROM kogebogen ORDER BY navn"; }
//////////////////////////// // rigtig søgning - tekst // //////////////////////////// elseif (preg_match("/^SELECT \* FROM kogebogen WHERE \(\(/", $query)) { $query = substr($query,0,(strLen($query)-5));//Sletter intil AND slut $query .= ") ORDER BY navn DESC"; } //////////////////////////// //uheldig søge formulering// ////////////////////////////
//////////////////////////// // rigtig søgning + tekst // //////////////////////////// else { $query = substr($query,0,(strLen($query)-5));//Sletter intil AND slut $query .= ") ORDER BY score DESC"; } } echo ' <tr> <td colspan="6"> '.$query.' </td> </tr> ';
/********************************************************* | | | Her findes de næste sider | | | *********************************************************/
_____tekst.php______ class Cleaner { // fjerner ord var $stopwords = array(" hvad ", " hvilke ", " hvordan ", " hvor ", " sådan ", " så ", " er ", " jeg ", " en ", " to ", " laver ", " find ", " finder ", " se ", " så ", " ser ", " jeg ", " dig ");
//fjerner tegn var $symbols = array('/','\\','\'','"',',','.','<','>','?',';',':','[',']','{','}','|','=','+','-','_',')','(','*','&','^','%','$','#','@','!','~','`' );
function removeSymbols($string) { for ($i = 0; $i < sizeof($this->symbols); $i++) { $string = str_replace($this->symbols[$i],' ',$string); }
return trim($string); } } //< //fordi at det er dansk $stemmed_string = $tekst;
//starter Cleaner $clean_string = new Cleaner(); $stemmed_string = $clean_string->parseString($stemmed_string);
//deler søgetekseten op i et arrya for at fastslå om ordet er på et bokstav $split = split(" ",$stemmed_string); foreach ($split as $array => $value) { if (strlen($value) < 1) { continue; } $new_string .= ''.$value.' '; } $new_string=substr($new_string,0,(strLen($new_string)-1));
//deler søgetekseten op i et arrya $split_stemmed = split(" ",$new_string);
//Starten MySQL eftersprøgelsen
$sql = "SELECT DISTINCT MATCH(navn, tekst, ingredienser) Against ('$string' IN BOOLEAN MODE) as score, navn, tekst, ingredienser, id, hm, raiding, stemmer, oprindelse, dato, opretter, billede FROM kogebogen WHERE (";
while(list($key,$val)=each($split_stemmed)) { if($val<>" " and strlen($val) > 0) { $sql .= "(navn LIKE '%$val%' OR tekst LIKE '%$val%' OR ingredienser LIKE '%$val%') OR "; } } $sql=substr($sql,0,(strLen($sql)-4));//this will eat the last OR $sql .= " AND ) ORDER BY score DESC";
function removeSymbols($trestring) { for ($trei = 0; $trei < sizeof($trethis->symbols); $trei++) { $trestring = str_replace($trethis->symbols[$trei],' ',$trestring); }
return trim($trestring); } } //< //fordi at det er dansk $trestemmed_string = $oprindelse;
//starter Cleaner $treclean_string = new Cleanertre(); $trestemmed_string = $treclean_string->parseString($trestemmed_string);
//deler søgetekseten op i et arrya for at fastslå om ordet er på et bokstav $tresplit = split(" ",$trestemmed_string); foreach ($tresplit as $trearray => $trevalue) { if (strlen($trevalue) < 1) { continue; } $trenew_string .= ''.$trevalue.' '; } $trenew_string=substr($trenew_string,0,(strLen($trenew_string)-1));
//deler søgetekseten op i et arrya $tresplit_stemmed = split(" ",$trenew_string);
//Starten MySQL eftersprøgelsen
$tresql = "";
while(list($trekey,$treval)=each($tresplit_stemmed)) { if($treval<>" " and strlen($treval) > 0) { $tresql .= "(oprindelse LIKE '%$treval%') OR "; } } $tresql=substr($tresql,0,(strLen($tresql)-4));//this will eat the last OR $tresql .= " AND "; ?>
function removeSymbols($tostring) { for ($toi = 0; $toi < sizeof($tothis->symbols); $toi++) { $tostring = str_replace($tothis->symbols[$toi],' ',$tostring); }
return trim($tostring); } } //< //fordi at det er dansk $tostemmed_string = $bruger;
//starter Cleaner $toclean_string = new Cleanerto(); $tostemmed_string = $toclean_string->parseString($tostemmed_string);
//deler søgetekseten op i et arrya for at fastslå om ordet er på et bokstav $tosplit = split(" ",$tostemmed_string); foreach ($tosplit as $toarray => $tovalue) { if (strlen($tovalue) < 1) { continue; } $tonew_string .= ''.$tovalue.' '; } $tonew_string=substr($tonew_string,0,(strLen($tonew_string)-1));
//deler søgetekseten op i et arrya $tosplit_stemmed = split(" ",$tonew_string);
//Starten MySQL eftersprøgelsen
$tosql = "";
while(list($tokey,$toval)=each($tosplit_stemmed)) { if($toval<>" " and strlen($toval) > 0) { $tosql .= "(opretter LIKE '%$toval%') OR "; } } $tosql=substr($tosql,0,(strLen($tosql)-4));//this will eat the last OR $tosql .= " AND "; ?>
Første fil: Følgende linje er forkert: $query = "SELECT * FROM kogebogen WHERE ( AND "; hvad skal ( der ?
Fejl: $query = substr($query,0,(strLen($query)-21));//Sletter intil WHERE slut Hvordan kan du være sikker på at "WHERE findes 21 karatkere før slutningen i din $query streng ? Det har du ingen mulighed for, hvis jeg indtaster 12 forskellige ord.
Anden fil: Fejl: $sql = "SELECT DISTINCT MATCH(navn, tekst, ingredienser) Against ('$string' IN BOOLEAN MODE) as score, navn, tekst, ingredienser, id, hm, raiding, stemmer, oprindelse, dato, opretter, billede FROM kogebogen WHERE ("; $string er ikke defineret noget steder på det tidspunkt. Dernæst har du en "WHERE (" igen, hvilket ikke er særlig smart, da du ikke kan være sikker på hvad der kommer efter.
Og til sidst i filen har du endnu en fejl: $sql .= " AND ) ORDER BY score DESC"; Hvad skal "AND )" der ?? det er ikke korrekt sql.
Du har også denne sætning: $sql=substr($sql,0,(strLen($sql)-4));//this will eat the last OR Men den er meget farlig at kører på det tidspunkt som du går det på og jeg er sikker på det er det jeg har set udpluk af. Det kan komme til at slette noget i din sql som den ikke skulle have gjort.
Generelt, så er det en MEGET dårlig ide at sætte AND eller OR til sidst i de linjer som du tilføjer din sql. Grunden er at du aldrig ved hvad der kommer efter, og så løber du ind i at skulle slette i linjen hele tiden.
En anden ting er at du kun bør have funktioner liggende i de tre sidste filer, alt hvad du foretager dig med din sql bør kun ske i en fil, ellers mister du overblikket, det gjorde jeg. ( Det sammenholdt med at du sletter i din sql streng hele tiden.
En god ide for dig vil være at først finde ud af del elementerne i din WHERE, og så til først til sidst samle elementerne til en sql. Så kan du til sidst sætte alle de AND og OR som er brug for.
Ja... bum bum ... Jeg forstår godt hvorfor min måde ikke er den bedste, men den giver mange muligheder for søgning. Før hen hvor man bare kunne søge efter navnet på opskriften, og der så koden da også pen og fin ud. Men efter at have tilføget bare nogle få flere muligheder blev det hurtigt svært at finde rundt i. Jeg prøvede derfor flere forskellige muligheder, og syntes at denne var den bedste.
Men nu har jeg fundet løsningen et mellemrum betragtes som noget der deler 2 ord. Men da den aldrig køre whilen i de 3 ekstra script fordi der ikke er noget at køre det på sletter den de 4 tegn. der gør at MySQL bliver forkert.
Hvis man for den til at ignorere alt der ikke har noget at gøre med bogstaver eller tal så virker det fint fx.
if ($_GET['search'] == "" || $_GET['search'] == "Søgetekst" || preg_match("/^[^a-zA-Z0-9æøåÆØÅ]+$/", $_GET['search'])) { $query = "SELECT * FROM kogebogen WHERE ( AND "; }
Det gør at brugerne godt kan søge på "Hvilken opskrift har ost ?" eller bare "?" hvis brugeren ikke ved at man kan lade hvær med at skrive noget.
____ Når men hvis du ligger et svar vil jeg godt give dig 50 point, du har da givet mig noget at tænke over og det er jeg glad for :D
Jeg vil da gerne give et svar. Håber du kan bruge noget af det jeg har sagt.
Men igen med brug af trim() kan du fange en søgning som er " ".
Og så vil jeg komme med lidt flere oplysninger, tag at kigge på: http://dk.php.net/implode Når du skal putte AND eller OR mellem forskellige dele af din sql.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.