[php] strpos check op twee waarden?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Van Sebas

Van Sebas

14/11/2020 15:13:51
Quote Anchor link
Ik ben bezig om producten te importeren en daarbij wil ik ze eerst door een check halen om te controleren of een bepaald woord erin staat en als dat het geval is komen ze bij een bepaalde categorie.
Nu wil ik hiervoor strpos gebruiken en werkt dat prima wanneer ik zoek of een bepaald woord voorkomt in de omschrijving, maar wanneer ik zoek op een woord wat in de omschrijving moet zitten en een woord wat niet in de omschrijving mag zitten gaat het fout en werkt het niet. Kan iemand me vertellen wat ik nu precies fout doe?

Dit is mijn basis code:
if ((strpos(strtolower($omschrijving), 'rode') !== false) OR ((strpos(strtolower($omschrijving), 'gele') !== false) AND (!strpos(strtolower($omschrijving), 'man') !== false))) {
//Als het woord rode voorkomt dan toevoegen.
//Als het woord gele voorkomt ook toevoegen alleen wanneer het woord geld en man voorkomt dan niet.
$categorie = "Betreffende categorie";
}

en zoals gezegd gaat het fout bij de check op het woord gele en man en als beide erin staan moet hij niet toegevoegd worden.

Nu heb ik het ook met deze regels geprobeerd:
if ((strpos(strtolower($omschrijving), 'rode') !== false) OR ((strpos(strtolower($omschrijving), 'gele') !== false) AND (strpos(strtolower($omschrijving), 'man') === false))) {

Of zo:
if ((strpos(strtolower($omschrijving), 'rode') !== false) OR ((strpos(strtolower($omschrijving), 'gele') !== false) AND (strpos(strtolower($omschrijving), 'man') !== false))) {

En zo:
if ((strpos(strtolower($omschrijving), 'rode') !== false) OR ((strpos(strtolower($omschrijving), 'gele') !== false) AND (strpos(strtolower($omschrijving), 'man') === true))) {


Maar die check op twee waarden gaat maar niet goed.
Wat doe ik nu fout?
 
PHP hulp

PHP hulp

19/01/2021 13:44:58
 
Thomas van den Heuvel

Thomas van den Heuvel

14/11/2020 16:57:49
Quote Anchor link
Het probleem is de ! voor de laatste strpos. Zet hier ofwel haken omheen, of makkelijker, verander !strpos(...) !== false in strpos(...) === false.

Ook is het misschien beter om respectievelijk || en && te gebruiken in plaats van OR en AND voor dit soort Boolse statements.
Gewijzigd op 14/11/2020 17:27:59 door Thomas van den Heuvel
 
Ad Fundum

Ad Fundum

14/11/2020 20:10:43
Quote Anchor link
Wat zou er beter zijn aan || en && dan aan and en or?
Is dat niet gewoon een kwestie van persoonlijke smaak?
Zo zou ik er blind vanuit durven gaan dat programmeurs die ook JavaScript typen geneigd zijn om de dubbele ampersand te gebruiken, waar mensen die meer SQL typen eerder geneigd zijn om het keyword and te gebruiken. Voor PHP maakt het niet uit toch?

EDIT: toch maar even in de manual gekeken voor die laatste vraag. Het maakt wel degelijk uit voor PHP. Toch wel maf dat ik nooit bugs heb gekregen hierdoor, waarschijnlijk omdat ik nooit constructies gebruik waarbij het resultaat in een bestaande variabele terechtkomt. Ik gebruik het altijd voor nieuwe variabelen of bijvoorbeeld in een if()-statement.

PHP heeft de operator && vanuit C, maar ik vraag me nu wel af wanneer en vooral waarom de operator and is uitgevonden. Iemand enig idee wat je daar extra mee kan? (Behalve dat het bugs kan introduceren..)
Gewijzigd op 14/11/2020 20:24:55 door Ad Fundum
 
- Ariën -
Beheerder

- Ariën -

14/11/2020 20:24:45
Quote Anchor link
Of je AND en OR gebruikt of && en ||, er zit een voorrangsregel in. Maar ik gebruik altijd && en ||.
 
Ad Fundum

Ad Fundum

14/11/2020 20:27:30
Quote Anchor link
Ik ben om hoor, ondanks dat ik het lelijker vind staan.
&& en || werken intuïtiever.

Wat is de toegevoegde waarde van and en or?
 
Thomas van den Heuvel

Thomas van den Heuvel

14/11/2020 21:13:19
Quote Anchor link
Nou, als je ff de reactie op je mysqli_query_params() functie leest :p.
 
Van Sebas

Van Sebas

15/11/2020 13:28:51
Quote Anchor link
Bedankt heren voor een verduidelijking.
En wanneer ik !strpos verander naar strpos en ===false opgeef zoals hieronder dan krijg ik wel goed antwoord.

if ((strpos(strtolower($omschrijving), 'rode') !== false) OR ((strpos(strtolower($omschrijving), 'gele') !== false) AND (strpos(strtolower($omschrijving), 'man') === false))) {

Ik loop alleen nog tegen een ander probleem aan en ik denk tot dat in eerste instantie ook tot het probleem kwam en dat is het volgende. Ik wil namelijk checken of het woord 'gele' voorkomt en zoja dan toevoegen maar wanneer in dezelfde omschrijving ook het woord 'man' of 'vrouw' voorkomt dan moet die niet toegevoegd worden. Maar als ik dit ervan maak dan gaat het niet goed:

if ((strpos(strtolower($omschrijving), 'rode') !== false) || ((strpos(strtolower($omschrijving), 'gele') !== false) && ((strpos(strtolower($omschrijving), 'man') === false) || (strpos(strtolower($omschrijving), 'vrouw') === false)))) {
 
Ad Fundum

Ad Fundum

15/11/2020 13:31:25
Quote Anchor link
'and' en 'or' voor flow control... beter leesbaar dan if? ff testen...

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
// and voor flow control
defined('TOEGANG') or die('Geen toegang');

// vs. if() voor flow control
if (!defined('TOEGANG')) die('Geen toegang');
?>


Tsja.. volgens mij is de toegevoegde waarde nihil, of er moet nog een andere use case zijn. Dit weegt nog niet op tegen de verwarring die het kan veroorzaken.
Gewijzigd op 15/11/2020 13:32:32 door Ad Fundum
 
Van Sebas

Van Sebas

15/11/2020 13:39:39
Quote Anchor link
Volgens mij was ik iets te snel en moet het zo:

((strpos(strtolower($omschrijving), 'gele') !== false) &&
((strpos($omschrijving, 'man') || strpos($omschrijving, 'vrouw')) === false))
 
Thomas van den Heuvel

Thomas van den Heuvel

15/11/2020 14:04:28
Quote Anchor link
Het loont de moeite om dit eens uit te schrijven over meerdere regels, en deze wellicht te voorzien van commentaar van wat nu eigenlijk de bedoeling is. Ook zijn bepaalde haken overbodig. Je krijgt dan, uitgaande van het bovenstaande, het volgende:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
if (
    strpos(strtolower($omschrijving), 'rode') !== false
    ||
    (

        strpos(strtolower($omschrijving), 'gele') !== false
        &&
        (

            strpos(strtolower($omschrijving), 'man') === false
            ||
            strpos(strtolower($omschrijving), 'vrouw') === false
        )
    )
) {

    echo 'ok';
}
else {
    echo 'nok';
}

?>

Het probleem zit hem hier in het laatste OR-statement. Immers, hier zeg je "als de omschrijving ongelijk is aan man of vrouw". Maar als deze het woord "man" bevat dan voldoet de verschilt-van-vrouw conditie en andersom. Op het moment dat de omschrijving het woord "gele" bevat moet aan *al* deze condities voldaan zijn. Je zult hier dus een constructie met ANDs moeten werken:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
if (
    strpos(strtolower($omschrijving), 'rode') !== false
    ||
    (

        strpos(strtolower($omschrijving), 'gele') !== false
        &&
        strpos(strtolower($omschrijving), 'man') === false
        &&
        strpos(strtolower($omschrijving), 'vrouw') === false
    )
) {

    echo 'ok';
}
else {
    echo 'nok';
}

?>

Een andere observatie is de volgende: je doet hier nogal vaak hetzelfde. Op het moment dat je vaak eenzelfde bewerking uitvoert loont het de moeite om hier een functie voor te introduceren. Dit kan ook helpen met de leesbaarheid. Beschouw de volgende functie:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
function contains($needle, $haystack) {
    return strpos(strtolower($haystack), $needle) !== false;
}

?>

En gebruik dan de functie in de vorige controle:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
if (
    contains('rode', $omschrijving)
    ||
    (
contains('gele', $omschrijving) && !contains('man', $omschrijving) && !contains('vrouw', $omschrijving))
) {

    echo 'ok';
}
else {
    echo 'nok';
}

?>

Dat leest toch een stuk prettiger nietwaar? Dit maakt het waarschijnlijk makkelijker om dit soort expressies op te stellen en is daarmee ook direct "zelfdocumenterend".
Gewijzigd op 15/11/2020 14:10:07 door Thomas van den Heuvel
 
Rob Doemaarwat

Rob Doemaarwat

15/11/2020 15:08:33
Quote Anchor link
gratis in PHP 8: str_contains
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.