简体   繁体   中英

How to dynamically accumulate checkbox values in a SQL query

I have a search form where users can choose a few checkboxes, set a date range, use a wildcard search etc. and via button click it gets sent via ajax to a PHP file and executed in a MySQL query.

In the php file I set up a cascade of if-statements to ensure the query works regardless of the user having chosen certain values, fe like this:

// variable from a risk level dropdown menu
if ($_POST['risklevelcount']=="") {
    $risklevel = "MASTER.RISK_LEVEL != ''";
}

else {
    $risklevel = "MASTER.RISK_LEVEL = "' . $risklevelcount . "'";
}

the variables then are implemented in the where clause of the mysql query, which looks like this:

$result = mysql_query("
SELECT *
FROM        MASTER
WHERE 
        (( ". $buttonvalue ." ) AND ( ". $date . " ) AND ( ". $risklevel ." ))
");

To ensure the query gets executed regardless of the user having checked a checkbox, I analoguously implemented them in a if-clause like this:

if(!empty($checkbox1)) 
    $checkbox1 = "MASTER_CHECK like '%dog%'"; 
else $checkbox1 = "MASTER.CHECK = '' OR MASTER.CHECK != ''";

if(!empty($checkbox2)) 
    $checkbox2 = "MASTER_CHECK like '%cat%'"; 
else $checkbox2 = "MASTER.CHECK = '' OR MASTER.CHECK != ''";

if(!empty($checkbox3)) 
    $checkbox3 = "MASTER_CHECK like '%bird%'"; 
else $checkbox3 = "MASTER.CHECK = '' OR MASTER.CHECK != ''";

If I add these to the above MySQL query where clause I obviously won't get the results I want:

$result = mysql_query("SELECT *
FROM        MASTER
WHERE 
        (
            ( ". $buttonvalue ." ) AND ( ". $date . " ) AND (". risklevel .") AND
                (
                    (". $checkbox1.") OR (". $checkbox2.") OR (". $checkbox3.")
                )
        )
");

I won't get for example results for 'dog' AND 'cat' but not 'bird' (= checkbox 1 and 2 checked but not 3).

I know this is a really stupid approach from the start, regardless of the checkboxes. I sadly don't know how to do any better yet. If someone could point me in the right direction, I would be very glad. I think there is a much more smart way to do it, fe with arrays? I just really lack a real basis knowledge!

I suppose you have a form like this one :

<form id="myFormId" method="POST" action="index.php">
    <div>
        <label for="level">Level :</label>
        <select name="risklevelcount">
            <option value="">-- all level --</option>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
    </div>
    <div>
        <label>Any Pet ?</label>
        <input type="checkbox" name="pet[]" value="dog">dog
        <input type="checkbox" name="pet[]" value="cat">cat
        <input type="checkbox" name="pet[]" value="bird">bird
    </div>
    <input type="submit" value="submit">
</form>

Here is what I recommend for PHP part :

$strWhere = '1=1';

if(true === isset($_POST['risklevelcount']) && true === is_numeric($_POST['risklevelcount']))
{
    $strWhere = ' AND MATER.RISK_LEVEL = '.mysql_escape_string($_POST['risklevelcount']);
}

if(true === isset($_POST['pet']) && 0 < sizeof($_POST['pet']))
{
    $strWhere .= 'AND (';
    foreach($_POST['pet'] as $pet)
    {
        $strWhere .= ' MASTER_CHECK like "%'.mysql_escape_string($pet).'%" OR ';
    }
    //remove last OR
    $strWhere = substring($strWhere, 0, -3);
    $strWhere .= ')';
}

$result = mysql_query("SELECT * FROM MASTER WHERE ".$strWhere);

I agree with mate, use mysqli or PDO is better, at least escape strings. Moreover, stop saying in your queries MASTER.RISK_LEVEL != '' or worst MASTER.CHECK = '' OR MASTER.CHECK != '' .

In the first case, I supposed risk_level is always defined. So no need to say risk_level != '' . And in the second case, Its useless to say I want string null or not null. Just dont ask and you 'll have all results.

EDIT :

If you check the form at the beginning of my answer, I've add an ID which is myFormId . So with jQuery, if you want to serialize your form data, just do :

javascript:

var formData = $('#myFormId').serialize();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM