[PHP] Duplicate entry voorkomen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 21-09 08:36
Ik heb veld waar je een tekst kan invoeren deze word opgeslagen in een database, hoe kan ik in PHP controleren of die tekst niet al in de database voorkomt?

Bijvoorbeeld onderstaande zin, chop ik in 3 aparte woorden, en wil dan de database checken of die een regel heeft waar alle 3 de woorden in voorkomen. (hoofdletter ongevoelig)

code:
1
2
3
$str = 'hypertext language, programming';
$chars = preg_split("/[\s,]+/", $str);
print_r($chars);


Kom er niet zo goed uit, checken tegen 1 woord lukt me wel .. maar al die woorden niet :(
Als het niet voorkomt mag de nieuwe tekst in de database worden toegevoegd, anders niet.

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Ze moeten op één regel staan? En de volgorde is niet relevant? Dan zul je waarschijnlijk alles wat in de database staat moeten selecteren, en dan een voor een splitten op regeleindes. En dan zul je daarna in elke regel moeten gaan matchen met bijvoorbeeld stristr().

'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.


Acties:
  • 0 Henk 'm!

  • chris
  • Registratie: September 2001
  • Laatst online: 11-03-2022
Als ze alledrie tegelijkertijd voor kunnen komen moet je dus zoeken op iets als:
/woord1(.*)woord2(.*)woord3/ of /woord1(.*)woord3(.*)/woord2(.*)/, etc.

Acties:
  • 0 Henk 'm!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 21-09 08:36
Ik was dus inderdaad aan het kloten met stristr().
Maar dan lukt het me alleen om 1 woord te checken en niet allemaal (mits et er meerdere zijn)...

Zat namelijk te denken om de database in een while loop te gooien en dan weer in een if loop die stristr om elke regel stuk voor stuk te checken, maar hoe dan zinnen te checken ... en aan te geven of ie wel of nie bestaat ... daar ben ik dus nog nie achter...

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Even uit de losse hand, vrij slecht ontworpen en niet getest:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function magInvoeren($query, $woorden) {
  $rs = mysql_query($query);
  while ($row = mysql_fetch_assoc($rs)) {
    $regels = preg_split("/[\r\n]*/", $row['veld']);
    foreach ($regels as $regel) {
      $ret = false;
      foreach ($woorden as $woord) {
        if (!stristr($regel, $woord)) {
          $ret = true;
        }
      }
      if (!$ret) return false;
    }
  }
  return true;
}

Zoiets zou moeten werken met elk aantal woorden. $woorden is hierbij een array van woorden, en $query is uiteraard gewoon een query. :P

'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.


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Misschien dat ik de bedoeling niet snap,
Maar je kunt toch
[sql=code]WHERE woord LIKE '%woord1%' AND woord LIKE '%woord2%' AND woord LIKE '%woord3%'[/] doen :?

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

frickY schreef op woensdag 04 januari 2006 @ 22:10:
Misschien dat ik de bedoeling niet snap,
Maar je kunt toch
SQL:
1
WHERE woord LIKE '%woord1%' AND woord LIKE '%woord2%' AND woord LIKE '%woord3%'
doen :?
Als ik het goed begrijp gaat het de topicstarter om de woorden per regel, dus dan zou je die ook al eerst moeten splitten. Als dat niet hoeft, dan werkt jouw oplossing wel, maar niet als het toevallig het eerste of het laatste woord van het veld betreft.

'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.


Acties:
  • 0 Henk 'm!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 21-09 08:36
-NMe- schreef op woensdag 04 januari 2006 @ 22:06:
Even uit de losse hand, vrij slecht ontworpen en niet getest:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function magInvoeren($query, $woorden) {
  $rs = mysql_query($query);
  while ($row = mysql_fetch_assoc($rs)) {
    $regels = preg_split("/[\r\n]*/", $row['veld']);
    foreach ($regels as $regel) {
      $ret = false;
      foreach ($woorden as $woord) {
        if (!stristr($regel, $woord)) {
          $ret = true;
        }
      }
      if (!$ret) return false;
    }
  }
  return true;
}

Zoiets zou moeten werken met elk aantal woorden. $woorden is hierbij een array van woorden, en $query is uiteraard gewoon een query. :P
Ga dit is proberen :)
Die SQL query werkt denk nie want je weet nooit hoeveel woorden er in de zin staan die mensen invoeren....

Acties:
  • 0 Henk 'm!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 21-09 08:36
hmm werk nie .. heb nu

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if($zoeken != "") {
    $insert_yes = true;
    $result = mysql_query("SELECT * FROM top20 ORDER BY rowid DESC");
    $woorden = preg_split("/[\s,]+/", $zoeken);
    while ($row = mysql_fetch_assoc($result)) {
          $regels = preg_split("/[\r\n]*/", $row['woord']);
                foreach ($regels as $regel) {
                    $ret = false;
                    foreach ($woorden as $woord) {
                        if (!stristr($regel, $woord)) {
                            $ret = true;
                        }
                    }
                    if (!$ret) $insert_yes = false;
                }
    }
    if($insert_yes == true) {
    mysql_query("INSERT INTO top20 (woord) VALUES ('$zoeken')");
    }


Maar blijf dubbele entries krijgen :'(

[ Voor 15% gewijzigd door Reveal! op 04-01-2006 22:51 ]


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Reveal! schreef op woensdag 04 januari 2006 @ 22:31:
Die SQL query werkt denk nie want je weet nooit hoeveel woorden er in de zin staan die mensen invoeren....
Maakt dat wat uit hoeveel woorden het zijn? Je kan die query toch dynamisch bouwen?

Acties:
  • 0 Henk 'm!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 21-09 08:36
Dan zou je me heel erg helpen met een voorbeeld :P
Een vraagje nog maakt SQL wel onderscheid tussen hoofdletters en kleine letters ?

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Mischien dat dit werkt:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

function splitInWords($string)
{
    return preg_split("/[\s,]+/", $string);
}

function fieldWithWordsIsPresent($words)
{
    $whereConditions = array();
    foreach ( $words as $word )  $whereConditions[] = "'%" . mysql_real_escape_string($word) . "%' LIKE veld";
    $query = "SELECT 1 FROM tabel WHERE " . implode(" AND ", $whereConditions);
    $result = mysql_query($query) or die(mysql_error());
    return mysql_num_rows($result) > 0;
}

$string = 'hypertext language, programming';
$isPresent = fieldWithWordsIsPresent(splitInWords($string));

?>

Heb het niet getest overigens.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Reveal! schreef op woensdag 04 januari 2006 @ 22:58:
Dan zou je me heel erg helpen met een voorbeeld :P
Een vraagje nog maakt SQL wel onderscheid tussen hoofdletters en kleine letters ?
dat is toch niet zo moeilijk :?

PHP:
1
2
3
4
5
6
7
8
9
$str = 'hypertext language, programming';
$chars = preg_split("/[\s,]+/", $str);

$query = "SELECT * FROM blaat WHERE 1";

foreach($chars as $word){
  $query .= " AND woord LIKE '%".$word."%'";
}
echo $query;


voorbeeld

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Ik persoonlijk zou het totaal anders aanpakken dan er tot nu toe gepost ( ervanuit gaande dat je regels tabel vrij groot zal worden ) want like %query's% zijn bijna in geen enkele dbase leuk.

Gewoon 1 tabel aanmaken met daarin alleen woord-id en de unieke woorden uit alle zinnen.
Dan 1 tabel met daarin woord-id en zin-nr.

Als dit voorwerk gedaan is hoef je alleen maar je zin te splitsen in unieke woorden, deze woorden zoek je op in je woordentabel ( beperkt aantal woorden dus snel ). Dan zoek je aan de hand van je woord-id's ( integer met goede indexen dus supersnel ) weer de zinnen op waarin de woorden staan en als je dan alle woorden in 1 zinnr hebt staan heb je een match, anders toevoegen.

Het toevoegen zal langzaam gaan omdat hij dan veel moet veranderen qua indexen etc. Maar als dit primair gebruikt wordt om te zoeken dan werkt het een stuk sneller dan %like% query's die al je indexen niet gebruiken...

Acties:
  • 0 Henk 'm!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 21-09 08:36
%zoek% SQL query kan het eigenlijk niet worden ... want dan matched hij geen exacte worden...
Dus als iemand alleen zoekt op pl pakt ie alles waar pl in voorkomt en dat is dus geen exacte match ...

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Reveal! schreef op woensdag 04 januari 2006 @ 23:40:
%zoek% SQL query kan het eigenlijk niet worden ... want dan matched hij geen exacte worden...
Dus als iemand alleen zoekt op pl pakt ie alles waar pl in voorkomt en dat is dus geen exacte match ...
True, maar je kan ook een spatie meepakken, of achteraf de results nogmaals checken in PHP.
Hoewel ik (afhankelijk van de hoeveelheid data, nu en in de toekomst) eerder zal kijken naar zo'n index systeem zoals Gomez12 hierboven post :)

Acties:
  • 0 Henk 'm!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 21-09 08:36
Dat klinkt alleen heel ingewikkeld en beetje n00b nog :)
Maar zoiets als ik probeer te doen moet toch bestaan :S

Een forum kan toch ook checken bij het aanmaken van een topic of deze naam al bestaat :?
Dat is eigenlijk ongeveer hetzelfde als wat ik probeer te doen....

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

maar jij zoekt naar losse woorden, dat is iets anders dan een kolom die uniek moet zijn ;)

Acties:
  • 0 Henk 'm!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 21-09 08:36
mwoah ik zoek eigenlijk een zin...
maar soms typted iemand het met een hoofdletter soms niet en soms bv.

Gathering of Tweakers en Tweakers Gathering

mja dat is etzelfde :)

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Reveal! schreef op woensdag 04 januari 2006 @ 23:53:
Dat klinkt alleen heel ingewikkeld en beetje n00b nog :)
Maar zoiets als ik probeer te doen moet toch bestaan :S

Een forum kan toch ook checken bij het aanmaken van een topic of deze naam al bestaat :?
Dat is eigenlijk ongeveer hetzelfde als wat ik probeer te doen....
Ok dan nieuw idee voor een forum-topic name check. ( oftewel een string check ).
Kijk eerst eens waar het je om gaat, vind jij dat er verschil is tussen :
1 : Hallo, dit is een test.
2 : Hallo dit iseen TEST

Indien nee strip dan je invoer eerst van alle overbodige ( oftewel alles wat niet van a-z is, desgewenst buitenlandse leestekens ( e met een streepje / dakje / hekje omzetten naar een gewone e ) ) leestekens dus ook spaties en komma's en punten. ( eindresultaat Halloditiseentest)
Zet dan je invoer om naar hoofdletters / kleine letters ( gewoon 1 soort als standaard hanteren ) (eindresultaat HALLODITISEENTEST )
Vergelijk dan je invoer met de dbase ( die vanwege eerdere controles alleen dit soort strings bevat ) Dan praat je de hele tijd over dezelfde invoer ongeacht hoe de gebruiker het invoert.

Indien ja, doe dan bovenstaande stappen in mindere mate ( naar eigen inzicht ) tot je een resultaat bereikt wat voor jou acceptabel is.

Oftewel standaardiseer waarnaar je zoekt. Dan valt het allemaal hardstikke mee en hoef je nog steeds geen like-functies uit te voeren.

Btw. Mijn advies is om dit soort dingen gewoon via een 100 stringreplacements uit te voeren ipv 1 regexp. Want regexp is IMHO alleen maar beperkt bruikbaar in de meeste gevallen en wordt veels te snel gebruikt. Een beetje regexp ( in de stelling van 1 regexp tegenover 100 stringreplacements / 100 string in string funties ) is :
a : heel moeilijk te doorgronden als je het later terugleest ( Bij stringreplacements zie ik heel snel waar ik zit in het debuggen )
b : Erg duur tegenover enkele ( minder dan 25 ) string_functies ( afhankelijk per programmeertaal )

In sommige gevallen kom je bijna niet onder een regex uit, maar dit is imho niet zo'n geval./

Acties:
  • 0 Henk 'm!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 21-09 08:36
Hmm dat is een mogelijkheid....
Maar bv woorden in andere volgorde is inprincipe ook hetzelfde ..

Hoe zou ik dat dan moeten aanpakken ?

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Reveal! schreef op donderdag 05 januari 2006 @ 00:50:
mwoah ik zoek eigenlijk een zin...
maar soms typted iemand het met een hoofdletter soms niet en soms bv.

Gathering of Tweakers en Tweakers Gathering

mja dat is etzelfde :)
Is het volgende dan ook hetzelfde:
The Gathering : Een concert waarbij alleen Tweakers aanwezig waren.
of
Tweakers.net : een nieuwsverzameling ( Gathering )
of
HCC 2005 : A Gathering of all kinds of Tweakers.

Met de simpele 5-regelige scriptjes met like heb je grote kans dat je bovenstaande titels ook vind als je jouw combinatie wilt kunnen vinden. Of je vind jouw combinatie niet en bovenstaande ook niet ( Alhoewel mijn zinnen vrij vergezocht zijn, maar gaat meer om het idee )

Als je wilt krijgen wat jij nu ( bij 3e poging ) zegt dan ga je toch wel over een uitgebreid script praten, waar je eerst eens goed over moet kunnen nadenken want :
a : Hij moet aan woordherkenning kunnen doen ( hij moet zien dat Gathering en of en Tweakers 3 woorden zijn )
b : Hij moet een waarde kunnen geven aan een woord ( want of is blijkbaar niet belangrijk , want Gathering en Tweakers zijn wel belangrijk terwijl de combinatie Gathering en of niet relevant is )
c : hij moet aan plaatsbepaling van de woorden doen ( of vind jij een resultaat waar Tweakers en Gathering naast elkaar staan net zo belangrijk als een resultaat waar er tussen Tweakers en Gathering 200 andere woorden staan )
d : Hij moet case insensitive zijn

Dan zou ik persoonlijk (als simpele oplossing ) voor een uitbreiding van mijn 1e oplossing gaan door naast zinnr ook nog een het woordnr in de zin in op te slaan zodat je punt c ondervangt en iets in de trant van woorden kleiner dan 4 letters ( of een uitzonderingstabel ) niet opslaan om punt b te ondervangen. Maarja ondertussen ga je meer naar een zoekscript dan naar een duplicate entry controle.

Want onder "Gathering of Tweakers" en "Tweakers Gathering" kunnen heel andere topics ontstaan en dit zou ik persoonlijk ook niet gaan check, hooguit of de topictitle wel uniek is ( in een periode van 30 dagen want anders mag je nooit meer een topic heropenenen met dezeldfe title )

Acties:
  • 0 Henk 'm!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 21-09 08:36
Eigenlijk zou het script van -NMe- voldoende zijn alleen werkt ie helaas nie ....

Maar als het nu zou werken met de exacte woorden, waarbij het niet uitmaakt op welke plek ze staan zou ik al heel blij zijn :)

Kan altijd later nog voegwoorden als (en|of|de|een) altijd nog wegfilteren ...

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Reveal! schreef op donderdag 05 januari 2006 @ 01:31:
Eigenlijk zou het script van -NMe- voldoende zijn alleen werkt ie helaas nie ....
Mwah, het idee van dat script is in elk geval goed, en het lijkt me dat het met een beetje debuggen wel aan de praat te krijgen moet zijn. Maar eigenlijk ben ik het stiekem wel een beetje met Gomez12 eens dat dit een beetje een vreemde oplossing is.

Misschien kun je trouwens wat met similar_text(), levenshtein() of soundex()? Ik weet niet of die functies in dit geval toepasbaar zijn, maar je zou het kunnen onderzoeken. De laatste van die drie bestaat trouwens ook in MySQL zelf geloof ik.

'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