[php] zoekfunctie in php

Pagina: 1
Acties:
  • 264 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • twisted2000
  • Registratie: Januari 2004
  • Laatst online: 05-03-2021
Momenteel ben ik een simpele zoekfunctie aan t maken voor n site.
Hij moet alleen als ik een woord intik(of meerdere) die in n database kunnen zoeken en dan de bijbehorende artikels (uit de db) weergeven.

Nu ben ik alleen vast gelopen en weet niet hoe k dat op moet lossen. Heb onderstaande code,

maar als ik op meerdere woorden zoek en er komen ook meerdere woorden in een artikel voor dan geeft hij dus zo vaak dat artikel weer als er verscheidene woorden in voorkomen. (dus als er 2 verschillende woorden uit de zoekstring in voorkomen geeft hij 2x het artikel weer) Maar hij moet dan dus maar 1x het artikel weergeven

Weet ook waarom hij dat doet maar weet alleen neit hoe ik dit probleem moet aanpakken. Alvast bedankt.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?
  include("include/php/db.inc.php");
  
  $search = $_REQUEST['search'];
  
   $zoek2 = explode (" ", $search); 
   
   foreach($zoek2 as $zoek3)
   {

  
  $qry = "SELECT name FROM artikel WHERE content LIKE '%$zoek3%'";
    $result = mysql_query($qry) or die("Verbinding mislukt.");
    while ($row = mysql_fetch_array($result)) {
      $name = $row["name"];
      
      echo $name . "<br>";
      }
      }
?>

[ Voor 7% gewijzigd door twisted2000 op 28-10-2004 12:26 ]


Acties:
  • 0 Henk 'm!

  • Bram77
  • Registratie: September 2004
  • Laatst online: 10-07-2023
Is het een idee om $name in een array te stoppen zodat je kunt controleren of het resultaat al voorbij gekomen is?

Acties:
  • 0 Henk 'm!

  • Wacky
  • Registratie: Januari 2000
  • Laatst online: 05-09 21:19

Wacky

Dr. Lektroluv \o/

Of gebruik GROUP BY id ofzo :)

Nu ook met Flickr account


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:54

Janoz

Moderator Devschuur®

!litemod

Per zoekwoord voer je een apparte query uit en druk je de resultaten telkens weer af. het is dus ook niet vreemd dat die resultaten vaker voorkomen. Je zult op 1 of andere manier er voor moeten zorgen dat het of in 1 query gebeurt, of dat je de resultaten eerst opslaat en filtert voordat je ze afdrukt.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Verwijderd

Bram77 schreef op 28 oktober 2004 @ 12:29:
Is het een idee om $name in een array te stoppen zodat je kunt controleren of het resultaat al voorbij gekomen is?
Of nog beter: $id?

Wat gebruik je trouwens handige namen ($search, $zoek2, $zoek3) :X

Acties:
  • 0 Henk 'm!

  • Superdeboer
  • Registratie: December 2002
  • Niet online

Superdeboer

Sa-weee-tah

Kijk eens in dit topic en dan met name naar de manier waarop die dude het uiteindelijk opgelost heeft in [rml]Slagroom in "[ PHP+MySQL] Zoekfunctie"[/rml]

Daar wordt verwezen naar een werkend codevoorbeeld, dat ik zelf ook gebruikt heb om een dergelijke searchfunctie te bouwen. Verder geeft dat topic op zich nog wel een paar handige handreikingen en links om jouw probleem aan te pakken. :)

De truc is om je query dynamisch op te bouwen aan de hand van de vraag of er naar één string als "zoektermA zoektermB" wordt gezocht, of dat je gaat exploden als er daadwerkelijk op twee termen gezocht wordt, bijvoorbeeld in de zin van "zoektermA + zoektermB" en je query daar dus op aan moet passen. :)

When I write my code, only God and I know what it means. One week later, only God knows.
Hell yes it's a Cuban Cigar, but I'm not supporting their economy, I'm burning their fields.


Acties:
  • 0 Henk 'm!

  • jnr24
  • Registratie: Oktober 2004
  • Laatst online: 27-08 11:48
probeer inderdaad iets als:


$query = "SELECT DISTINCT (artikle_ID) FROM artikel WHERE"
of
$query = "SELECT artikel_id,content,bla,bla FROM artikel WHERE" #optie 2

foreach($zoek2 as $zoek3)
{


$query .= "content LIKE '%$zoek3%' OR";

}

$query = preg_replace('/OR$/','',$query) ; # laatste OR weggooien..
$query = preg_replace('/OR$/','GROUP BY 1',$query) ; # GROUP erbij igg optie2

$result = mysql_query($query) or die("Verbinding mislukt.");
while ($row = mysql_fetch_array($result))
echo $row["name"] . "<BR>";


Heel vies maar ondertussen slaap ik nog een nachtje over de mooie oplossing en werkt het wel! :D (hoop ik, sorry ik doe meer perl)

Acties:
  • 0 Henk 'm!

  • twisted2000
  • Registratie: Januari 2004
  • Laatst online: 05-03-2021
werk al n stuk beter nu....

alleen het splitsen van die sql wil hij niet echt doen..dan geeft ie nog n foutmelding

edit: is al gelukt :)

[ Voor 10% gewijzigd door twisted2000 op 28-10-2004 13:49 ]


Acties:
  • 0 Henk 'm!

  • twisted2000
  • Registratie: Januari 2004
  • Laatst online: 05-03-2021
dat doet hij ook niet.....je krijgt dan namelijk ook 3 keer de gehele $query achter elkaar....

als ik het echter zo doe:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?
  include("include/php/db.inc.php");
  
  $search = $_REQUEST['search'];
  
   $zoek2 = explode (" ", $search); 
   
   
   
   foreach($zoek2 as $zoek3)
   {
       $query =  "SELECT DISTINCT (name) FROM artikel WHERE content LIKE '%$zoek3%'";
       
    }
  
  $result = mysql_query($query) or die("Verbinding mislukt.");

   while ($row = mysql_fetch_array($result)) {
      $name = $row["name"];
     
    
      echo $name . "<br>";
      
      }
      
     
      ?>


dus alleen de query in het foreach gedeelte zet, zou je denken eigenlijk dat ie t moet doen (ik zou dat denken) alleen dan geeft hij de eerste "hit" uit de database niet weer.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:54

Janoz

Moderator Devschuur®

!litemod

Wat je hierboven doet is tot 3x toe een query toekennen. En pas na de laatste toekenning ga je de query daadwerkelijk uitvoeren. Alleen de laatste query wordt dus uitgevoerd.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • the_dgc
  • Registratie: Augustus 2001
  • Laatst online: 18-11-2022

the_dgc

raar he..... leven!!

twisted2000 schreef op 28 oktober 2004 @ 12:25:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?
  include("include/php/db.inc.php");
  
  $search = $_REQUEST['search'];
  
   $zoek2 = explode (" ", $search); 
   
   foreach($zoek2 as $zoek3)
   {

  
  $qry = "SELECT name FROM artikel WHERE content LIKE '%$zoek3%'";
    $result = mysql_query($qry) or die("Verbinding mislukt.");
    while ($row = mysql_fetch_array($result)) {
      $name = $row["name"];
      
      echo $name . "<br>";
      }
      }
?>
wat je simpelweg moet doen is eerst je query goed opbouwen en em dan uitvoeren gevolgt door een group by..


of wel:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?
include("include/php/db.inc.php");

$search = $_REQUEST['search'];
  
$zoek2 = explode (" ", $search); 
   
$like = "";   
foreach($zoek2 as $zoek3)  {
    //dus hier gaan we eerst het like gedeelte compleet maken
    if ($like <> "") {
        $like = "$like and LIKE '%$zoek3%'";
    }
    else {
        $like = "LIKE '%$zoek3%'";
    }
}
  
if ($like <> "") {
   //kleine beveiliging voor als er niks is ingevult  
   $qry = "SELECT name FROM artikel WHERE content $like order by artikel";
   $result = mysql_query($qry) or die("Verbinding mislukt.");
   while ($row = mysql_fetch_array($result)) {
        $name = $row["name"];
        echo $name . "<br>";
    }
}
?>

een wereld zonder vrede.. raar?? kijk om je heen dan merkje dat het heel normaal is...
neeeh ik ben niet druk, jij bent gewoon te rustig !!
dual xeon 2.4, 1024 intern, gf3 ti200, maxtor 60 gb 7200 rpm en nog wat opvulling


Acties:
  • 0 Henk 'm!

  • MaNdM
  • Registratie: April 2001
  • Laatst online: 22:38

MaNdM

1000-dingen-doekje

Als je een fulltext-search doet in boolean mode kan je net als bij google met een + voor een woord meerdere zoektermen geven. Dan krijg je een resultaat met waardebepaling. Staat in de MySQL Manual maar is helaas pas vanaf versie 4.1 te gebruiken in MyISAM tabellen. Het is een mogelijkheid en je had de versie van je dbase er niet bijgezet.

To be determined...


Acties:
  • 0 Henk 'm!

  • twisted2000
  • Registratie: Januari 2004
  • Laatst online: 05-03-2021
heb nu dit en t werkt prima (incl het tellen van het aantal hits)

heb alleen nog 1 klein probleempje....het tellen van het aantal hits is hoofdletter gevoelig. Hoe doe ik dat niet hoofdlettergevoelig maken?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<? 
include("include/php/db.inc.php"); 

$search = $_REQUEST['search']; 
   
$zoek2 = explode (" ", $search); 
    
$like = "";  
$count = "";   
foreach($zoek2 as $zoek3)  { 
    //dus hier gaan we eerst het like gedeelte compleet maken 
    if ($like <> "") { 
        $like = "$like OR content LIKE '%$zoek3%'"; 
    } 
    else { 
        $like = "LIKE '%$zoek3%'"; 
    }
    if ($count <> "") { 
        $count = "$count,$zoek3"; 
    } 
    else { 
        $count = "$zoek3"; 
    }    
} 
 echo "Gezocht naar: " . $count . "<BR>";
if ($like <> "") { 
   //kleine beveiliging voor als er niks is ingevult   
   $qry = "SELECT DISTINCT name, content FROM artikel WHERE content $like order by ID"; 
   $result = mysql_query($qry) or die("Verbinding mislukt."); 
   while ($row = mysql_fetch_array($result)) { 
        $name = $row["name"];
        $content = $row["content"];
        
        $count2 = explode (",", $count);
        $n = ""; 
        foreach($count2 as $count3) {
        if ($n <> "") { 
        $n = $n + count(explode($count3,$content)) - 1;
    } 
    else { 
       $n = count(explode($count3,$content)) - 1; 
    }
    }
        echo $name . "-" . $n .   "<br>"; 
    } 
} 
?>

Acties:
  • 0 Henk 'm!

  • the_dgc
  • Registratie: Augustus 2001
  • Laatst online: 18-11-2022

the_dgc

raar he..... leven!!

twisted2000 schreef op 28 oktober 2004 @ 16:38:
heb nu dit en t werkt prima (incl het tellen van het aantal hits)

heb alleen nog 1 klein probleempje....het tellen van het aantal hits is hoofdletter gevoelig. Hoe doe ik dat niet hoofdlettergevoelig maken?
alles lowecase maken..

of in iedergeval in een formaat.. kwa opbouw dus bv eerste letter hoofdletter ofzo

een wereld zonder vrede.. raar?? kijk om je heen dan merkje dat het heel normaal is...
neeeh ik ben niet druk, jij bent gewoon te rustig !!
dual xeon 2.4, 1024 intern, gf3 ti200, maxtor 60 gb 7200 rpm en nog wat opvulling


Acties:
  • 0 Henk 'm!

  • pjotrk
  • Registratie: Mei 2004
  • Laatst online: 15-07 18:43
Wat voor datatype heeft de colom content?

Sommige datatypes worden namelijk case-sensitive vergeleken (BLOB en binary), andere worden standaard case-insensitive vergeleken (zoals het TEXT datatype).

Acties:
  • 0 Henk 'm!

  • mocean
  • Registratie: November 2000
  • Laatst online: 04-09 10:34
Zoek eens op Match Against (dat is SQL), dan kan je zoiets doen:

code:
1
2
3
SELECT DISTINCT ID, TxtValue 
       ((MATCH (TxtValue) AGAINST ('".$userinput."')) AS score
FROM Objects ORDER BY score";

[ Voor 19% gewijzigd door mocean op 29-10-2004 17:33 ]

Koop of verkoop je webshop: ecquisition.com


Acties:
  • 0 Henk 'm!

  • Wacky
  • Registratie: Januari 2000
  • Laatst online: 05-09 21:19

Wacky

Dr. Lektroluv \o/

Waarom doe je het niet zo:

code:
1
SELECT name FROM artikel WHERE content LIKE '%$zoek3% OR content LIKE '%$zoek2% OR content LIKE '%$zoek3%' GROUP BY ID


Of vat ik het probleem nou niet goed :+

Nu ook met Flickr account


Acties:
  • 0 Henk 'm!

  • pjotrk
  • Registratie: Mei 2004
  • Laatst online: 15-07 18:43
Wacky schreef op 29 oktober 2004 @ 17:40:
Waarom doe je het niet zo:

code:
1
SELECT name FROM artikel WHERE content LIKE '%$zoek3% OR content LIKE '%$zoek2% OR content LIKE '%$zoek3%' GROUP BY ID


Of vat ik het probleem nou niet goed :+
Zo naar zijn code kijkend wordt er uiteindelijk ook wel zo'n query opgebouwd :)

Maar nu ik zijn code zo eens lees geloof ik dat ik de vraag ook verkeerd heb gegrepen en geeft the_dgc idd al het antwoord.

Overigens kan de code wel wat overzichtelijker (niet getest)
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?
include("include/php/db.inc.php");

$searchWords = preg_split("/ +/", strtolower($_REQUEST['search'])); //preg_split ipv explode om lege array items te voorkomen
$like = "";
foreach($searchWords as $searchWord)  {
    //dus hier gaan we eerst het like gedeelte compleet maken
    if ($like <> "") {
        $like .= " OR ";
    }
    $like .= "content LIKE '%" . $searchWord . "%'";
}
echo "Gezocht naar: " . implode ( ", " , $searchWords) . "<BR>";

if ($like <> "") {
    //kleine beveiliging voor als er niks is ingevult
    $qry = "SELECT name, content FROM artikel WHERE " . $like . " ORDER BY id";
    $result = mysql_query($qry) or die("Verbinding mislukt.");
    while ($row = mysql_fetch_array($result)) {
        $name = $row['name'];
        $content = strtolower( $row['content'] );

        $n = 0;
        foreach($searchWords as $searchWord) {
            $n += substr_count($content, $searchWord);
        }
        echo $name . "-" . $n . "<br>";
    }
}
?>

[ Voor 12% gewijzigd door pjotrk op 29-10-2004 19:25 ]


Acties:
  • 0 Henk 'm!

  • Bram77
  • Registratie: September 2004
  • Laatst online: 10-07-2023
Wacky schreef op 29 oktober 2004 @ 17:40:
Waarom doe je het niet zo:

code:
1
SELECT name FROM artikel WHERE content LIKE '%$zoek3% OR content LIKE '%$zoek2% OR content LIKE '%$zoek3%' GROUP BY ID


Of vat ik het probleem nou niet goed :+
Op deze manier zoek je maar met 1 string (die uit meerdere woorden kan bestaan). Als je dus zoekt op "appel taart", dan vindt hij alleen dat waar appel en taart na elkaar staan. Maar niet een artiekel waar enkel "appel" of enkel "taart" in staat. "Appeltaart" dus wel!

[ Voor 11% gewijzigd door Bram77 op 30-10-2004 16:20 ]


Acties:
  • 0 Henk 'm!

Verwijderd

mocean schreef op 29 oktober 2004 @ 17:33:
Zoek eens op Match Against (dat is SQL), dan kan je zoiets doen:

code:
1
2
3
SELECT DISTINCT ID, TxtValue 
       ((MATCH (TxtValue) AGAINST ('".$userinput."')) AS score
FROM Objects ORDER BY score";
Oftewel Mysql Fulltext search.. Moet je wel eerst je een fulltext index aanmaken in je tabel, moet je dus even rondkijken, bijvoorbeeld googlen op mysql fulltext (levert volgens mij btw wat meer resultaten op dan op match against). Dit artikel moet genoeg zijn om het een beetje te snappen.

[ Voor 29% gewijzigd door Verwijderd op 31-10-2004 15:12 ]


Acties:
  • 0 Henk 'm!

  • MaNdM
  • Registratie: April 2001
  • Laatst online: 22:38

MaNdM

1000-dingen-doekje

Verwijderd schreef op 31 oktober 2004 @ 15:08:
[...]


Oftewel Mysql Fulltext search.. Moet je wel eerst je een fulltext index aanmaken in je tabel, moet je dus even rondkijken, bijvoorbeeld googlen op mysql fulltext (levert volgens mij btw wat meer resultaten op dan op match against). Dit artikel moet genoeg zijn om het een beetje te snappen.
Wat in het artikel niet vermeld wordt is dat de fulltext functies niet werken in MySQL versies ouder dan 4.1.x wat dus een grote bepalende factor is in het geheel.

To be determined...


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Bram77 schreef op 30 oktober 2004 @ 16:19:
Op deze manier zoek je maar met 1 string (die uit meerdere woorden kan bestaan). Als je dus zoekt op "appel taart", dan vindt hij alleen dat waar appel en taart na elkaar staan. Maar niet een artiekel waar enkel "appel" of enkel "taart" in staat. "Appeltaart" dus wel!
Hoe kom je daar nou bij? Er staat in die query OR en niet AND, dus hij evalueert naar true wanneer één, twee of alledrie de zoekwoorden voorkomen in het contentveld.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.

Pagina: 1