Ik heb een pagina met allemaal gegevens uit een database. Nou heb ik bovenaan die pagina een filter gemaakt met een selectform waar alle unieke waardes van het kolom type uit de database worden weergeven.
Nou is het de bedoeling wanneer iemand een waarde selecteert dat daarna daaronder alle rijen met alleen die waarde worden weergeven. Dat werkt tot nu toe goed:


<?php
 $statement = "`certificaten` WHERE type='".$_POST['filtertype']."' AND expires >= CURDATE() ORDER BY `expires` ASC"; // SQL Query
?>


Alleen nou heb ik ook <option value="*">Alles</option> toegevoegd aan die selectform. En nu was het mijn idee wanneer dit wordt gekozen dat dan WHERE type = '*' alle types laat zien.
Maar dat werkt niet want hij zoekt naar de waarde * en die staat nergens.

Nou is mijn vraag: is het mogelijk in een SQL statement dat hij alle types laat zien als ik * kies?
Ik kan er wel een if {} else {} omheen bouwen alleen naast dat je op type kan filteren kan je op nog veel meer dingen filteren.
En dan wordt het een massa van if and else terwijl als mijn idee zou werken ik zo klaar was.
Of bouw je query dynamisch op en verwijder deze conditie ingeval $_POST['filtertype'] leeg is.

Security: Wel even escapen met de juiste _real_escape_string() functie/methode wanneer deze niet leeg is / je deze invoegt in je query.
Bedankt voor jullie reacties!

@Ward: Ik heb nu * veranderd in %: <option value="%">Alles</option> alleen dat werkt helaas niet. :-(

@Thomas: Hoe zou ik mijn query dynamisch kunnen opbouwen? Klinkt wel goed.
Je kunt toch nagaan welke optie is opgegeven?
Als dat "alles" is, gebruik je de % van Ward of laat het nog makkelijker weg in je query (zoals Thomas aangeeft).
@Ward: Als je '%' gebruikt in een select, moet dat dan niet met like, bijv. WHERE type like '%'?

@Danny: om je query dynamisch te bouwen zou je iets kunnen doen als:

if ( $_POST['filtertype'] == '%') {
    $sTypeFilter = "type like '%' ";  
} else {
    $sTypeFilter = "type = '" . $_POST['filtertype'] . "' ";

$sSql = "SELECT * FROM certificaten WHERE ' . $sTypeFilter . "AND ...";


(uit de losse pols ingetikt, dus misschien niet helemaal foutloos)
GET is bij zoekfuncties handiger dan POST omdat je dan straffeloos heen en weer kunt navigeren van resultaat naar zoekopdracht zonder die vervelende "wil je deze data opnieuw versturen" boodschap. Daarnaast kun je dan een zoekopdracht knippen en plakken etc.

Alle DATA in je SQL statement zou ge-escaped moeten worden met een _real_escape_string() functie en/of je zou gebruik kunnen maken van whitelists.

Mogelijk kun je uit het volgende voorbeeld wat inspiratie halen:
<?php
header('Content-Type: text/html; charset=UTF-8');

function escape($in) {
    return htmlspecialchars($in, ENT_QUOTES, 'UTF-8');
}

// dummy functie, deze zou vervangen moeten worden door een _real_escape_string() functie
function db_escape($in) {
    return $in;
}
?>
<!DOCTYPE html>
<html>
<head>
<title>dynamic query</title>
<style type="text/css">
body        { font-family: sans-serif; font-size: 10pt; }
label       { display: block; float: left; width: 150px; }
label.radio { display: inline; float: none; padding: 0 5px; }
</style>
</head>

<body>
<?php
// je zou dit nog uit kunnen bouwen met dynamische formulier creatie enzo
$categoryOptions = array(
    '1' => 'one',
    '2' => 'two',
    '3' => 'three',
);
$orderOptions = array(
    'ASC'   => 'ascending',
    'DESC'  => 'descending',
);
?>
<form action="<?php echo escape($_SERVER['PHP_SELF']) ?>" method="get">
    <p>
        <label for="search_text">text</label>
        <input type="text" name="text" id="search_text" value="<?php echo escape(isset($_GET['text']) ? $_GET['text'] : '') ?>" /></p>
    <p>
        <label>category</label>
        <select name="category">
            <option value="">-- any --</option><?php
            foreach ($categoryOptions as $k => $v) {
                $selected = (isset($_GET['category']) && $_GET['category'] == $k ? ' selected="selected"' : '');
                ?><option value="<?php echo escape($k) ?>"<?php echo $selected ?>><?php echo escape($v) ?></option><?php
            }
        ?></select>
    </p>
    <p>
        <label>order</label><?php
        if (isset($_GET['order']) && isset($orderOptions[$_GET['order']])) {
            $order = $_GET['order'];
        } else {
            $order = 'DESC';
        }
        foreach ($orderOptions as $k => $v) {
            $id = 'search_order_'.strtolower($k);
            $checked = ($k == $order ? ' checked="checked"' : '');
            ?><input type="radio" name="order" id="<?php echo escape($id) ?>" value="<?php echo escape($k) ?>"<?php echo $checked ?> />
            <label class="radio" for="<?php echo escape($id) ?>"><?php echo escape($v) ?></label><?php
        }
    ?></p>
    <p>
        <label for="search_expired">expired</label>
        <input type="checkbox" name="expired" id="search_expired" value="1"<?php echo (isset($_GET['expired']) ? ' checked="checked"' : '') ?> />
    </p>
    <p>
        <input type="hidden" name="action" value="search" />
        <button type="submit">search</button>
    </p>
</form>
<?php
if (isset($_GET['action']) && $_GET['action'] == 'search') {
    // *** VALIDEER INPUT ***
    $text = false;
    if (isset($_GET['text']) && trim($_GET['text']) != '') {
        $text = trim($_GET['text']);
    }

    $category = false;
    // vergelijk met een whitelist
    if (isset($_GET['category']) && isset($categoryOptions[$_GET['category']])) {
        $category = $_GET['category'];
    }

    $order = 'DESC'; // kies een zinnige default
    // vergelijk met een whitelist
    if (isset($_GET['order']) && isset($orderOptions[$_GET['order']])) {
        $order = $_GET['order'];
    }

    $expired = false;
    if (!empty($_GET['expired'])) {
        $expired = true;
    }

    // *** BOUW QUERY ***
    $arguments = array();
    if ($text !== false) {
        // escape je DATA altijd, ook als dat niet per se nodig is
        // al is het maar om je DATA delen te markeren
        $arguments[] = "text LIKE '%".db_escape($text)."%'";
    }
    if ($category !== false) {
        // als category niet numeriek is zet je er quotes omheen
        $arguments[] = 'category = '.db_escape($category);
    }
    if ($expired) {
        $arguments[] = 'expires < CURDATE()';
    } else {
        $arguments[] = 'expires >= CURDATE()';
    }

    $query = 'SELECT * FROM certificaten';
    if (count($arguments)) {
        $query .= ' WHERE '.implode(' AND ', $arguments);
    }
    $query .= ' ORDER BY expires '.db_escape($order);

    // dump query
    ?><pre><?php echo escape($query) ?></pre><?php
}
?>
</body>
</html>


EDIT: sorteervolgorde in query ging nog mis
EDIT2: en categorieën, dat krijg je als je iets wijzigt en niet goed test :] fixed
Ik heb het idee van @Jan de Laet gekozen en dat werkt voor mij perfect. Bedankt :-)


<?php
//Filter Query
if (isset($_POST['filtersubmit'])) {
	
	// Laat alle Filtertypes zien of enkele
	if ($_POST['filtertype'] == '%') {
		$sTypeFilter = "type like '%' ";
	} else {
		$sTypeFilter = "type='" . $_POST['filtertype'] . "' ";
	}
	
	// Laat alle uitgevers zien of enkele
	if ($_POST['filteruitgever'] == '%') {
		$sUitgeverFilter = "uitgever like '%' ";
	} else {
		$sUitgeverFilter = "uitgever='" . $_POST['filteruitgever'] . "' ";
	}
	
	$statement = "`certificaten` WHERE " . $sTypeFilter . " AND " . $sUitgeverFilter . "  AND expires >= CURDATE() ORDER BY `expires` ASC"; // SQL Query
	
//Standaard Query
} else {
	$statement = "`certificaten` WHERE verlengd='nee' AND actief='ja' AND expires >= CURDATE() ORDER BY `expires` ASC"; // SQL Query
}
?>

Reageren