Autor Zpráva
kopi
Profil
Zdravím,
potřeboval bych poradit, jak nejlépe udělat filtr záznamů v php. Máme 5 formulářových prvků ke specifikaci filtru - 2 selecty a 3 radiobuttony. Po odeslání filtru postupuju jako při klasickém zpracování formuláře.

if(isset($_POST[filtr]))  {

$funkce=trim($_POST['funkce']); // select
$pobocka=trim($_POST['pobocka']); //select
$aktivni=trim($_POST['aktivni']); //radio
$archiv=trim($_POST['archiv']); //radio
$vse=trim($_POST['vse']); //radio

} 

Teď bych sestavil dotaz na db
SELECT * FROM uzivatele WHERE funkce = $funkce AND pobocka=$pobocka AND stav =  aktivni nebo archiv nebo vse

podotýkám, že stav musí být v radiobuttonech a ne v selectu. Jak mám udělat, aby když někdo nevyplní filtr například "funkce", aby v dotazu byl výběr funkce ignorován, tedy že na funkci nezáleží?

Děkuji moc za rady.
Keeehi
Profil
$filter = [];

if (isset($_POST['funkce']) && $_POST['funkce'] !== 'defaultni hodnota') {
    $filter[] = "funkce = '".mysqli_real_escape_string($link, $_POST['funkce'])."'";
}
if (isset($_POST['pobocka']) && $_POST['pobocka'] !== 'defaultni hodnota') {
    $filter[] = "pobocka = '".mysqli_real_escape_string($link, $_POST['pobocka'])."'";
}
if (isset($_POST['stav']) && $_POST['stav'] !== 'vse') {
    $filter[] = "stav = '".mysqli_real_escape_string($link, $_POST['stav'])."'";
}

$sql = "SELECT * FROM uzivatele".(empty($filter) ? '' : ' WHERE '.implode(' AND ', $filter));
kopi
Profil
chápu tu myšlenku, ale nějak mi to nefunguje :) po odeslání formuláře se nic nestane, žádný filtr neproběhne. Problém vidím v tom, že filtr "stav" není jako jedno pole, ale jsou to vlastně 3 radiobuttony a jen jeden z nich bude mít při odesílání hodnotu. Každopádně děkuju za logický návod.
Keeehi
Profil
kopi:
Problém vidím v tom, že filtr "stav" není jako jedno pole, ale jsou to vlastně 3 radiobuttony a jen jeden z nich bude mít při odesílání hodnotu.
Přesně tak jsem to navrhoval.
kopi
Profil
tak teď už to nechápu :) já tam vidím jen stav "vše". Co je prosím Vás ta proměnná $link?
Keeehi
Profil
kopi:
já tam vidím jen stav "vše"
Předpokládám, že stav v DB je buď aktivní nebo archiv. Tudíž pokud bude vybráno aktivní, do podmínky se přidá stav='aktivní', pokud to bude archiv, přidá se stav='archiv' a pokud to bude vše tak místo toho aby se tam přidalo stav='aktivní' or stav='archiv' se tam nepřidá nic, protože by to bylo zbytečné.
Pokud to má fungovat jinak, hodil by se HTML kód formuláře a lepší popis.

Co je prosím Vás ta proměnná $link?
V té je spojení na databázi. V rodině funkcí mysql_* to bylo nepovinné. Jelikož jsou tyto funkce dnes považovány za zastaralé, použil jsem jejich nástupce, mysqli_* a tam už je předávání spojení na databázi povinné.

Tak nějak předpokládám že databáze bude MySQL. Pokud ne, escapování bude třeba změnit. Taky by se hodilo znát datové typy sloupců. Jen tak se dá napsat správné escapování.
kopi
Profil
Ano, se sloupcem stav je to přesně tak, jak říkáte. Taky používám Mysqli, tak se s tím jdu ještě poprat a nějak to musím dát dohromady.
Alphard
Profil
Smazal jsem duplicitní vlákno k tomuto, nebudeme vše řešit od začátku. Popište, v čem je aktuálně problém.
kopi
Profil
Omlouvám se. Problém je v tom, že mi tento kod nic nefiltruje a moc tomu ani nerozumím. Nerozumím téhle části: uzivatele".(empty($filter) ? '' : '. Když hodnota pobocka a práva jsou typu INT, tak funkce real_escape_string ".mysqli_real_escape_string($link, $_POST['funkce'])." tam nebude?

if (isset($_POST['stav']) && $_POST['stav'] !== 'vse') {
    $filter[] = "stav = '".mysqli_real_escape_string($link, $_POST['stav'])."'";

Tohle bych pochopil, kdyby se zpracovával selectbox s name="stav". Ale já mám 3 radiobuttony (aktivni, archiv, vse).

Děkuju za pomoc, jsem v tomhle opravdu ztracený
Alphard
Profil
kopi:
Nerozumím téhle části...
Základní myšlenka je taková, že se jednotlivé podmínky ukládají do pole, to proto, aby se mohla kterákoliv z nich vynechat. Pro zpracování všech položek filtru se zkontroluje, jestli se má vůbec nějaká podmínka aplikovat a pokud ano, vloží se do SQL dotazu.
Ta podmínka je tam proto, aby se nevytvořil syntakticky chybný dotaz s prázdným where, např. "SELECT * FROM uzivatele WHERE ", pokud se nemá aplikovat žádná podmínka.

Tohle bych pochopil, kdyby se zpracovával selectbox s name="stav". Ale já mám 3 radiobuttony (aktivni, archiv, vse).
Pokud je vybráno 'vše', není třeba nic filtrovat a tělo podmínky se nevykoná. Pokud je vybráno něco jiného, tak se do dotazu vloží patřičný výraz, ve vašem případě buď stav = 'aktivni' nebo stav = 'archiv'.
kopi
Profil
Děkuju za ujasnění. Jen ještě poprosím o doplnění.
"stav = '".mysqli_real_escape_string($link, $_POST['stav'])."'"

žádné pole "stav" ve formuláři neodesílám - viz:

$funkce=trim($_POST['funkce']); // select
$pobocka=trim($_POST['pobocka']); //select
$aktivni=$_POST['aktivni']; //radio
$archiv=$_POST['archiv']; //radio
$vse=$_POST['vse']; //radio

Proto nevím, co mám do té podmínky dát. Nebo to mám udělat pro každý radiobutton jednu podmínku, kde místo $_POST[stav] bude $_POST[aktivni], $_POST[archiv], $_POST[vse]?
Keeehi
Profil
kopi:
Ukaž nám html kód toho formuláře. Hlavní je ta část s radiobuttony. Pokud máš na stránce opravdu jen tři a má být vybraný vždy právě jeden z nich, nemohou se jmenovat jinak. Pokud ano, tak se ti to nemůže chovat správně.
kopi
Profil
to máte pravdu, radiobuttony jsem upravil, všechny mají name stav. Problém mám v tom, že když si vyberu pobočku a dám filtrovat a nechám si vypsat obsah proměnné $filtr, tak mi to vypíše jen Array


// html formulář
<input type="radio" name="stav" value="Aktivní"> Aktivní
<input type="radio" name="stav" value="Archiv"> Archiv
<input type="radio" name="stav" value="vše"> Vše


//zpracování filtru
    if(isset($_POST['filtr']))    {      // pokud byl odeslan formular
                                    
    $pobocka=$_POST['pobocka'];
     $stav=trim($_POST['stav']);
                                    
    $filter = [];

    if (isset($_POST['pobocka']) && $_POST['pobocka'] !== '') {
    $filter[] = "id = $_POST['pobocka'])";
    }
    if (isset($_POST['stav']) && $_POST['stav'] !== 'vse') {
    $filter[] = "stav = '".mysqli_real_escape_string($conn, $_POST['stav'])."'";
        }
    echo "$filter";  
                                    
       }
                  

pracuju tady zatím jen s pobočkou a stavem, práva zde nejsou. Jako hodnota pobočky se formuláře odešla id pobočky
Keeehi
Profil
Pole se ná vypsat pomocí echo. Doporučil bych var_dump($proměnná);

if(isset($_POST['filtr'])) {
    $filter = [];
 
    if (isset($_POST['pobocka']) && $_POST['pobocka'] !== '') {
        $filter[] = "id = ".(int)$_POST['pobocka'];
    }
    
    if (isset($_POST['stav']) && $_POST['stav'] !== 'vse') {
        $filter[] = "stav = '".mysqli_real_escape_string($conn, $_POST['stav'])."'";
    }
    
    var_dump($filter);
}
kopi
Profil
v tomhle případě se mi do proměnné $filtr vypíše - array(1) { [0]=> string(7) "id = 1 " }

ale výpis záznamů mi to vypisuje, že nebyly nalezeny žádná data, tak ještě někde dělám něco špatně :)
Keeehi
Profil
kopi:
Doporučil bych si vypsat SQL dotaz. Můžeš přijít na problém. Pokud ne, tak si v tom v čem spravuješ databázi spusť tento okopírovaný dotaz. Vrátilo to výsledky? Ne => chyba je v dotazu, nebo jen neexistuje žádný řádek vyhovující omezující podmínce. Ano => Buď je problém v komunikaci s databází, nebo jen spíš špatně vypisuješ výsledky.

Jinak podle výpisu jsem poznal, že jsi nepoužil mojí úpravu z [#14]. Což je bezpečnostní díra.

Jinak kdybych si měl vsadit, tak problém je v tom, že chceš filtrovat podle pobočky, ale ve skutečnosti filtruješ podle IDčka.
$filter[] = "pobocka = ".(int)$_POST['pobocka'];
To by odpovídalo dotazu z [#1].
kopi
Profil
Už to funguje!!! Měl jsem chybu ve výpisu záznamů. Pánové, moc Vám oběma děkuji. tohle bych sám nikdy nevykoumal!


pro výpis jsem použil var_dump, chybu jsem měl v tom, že při výpisu jsem po tom neustálém přepisování a zkoušení zapomněl dát do SELECT připojení k db. takže hloupost.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: