Een zoek veld voor twee database velden

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Donald Boers

Donald Boers

23/07/2016 18:00:19
Quote Anchor link
Voor een facturatie systeem heb ik een pagina waar ik naar facturen wil kunnen zoeken. Dit zou moeten kunnen via een tekst veld, door op het ordernummer te zoeken (een specifieke factuur) of op de naam van een klant (kunnen meerdere facturen zijn). Ik dacht dit op de volgende manier te kunnen verwezenlijken:

Model
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
function klant_facturen_zoeken($search)
{
    sql    = "SELECT O.order_id
                , O.order_datum
                , K.naam
             FROM offline_orders O
             JOIN klant_gegevens K ON O.klant_id = K.klant_id
            WHERE (O.order_id LIKE :search OR K.naam LIKE :search2)";

    $stmt = $this->pdo->prepare($sql);
    $stmt->execute(array(':search' => '%'.$search.'%', ':search2' => '%'.$search.'%'));

    return $stmt->fetchAll();    
}


Controller:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
$search         = filter_input(INPUT_GET, 'search', FILTER_FLAG_STRIP_LOW);
$klant_facturen    = $this->administratie->klant_facturen_zoeken($search);


waarbij de variabele $search het tekstveld in het formulier is.

Dit levert geen resultaten op. Terwijl wanneer de zelfde query in phpMyAdmin uitvoer met vaste waardes zoals:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
SELECT O.order_id, O.order_datum , K.naam FROM offline_orders O JOIN klant_gegevens K ON O.klant_id = K.klant_id WHERE (O.order_id LIKE '%000001%' OR K.naam LIKE '');

of
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
SELECT O.order_id, O.order_datum , K.naam FROM offline_orders O JOIN klant_gegevens K ON O.klant_id = K.klant_id WHERE (O.order_id LIKE '' OR K.naam LIKE '%Donald Boers%');

krijg ik wel de juiste resultaten. Wat is er fout in mijn aanpak waardoor ik geen resultaten krijg.

Bij voorbaat dank
Gewijzigd op 23/07/2016 18:04:29 door Donald Boers
 
PHP hulp

PHP hulp

25/12/2024 17:25:10
 
- SanThe -

- SanThe -

23/07/2016 18:33:38
Quote Anchor link
Op regel 3
sql = "SELECT O.order_id
moet zijn
$sql = "SELECT O.order_id

Staat je foutmelding wel aan?
 
Donald Boers

Donald Boers

23/07/2016 21:51:27
Quote Anchor link
- SanThe - op 23/07/2016 18:33:38:
Op regel 3
sql = "SELECT O.order_id
moet zijn
$sql = "SELECT O.order_id

Staat je foutmelding wel aan?


Sorry. Dat was een typo in het bericht. In de query zelf staat het namelijk wel goed. Dus de vraagt blijft bestaan wat ik fout doe of over het hoofd zie.

Alvast bedankt
 
Obelix Idefix

Obelix Idefix

24/07/2016 00:58:49
Quote Anchor link
Heeft $search wel een waarde?
 
Donald Boers

Donald Boers

24/07/2016 08:12:27
Quote Anchor link
Obelix en Idefix op 24/07/2016 00:58:49:
Heeft $search wel een waarde?

Ja zeker wel. Ik heb het zowel geprobeerd met alleen het order_id:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
WHERE O.order_id LIKE :search

$stmt = $this->pdo->prepare($sql);
$stmt->execute(array(':search' => '%'.$search.'%'));

en hetzelfde met naam. En toen kreeg ik wel resultaten wanneer ik iets in tikte in het zoekveld. Vanaf het moment dat ik ze beidde gebruikte krijg ik geen resultaten meer
 
Ward van der Put
Moderator

Ward van der Put

24/07/2016 10:16:59
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
WHERE (O.order_id LIKE :search OR K.naam LIKE :search2)

Het ordernummer is een integer en de klantnaam een string.
Volgens die logica kun je de OR in de WHERE-clausule uitsplitsen.
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
20
21
22
23
24
25
<?php
public function klant_facturen_zoeken($search)
{

    $sql = '
        SELECT
               O.order_id,
               O.order_datum,
               K.naam
          FROM offline_orders O
          JOIN klant_gegevens K ON O.klant_id = K.klant_id
    '
;

    // Zoek numeriek op ordernummer of alfanumeriek op klantnaam
    if (is_numeric($search)) {
         $sql .= 'WHERE O.order_id LIKE ?';
    }
else {
         $sql .= 'WHERE K.naam LIKE ?';
    }


    $stmt = $this->pdo->prepare($sql);
    $stmt->bindParam(1, "%$search%", \PDO::PARAM_STR);
    $stmt->execute();
    return $stmt->fetchAll();    
}

?>
Gewijzigd op 24/07/2016 10:21:07 door Ward van der Put
 
Donald Boers

Donald Boers

24/07/2016 11:33:56
Quote Anchor link
Ward van der Put op 24/07/2016 10:16:59:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
WHERE (O.order_id LIKE :search OR K.naam LIKE :search2)

Het ordernummer is een integer en de klantnaam een string.
Volgens die logica kun je de OR in de WHERE-clausule uitsplitsen.
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
20
21
22
23
24
25
<?php
public function klant_facturen_zoeken($search)
{

    $sql = '
        SELECT
               O.order_id,
               O.order_datum,
               K.naam
          FROM offline_orders O
          JOIN klant_gegevens K ON O.klant_id = K.klant_id
    '
;

    // Zoek numeriek op ordernummer of alfanumeriek op klantnaam
    if (is_numeric($search)) {
         $sql .= 'WHERE O.order_id LIKE ?';
    }
else {
         $sql .= 'WHERE K.naam LIKE ?';
    }


    $stmt = $this->pdo->prepare($sql);
    $stmt->bindParam(1, "%$search%", \PDO::PARAM_STR);
    $stmt->execute();
    return $stmt->fetchAll();    
}

?>


Hallo Ward. Hartelijk bedankt voor je reactie en oplossing. Ik ga dat zeer zeker proberen. Echter net voor jij reageerde heb ik een aantal wijzigingen aangebracht. Zo heb ik de naam van het zoekveld in het formulier veranderd van search in zoekTerm en in de Model heb ik de Param veranderd van $search in $term
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
    function klant_facturen_zoeken($term)
    {
        $sql    =     "SELECT O.order_id
                           , O.order_datum
                           , K.naam
                        FROM offline_orders O
                        JOIN klant_gegevens K ON O.klant_id = K.klant_id
                       WHERE (order_id LIKE :term OR naam LIKE :term2)";
                      
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(array(':term' => $term.'%', ':term2' => $term.'%'));
        
        return $stmt->fetchAll();    
    }

Vervolgens heb ik de variabele term in de Controller gebruikt

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$term  = filter_input(INPUT_GET, 'zoekTerm', FILTER_SANITIZE_STRING);


En geloof het of niet het werkt. Ik probeer te achterhalen waar dit door komt? Voor zover ik weet is het woord search geen gereserveerd woord in mySql of ik moet me vergissen. Wellicht kun jij een verklaring verzinnen.

Maar nogmaals bedankt voor je reactie en tip over het uitsplitsen in de WHERE clause
 
Thomas van den Heuvel

Thomas van den Heuvel

24/07/2016 14:10:31
Quote Anchor link
Quote:
Ik probeer te achterhalen waar dit door komt?

Het probleem is een beetje dat je meerdere dingen tegelijkertijd hebt veranderd. Daarom is het moeilijk om precies aan te geven wat precies de oorzaak is. Zo:
- heb je de tabelaliassen O en K weggelaten in je WHERE-conditie
- zijn je LIKE criteria veranderd (nu enkel aan het einde een %)
- filter je je invoer op een andere manier

Echter, geen van deze wijzigingen, noch het veranderen van namen van formulierelementen of GET variabelen zouden volgens mij echt (veel) uit moeten maken. De enige manier om er achter te komen waarom de ene opzet wel werkt en de andere niet is door de query te loggen en te kijken wat MySQL hier uiteindelijk van maakt (oftewel, begin je zoektocht bij het einde: je query levert geen resultaat op waar je resultaat verwacht --> inspecteer de query). Ook wat @SanThe zegt: zorg dat (PHP) fouten oppikt (via error_reporting) en weergeeft (via display_errors).

Quote:
Voor zover ik weet is het woord search geen gereserveerd woord in mySql of ik moet me vergissen.

Ik denk dat dat niet uitmaakt, dit zijn slechts placeholder-namen.

Wat wel van groot belang kan zijn is het volgende: afhankelijk van hoe jij een verbinding maakt met je database via PDO kan dit consequenties hebben over HOE fouten WAAR gemeld worden door PDO.

Allereerst: gebruik je PDO::ATTR_EMULATE_PREPARES? Dit bepaalt of PDO gebruik maakt van gesimuleerde prepares (ingeval deze instelling de waarde true heeft). Dit houdt in dat PDO het querysjabloon nooit vantevoren naar de database stuurt (wat wel gebeurt ingeval deze instelling de waarde false heeft, want de MySQL database heeft zelf ook een "native" prepared statements voorziening). Dus foutmeldingen over de syntax van de query komen dan niet tot uiting tijdens het preparen, maar pas tijdens de uitvoer. Default staat het emuleren van prepared statements aan. Heb je deze instelling niet expliciet geconfigureerd werkt het ook op die wijze.

En dat brengt ons bij het tweede dingetje: hoe handel jij fouten af via PDO? Oftewel wat voor waarde heeft PDO::ATTR_ERRMODE? De default waarde is PDO::ERRMODE_SILENT. Dit houdt in dat PDO normaal geen directe / visuele ruchtbaarheid geeft aan opgetreden fouten. Mocht je deze instelling niet expliciet geconfigureerd hebben is dat het default gedrag: er zal geen haan naar foutmeldingen kraaien.

Realiseer je je goed dat PDO niet op voorhand geschreven is voor een specifieke database en als gevolg hiervan niet op voorhand (optimaal) is geconfigureerd voor interactie met eerdergenoemde database. Naar mijn mening is het gewoon het beste om alle (al dan niet database-specifieke instellingen van de database-specifieke driver) instellingen expliciet in te stellen. Of gewoon MySQLi te gebruiken als je toch alleen van MySQL gebruik maakt :p.

Het venijn van PDO zit hem in de staart: PDO dwingt je om je te verdiepen in de werking van de database-specifieke driver die vervolgens met zorg geconfigureerd en behandeld moet worden. Als je hier geen weet van hebt dan zul je vaker voor dit soort puzzels komen te staan die vaak (?) naar configuratie herleidbaar zijn. En ja, debuggen van queries (de queries die de database concreet uitvoert) kan volgens mij alleen via de log.

EDIT: concreet: stel de instelling general_log in op ON en vul het pad naar de logfile in in general_log_file. Houd er wel rekening mee dat dit bestand vrij snel groeit dus gebruik dit uitsluitend voor (korte) debug sessies (en zet deze functionaliteit na afloop weer uit).
Gewijzigd op 24/07/2016 15:10:11 door Thomas van den Heuvel
 



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.