Filter SQL met $_POST waarden in een array

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Donovan -

Donovan -

08/02/2019 19:50:03
Quote Anchor link
Hoi!

Sinds een tijdje ben ik met een webshop bezig en ik ben aan de product filtering toegekomen. Heb een 5 tal filters vanuit een form die ik dan post naar een array. Wat mijn bedoeling is, is dat de SQL op zichzelf ontstaat door de elementen uit de array. Tot nu toe heb ik:

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?php
    function product_filter()
    {
    
        require_once("dbcontroller.php");
        $db_handle = new DBController();
        
        if ($_SERVER['REQUEST_METHOD'] == 'POST')
        {

            $filter = array();
            $sort_products         = $_POST['Sorteren'];
            $price_min         = $_POST['MinP'];
            $price_max         = $_POST['MaxP'];
            $length_min         = $_POST['MinL'];
            $length_max         = $_POST['MaxL'];
            $height_min         = $_POST['MinH'];
            $height_max         = $_POST['MaxH'];
            $weight_min         = $_POST['MinW'];
            $weight_max         = $_POST['MaxW'];
            
            if(isset($_POST['Kleur']))
            {

                $has_color    = $_POST['Kleur'];
                $filter[]       = "Kleur contains '".$has_color."'";
            }

            
            if (isset($_GET['categorie'])) {
                $filter[] = "Categorie = '".$_GET['categorie']."' ";
            }

            if(!empty($price_min_max)) {
                $filter[] = "prijs_nieuw between'".$price_min."' and '".$price_max."'";
            }

            if(!empty($length_min_max)) {
                $filter[] = "lengte between        '".$length_min."' and '".$length_max."'";
            }

            if(!empty($height_min_max)) {
                $filter[] = "hoogte between        '".$height_min."' and '".$height_max."'";
            }

            if(!empty($weight_min_max)) {
                $filter[] = "gewicht between    '".$weight_min."' and '".$weight_max."'";
            }

            if(!empty($contains_color)) {
                $filter[] = "kleur contains        '".$kleuren."'";
            }

            
            if(!empty($sort_products)) {
              if ($_POST['Sorteren'] == "Naam oplopend ")
              {

                $filter[] = "ORDER BY naam ASC";
              }

              if ($_POST['Sorteren'] == "Naam aflopend ")
              {

                $filter[] = "ORDER BY naam DESC";
              }

              if ($_POST['Sorteren'] == "Prijs oplopend ")
              {

                $filter[] = "ORDER BY prijs_nieuw ASC ";
              }

              if ($_POST['Sorteren'] == "Prijs aflopend ")
              {

                $filter[] = "ORDER BY prijs_nieuw DESC ";
              }
            }

        echo "<pre>".print_r($filter,true)."</pre>";
        echo "<vr/>";

        if (count($filter) > 0) {    
          $product_array = $db_handle->runQuery('SELECT * FROM producten WHERE IN ("'.implode("AND",$filter).'"');
        }

?>


Het probleem is, is dat de array zich niet vult met de filters die aangepast/ingesteld zijn. De array heeft vervolgens 0 items.Wat dien ik aan te passen waardoor de aangepaste filters oom in de array komen en zorgen voor een passend filter?
Dank alvast!


Edit: als ik losse dingen in de array wil zetten om te testen, bijvoorbeeld;
$filter[] = "Test";
$filter[] = "Voor";
$filter[] = "Deze";
$filter[] = "Array";

dan vult de array zich wel!
Gewijzigd op 08/02/2019 20:28:28 door Donovan -
 
PHP hulp

PHP hulp

28/03/2024 15:37:56
 
Rob Doemaarwat

Rob Doemaarwat

08/02/2019 20:30:34
Quote Anchor link
Poehee ...
- SQL injectie!?
- Waarom zit de categorie in de GET en de rest in de POST?
- Waar komt die $price_min_max vandaan?
- Waar komt die $length_min_max vandaan?
- Waar komt die $height_min_max vandaan?
- Waar komt die $weight_min_max vandaan?
- waar komt die $contains_color vandaan?
Die laatste zullen grofweg wel de reden zijn waarom je $filters niet wordt gevuld.

Vervolgens doe je de filters met een implode in een IN (...), maar het was al valide SQL (minus die SQL injectie dan ...). Echo de SQL uit runQuery() eens, dan zul je zien dat je SQL opdracht niet klopt.
 
Donovan -

Donovan -

08/02/2019 20:39:48
Quote Anchor link
$price_min_max en dat soort, zijn de filter opties, allemaal van range sliders.
Ik heb deze nu gewijzigd naar ('SELECT * FROM producten WHERE ("'.implode("AND",$filter).'")');

Daar komt alleen niet zo veel spannends uit als ik die echo omdat die Array helemaal leeg is..
SELECT * FROM producten WHERE (""). Dus tussen die quotes moeten alle opties van de filters komen. Ik heb die kleuren-filter eruit gehaald. Dat zijn als enige checkboxses dus die heb ik eruit ge"/"'t!
Gewijzigd op 08/02/2019 20:45:58 door Donovan -
 
Thomas van den Heuvel

Thomas van den Heuvel

08/02/2019 20:56:12
Quote Anchor link
In het $price_min_max if-statement ontbreekt in ieder geval een spatie na de "between".

En wat moet er in de IN bekeken/vergeleken worden, er staat nu WHERE IN? Die kende ik nog niet.

En wat @Rob zei, onveilige query, en het loont de moeite om deze zut via GET af te handelen, in plaats van POST, het betreft immers zoekfunctionaliteit.

EDIT: waar komt $kleuren vandaan?

Ik denk dat het de moeite loont om de uiteindelijke SQL-query zelf eens onder de loep te nemen want deze heeft lang niet altijd het goede formaat.
Gewijzigd op 08/02/2019 20:58:55 door Thomas van den Heuvel
 
Donovan -

Donovan -

08/02/2019 21:09:33
Quote Anchor link
Thomas van den Heuvel op 08/02/2019 20:56:12:
In het $price_min_max if-statement ontbreekt in ieder geval een spatie na de "between".

En wat moet er in de IN bekeken/vergeleken worden, er staat nu WHERE IN? Die kende ik nog niet.

En wat @Rob zei, onveilige query, en het loont de moeite om deze zut via GET af te handelen, in plaats van POST, het betreft immers zoekfunctionaliteit.

EDIT: waar komt $kleuren vandaan?

Ik denk dat het de moeite loont om de uiteindelijke SQL-query zelf eens onder de loep te nemen want deze heeft lang niet altijd het goede formaat.


Dat is even een 2, alleen wat is het probleem met de POST? Ik heb alleen range sliders, dus anders dan een getal kan het niet worden. Plus die array blijft nog leeg..
 
Rob Doemaarwat

Rob Doemaarwat

08/02/2019 21:25:06
Quote Anchor link
Donovan - op 08/02/2019 20:39:48:
$price_min_max en dat soort, zijn de filter opties, allemaal van range sliders.

Maar waar komen ze vandaan? In het stukje code hierboven zie ik ze niet staan (ook niet als global). Als je dus niet een stuk code hebt "weggelaten" zijn ze dus bij voorbaat "empty" (oftewel !empty(...) levert een false op) en zal je $filters dus nergens worden aangevuld (kortom: met wat ik hierboven zie is het dus vrij logisch dat $filters leeg is/blijft).
Gewijzigd op 08/02/2019 21:25:34 door Rob Doemaarwat
 
Donovan -

Donovan -

08/02/2019 21:27:38
Quote Anchor link
Rob Doemaarwat op 08/02/2019 21:25:06:
Donovan - op 08/02/2019 20:39:48:
$price_min_max en dat soort, zijn de filter opties, allemaal van range sliders.

Maar waar komen ze vandaan? In het stukje code hierboven zie ik ze niet staan (ook niet als global). Als je dus niet een stuk code hebt "weggelaten" zijn ze dus bij voorbaat "empty" (oftewel !empty(...) levert een false op) en zal je $filters dus nergens worden aangevuld (kortom: met wat ik hierboven zie is het dus vrij logisch dat $filters leeg is/blijft).

Ik heb een form waaruit ze komen. Zou het kunnen dat-ie ze niet ziet?




Toevoeging op 08/02/2019 21:28:09:

Donovan - op 08/02/2019 21:27:38:
Rob Doemaarwat op 08/02/2019 21:25:06:
Donovan - op 08/02/2019 20:39:48:
$price_min_max en dat soort, zijn de filter opties, allemaal van range sliders.

Maar waar komen ze vandaan? In het stukje code hierboven zie ik ze niet staan (ook niet als global). Als je dus niet een stuk code hebt "weggelaten" zijn ze dus bij voorbaat "empty" (oftewel !empty(...) levert een false op) en zal je $filters dus nergens worden aangevuld (kortom: met wat ik hierboven zie is het dus vrij logisch dat $filters leeg is/blijft).

Ik heb een form waaruit ze komen. Zou het kunnen dat-ie ze niet ziet?

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<form method="post" action="#">
<table class="opties">
<tr class="OPTIE">
  <td><label for="Sorteren"><b>Sorteren:</b></label></td>
  </tr>
<tr>
  <td colspan="2" >
      <select name="Sorteren" id="Sorteren">
          <option value="Naam oplopend"     <?php echo (isset($_POST['Sorteren']) && $_POST['Sorteren'] == "Naam oplopend")?'selected="selected"':'';?>    >op naam [A-Z]</option>
          <option value="Naam aflopend"     <?php echo (isset($_POST['Sorteren']) && $_POST['Sorteren'] == "Naam aflopend")?'selected="selected"':'';?>    >op naam [Z-A]</option>
          <option value="Prijs oplopend"     <?php echo (isset($_POST['Sorteren']) && $_POST['Sorteren'] == "Prijs oplopend")?'selected="selected"':'';?>    >op prijs [Oplopend]</option>
          <option value="Prijs aflopend"     <?php echo (isset($_POST['Sorteren']) && $_POST['Sorteren'] == "Prijs aflopend")?'selected="selected"':'';?>    >op prijs [Aflopend]</option>
      </select>
    </td>
  </tr>
<tr>
  <td colspan="2">&nbsp;</td>
</tr>
<tr class="OPTIE">
  <td><label for="Prijs"><b>Prijs (&euro;):</b></label></td>
</tr>
<tr>
  <td colspan="2">
<section class="range-slider">
<span class="rangeValues"></span>
  <input value="<?php if(isset($_POST['MinP']) && $_POST['MinP'] > 0) echo $_POST['MinP']; else echo "0"?>" min="0" max="200" step="0.10" type="range" id="MinP" name="MinP">
  <input value="<?php if(isset($_POST['MaxP']) && $_POST['MaxP'] < 200) echo $_POST['MaxP']; else echo "200"?>" min="0" max="200" step="0.10" type="range" id="MaxP" name="MaxP">
</section>
</td>
  </tr>
<tr>
  <td colspan="2">&nbsp;</td>
</tr>
<tr>
  <td colspan="2">&nbsp;</td>
</tr>
<tr  class="OPTIE">
  <td><label for="Lengte"><b>Lengte (cm):</b></label></td>
</tr>
<tr>
  <td colspan="2">  
<section class="range-slider">
<span class="rangeValues"></span>
  <input value="<?php if(isset($_POST['MinL']) && $_POST['MinL'] > 0) echo $_POST['MinL']; else echo "0"?>" min="0" max="200" step="0.10" type="range" id="MinL" name="MinL">
  <input value="<?php if(isset($_POST['MaxL']) && $_POST['MaxL'] < 200) echo $_POST['MaxL']; else echo "200"?>" min="0" max="200" step="0.10" type="range" id="MaxL" name="MaxL">
</section>
  </td>
</tr>
<tr>
  <td colspan="2">&nbsp;</td>
</tr>
<tr>
  <td colspan="2">&nbsp;</td>
</tr>
<tr class="OPTIE">
  <td><label for="Hoogte"><b>Hoogte (cm):</b></label></td>
</tr>
<tr>
  <td colspan="2">
<section class="range-slider">
<span class="rangeValues"></span>
  <input value="<?php if(isset($_POST['MinH']) && $_POST['MinH'] > 0) echo $_POST['MinH']; else echo "0"?>" min="0" max="200" step="0.10" type="range" id="MinH" name="MinH">
  <input value="<?php if(isset($_POST['MaxH']) && $_POST['MaxH'] < 200) echo $_POST['MaxH']; else echo "200"?>" min="0" max="200" step="0.10" type="range" id="MaxH" name="MaxH">
</section>
  </td>
</tr>
<tr>
  <td colspan="2">&nbsp;</td>
</tr>
<tr>
  <td colspan="2">&nbsp;</td>
</tr>
<tr class="OPTIE">
  <td><label for="Gewicht"><b>Gewicht (g):</b></label></td>
</tr>
<tr>
  <td colspan="2">  
<section class="range-slider">
<span class="rangeValues"></span>
  <input value="<?php if(isset($_POST['MinW']) && $_POST['MinW'] > 0) echo $_POST['MinW']; else echo "0"?>" min="0" max="200" step="0.10" type="range" id="MinW" name="MinW">
  <input value="<?php if(isset($_POST['MaxW']) && $_POST['MaxW'] < 200) echo $_POST['MaxW']; else echo "200"?>" min="0" max="200" step="0.10" type="range" id="MaxW" name="MaxW">
</section>
  </td>
</tr>
<tr>
  <td colspan="2">&nbsp;</td>
</tr>
<tr>
  <td colspan="2">&nbsp;</td>
</tr>
<tr class="OPTIE">
  <td><label for="Kleur"><b>Kleuren:</b></label></td>
</tr>
<tr>
  <td>
      <input type="checkbox" name="Kleur1" <?php if(isset($_POST['Kleur1']) == "Rood") {echo "checked='checked'";} ?>value="Rood">Rood</input><br/>
      <input type="checkbox" name="Kleur2" <?php if(isset($_POST['Kleur2']) == "Roze") {echo "checked='checked'";} ?>value="Roze">Roze</input><br/>
    <input type="checkbox" name="Kleur3" <?php if(isset($_POST['Kleur3']) == "Geel") {echo "checked='checked'";} ?>value="Geel">Geel</input><br/>
    <input type="checkbox" name="Kleur4" <?php if(isset($_POST['Kleur4']) == "Zwart"){echo "checked='checked'";} ?>value="Zwart">Zwart</input><br/>
    <input type="checkbox" name="Kleur5" <?php if(isset($_POST['Kleur5']) == "Grijs"){echo "checked='checked'";} ?>value="Grijs">Grijs</input>
  </td>
  <td>
      <input type="checkbox" name="Kleur6" <?php if(isset($_POST['Kleur6']) == "Oranje"){echo "checked='checked'";} ?>value="Oranje">Oranje</input><br/>
      <input type="checkbox" name="Kleur7" <?php if(isset($_POST['Kleur7']) == "Paars") {echo "checked='checked'";} ?>value="Paars">Paars</input><br/>
    <input type="checkbox" name="Kleur8" <?php if(isset($_POST['Kleur8']) == "Groen") {echo "checked='checked'";} ?>value="Groen">Groen</input><br/>
    <input type="checkbox" name="Kleur9" <?php if(isset($_POST['Kleur9']) == "Blauw") {echo "checked='checked'";} ?>value="Blauw">Blauw</input><br/>
    <input type="checkbox" name="Kleur10" <?php if(isset($_POST['Kleur110']) == "Wit")   {echo "checked='checked'";} ?>value="Wit">Wit</input>
 </td>
</tr>
<tr>
  <td colspan="2">&nbsp;</td>
</tr>
<tr class="OPTIE">
  <td colspan="2" align="center"><button type="submit" name="submit" onclick="product_filter()">Toepassen</button></td>
  </tr>
</table>
</form>  
Gewijzigd op 08/02/2019 22:23:33 door Donovan -
 
Thomas van den Heuvel

Thomas van den Heuvel

08/02/2019 22:01:37
Quote Anchor link
Zet even wat [code][/code] tags om het bovenstaande svp.
 
Donovan -

Donovan -

08/02/2019 22:23:50
Quote Anchor link
Thomas van den Heuvel op 08/02/2019 22:01:37:
Zet even wat [code][/code] tags om het bovenstaande svp.


Beter? ^^
 
- Ariën  -
Beheerder

- Ariën -

08/02/2019 22:28:43
Quote Anchor link
Top :-)
 
Rob Doemaarwat

Rob Doemaarwat

08/02/2019 23:22:46
Quote Anchor link
Maar nou zie ik nog niet waar ze vandaan komen. In die lap HTML zie ik niks wat op $price_min_max lijkt. En als ze al in je POST zitten zullen je ze toch ergens aan $price_min_max toe moeten kennen. Dat doe je wel voor $price_min en $price_max, maar niet voor $price_min_max.

Het is hetzelfde alsof je dit doet:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
die(empty($doe_maar_wat) ? 'niets' : 'iets'); //levert altijd "niets", omdat $doe_maar_wat niet bestaat
 
Thomas van den Heuvel

Thomas van den Heuvel

08/02/2019 23:28:53
Quote Anchor link
Donovan - op 08/02/2019 21:09:33:
[wat is het probleem met de POST?

- als je heen en weer navigeert tussen zoekformuler en resultaten krijg je waarschuwingen van je browser of je de formulierinformatie opnieuw wilt zenden, voor de goede orde zou je een POST-request altijd in een aparte actie af moeten handelen en iemand daarna direct moeten doorsturen om deze problematiek te voorkomen
- je kunt zoekopdrachten bookmarken met GET, dit kan niet met POST
- GET is transparant, je kunt alles zien in de URL
 
Donovan -

Donovan -

09/02/2019 09:44:49
Quote Anchor link
Rob Doemaarwat op 08/02/2019 23:22:46:
Maar nou zie ik nog niet waar ze vandaan komen. In die lap HTML zie ik niks wat op $price_min_max lijkt. En als ze al in je POST zitten zullen je ze toch ergens aan $price_min_max toe moeten kennen. Dat doe je wel voor $price_min en $price_max, maar niet voor $price_min_max.

Het is hetzelfde alsof je dit doet:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
die(empty($doe_maar_wat) ? 'niets' : 'iets'); //levert altijd "niets", omdat $doe_maar_wat niet bestaat


Ja ik miste die inderdaad, best stom. Ik gebruik nu overal de _min variant ($price_min bijvoorbeeld, die zijn nooit leeg, range slider is 0 of hoger). Alleen nog leeg :(
Gewijzigd op 09/02/2019 10:00:12 door Donovan -
 
Thomas van den Heuvel

Thomas van den Heuvel

09/02/2019 14:39:35
Quote Anchor link
Zoals met zoveel vraagstukken: deel dit op in stukken.

Begin met je formulier (A) en de verwerking ervan? Wat zit er in $_POST? Dump dit eens naar het scherm.

Op het moment dat dit klopt ga je verder kijken naar je query (B).

De uitvoer van A is namelijk invoer van B.

Nu kijk je, net zoals in een ander vraagstuk, helemaal aan het eind van de rit wat er gebeurt en constateer je dat er dingen misgaan.

Begin gewoon eens bij het begin en ga hier stap voor stap doorheen.
 
Donovan -

Donovan -

17/02/2019 15:13:37
Quote Anchor link
Ok, ik ben er nu voor een deel. Ik vul de array nu via

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$filter[] = " gewicht BETWEEN ".$db_handle->quote($_POST['MinW']) . " AND " . $db_handle->quote($_POST['MaxW']);


Alleen er zit ergens nog een fout waardoor ik geen waarden terug krijg maar een true of false. Notice
: Trying to get property of non-object

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
$product_array = $db_handle->runQuery('SELECT * FROM producten WHERE
'.implode("AND",$filter)) or die ("Error ".$product_array->errorno);
en er komt uit

SELECT * FROM producten WHERE prijs_nieuw BETWEEN 0 AND 200AND lengte BETWEEN 0 AND 200AND hoogte BETWEEN 0 AND 200AND breedte BETWEEN 0 AND 200AND gewicht BETWEEN 0 AND 200AND ORDER BY naam ASC


Ok, grapje ik miste een spatie achter elke AND, plus het sorteren weggehaald. Dan werkt het!
Gewijzigd op 17/02/2019 15:22:35 door Donovan -
 



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.