« 1 2 »
Autor Zpráva
peter_r
Profil
Prosím o radu. Mám vyhľadávací formulár

<form action="results.php" method="post">
<input type="text" name="search" />
<input type="submit" value="Hľadať" />
</form>

Potrebujem urobiť výpis všetkých položiek z jedného stĺpca meno z databázy zamestnanci ale tak že hľadaný text nemusí byť na začiatku mena ale hocikde (napr. budem hľadať meno jan ale aby mi vypísalo nielen všetkých s menom Jan ale tiež ak sa hľadaný text nachádza aj napríklad inde, napr. meno Peter Janoviak), ešte chcem podotknúť že v tabuľke v stĺpci meno je nielen meno ale aj priezvisko, čiže priezvisko nie je v ďalšom stĺpci

prešiel som veľa internetových stránok ale nejak sa mi nedarí do toho dostať. Ďakujem
RastyAmateur
Profil
peter_r:
V dotazu můžeš zkusit použít LIKE operátor.
WHERE meno LIKE '%jan%'    // Finds any values that have "jan" in any position

Jinak proč máš přezdívku u jména? Nebylo by špatné to rozlišit.
Tomášeek
Profil
RastyAmateur:
Priezvisko je příjmení, nikoliv přezdívka.

Na složení dohromady vidím pozitiva (jedna kolonka ve formuláři místo dvou), i negativa (nemožnost seřadit dle příjmení). Záleží, jestli a jak se s těmi daty dal pracuje.
peter_r
Profil
ďakujem, skúsim sa s tým potrápiť, čiže príkaz bude

WHERE meno LIKE '%search%'

???
Kcko
Profil
peter_r:
ano a když si to příště vyzkoušíš, nebudeš se muset ani ptát.
Keeehi
Profil
Tomášeek:
jedna kolonka ve formuláři místo dvou
I když máš jednu kolonku ve formuláři tak jméno a příjmení můžeš mít v databázi zvlášť.
Tomášeek
Profil
Keeehi:
Ne vždy jde jméno strojové oddělit.

Anna Marie Novotná
Anna Nováková Novotná
A zápis, se kterým se v kolonce jméno a příjmení můžeš casto setkat, Novák Jan.
peter_r
Profil
skúsil som toto ale akosi mi to nefunguje:

$zamestnanci = Db::queryAll('
            SELECT *
            FROM zamestnanci WHERE meno LIKE '%search%'
        ');
        
        foreach ($zamestnanci as $u)
        {
            echo( "<a href=\"list.php?mat_id=".$u['zamestnanci_id']."\">".htmlspecialchars($u['meno'])."</a>");
            echo('<br>');
        }
Tomášeek
Profil
peter_r:
Samozřejmě, hledas ve jménech string “search”. Tak blbě se asi nikdo nejmenuje. Zkoušen to dal, práce s proměnnými je v první kapitole každé učebnice.
peter_r
Profil
ako som už písal v inom príspevku, s php a databázou len začínam, v podstate potrebujem pre uľahčenie svojej práce jednu stránku, nežiadam o vypracovanie celej stránky, len jednoducho php neovládam, mám pred sebou knihu o php, chodím po niekoľkých internetových stránkach o php, ale akosi si neviem s tým rady, takže ak sa nájde nieto kto mi s týmto problémom pomôže, budem mu vďačný

ako je uvedené v príspevku vyššie, mám formulár, kde výstup sa volá search

keď som v ďalšom príspevku napísal, že či to bude vyzerať takto

WHERE meno LIKE '%search%'

tak mi Kcko odpísal, že "ano a když si to příště vyzkoušíš, nebudeš se muset ani ptát." tak preto som to ani neriešil

takže skúšal som dať

WHERE meno LIKE '%$search%'

ale to tiež nefunguje, neviem či musím niekde definovať $search alebo mi tam chýbajú úvodzovky alebo zátvorky?

Ďakujem za každú radu.
Kcko
Profil
FROM zamestnanci WHERE meno LIKE '%search%'
Takže třeba FROM zamestnanci WHERE meno LIKE '%peter%'

Sem si musíš dosadit skutečnou hodnotu, kterou hledáš :-) (a pozor na escapování, nevím jakou DB vrstvu používáš)
RastyAmateur
Profil
peter_r:
mám formulár, kde výstup sa volá search
Nevolá, spíš zadává. Ale to je nepodstatné.
Jelikož máš method nastavený na post, danou proměnnou najdeš v poli $_POST s klíčem právě search, tedy $_POST['search']

Dále je potřeba nějak odlišovat uvozovky. Budeš muset nějak namíchat ", ' (případně `?), nebo to správně zaescapovat pomocí zpětného lomítka, protože 'SELECT * FROM zamestnanci WHERE meno LIKE '%$_POST['search']%'' ti samosebou vyhodí chybu.

A nakonec jak píše Kcko, pozor na SQL Injection
peter_r
Profil
ale tá hodnota je dosadená vo formulári (to som odpisoval Kckovi)

aj tak som z toho mimo :(
RastyAmateur
Profil
peter_r:
Do formuláře napíše člověk nějaké to jméno. Odešle formulář a v tom souboru results.php to zadané jméno najdeš v proměnné $_POST["search"]
peter_r
Profil
tak tomu rozumiem, ale keď to nahodím ako píšeš ty

'SELECT * FROM zamestnanci WHERE meno LIKE '%$_POST['search']%'

tak mi vyhodí chybu

Warning: A non-numeric value encountered in C:\xampp\htdocs\zamestnanci\results.php on line 25
Kcko
Profil
a řádek 25 je co? A hod sem celý kód, ne jen ten řádek 25 (ale zvýrazni ho).
Tahle hláška znamená, že provádíš matematicko operaci s nějakou proměnnou, která není číslem.
peter_r
Profil
riadok 25 je ten ktorý som napísal

'SELECT * FROM zamestnanci WHERE meno LIKE '%$_POST['search']%'

ok, za chvíľu sem hodím celý kód

ďakujem
RastyAmateur
Profil
peter_r:
ale keď to nahodím ako píšeš ty ..... tak mi vyhodí chybu
Jako vážně? Přečti si, prosím, znovu [#12]. Sice to nevypadá na matematickou chybu, ale vsadím se, že to jsou ty uvozovky
peter_r
Profil
čítam a neviem ako to mám chápať, neviem či vieš kde je chyba a len ma skúšaš alebo ...

nechcem sa opäť opakovať, ale s php len začínam a nechcem sa stať profesionálnym programátor, tak vás prosím, ak tak mi poradte, veď na to asi je toto fórum, ak nie tak budem hľadať pomoc inde, ďakujem

poprípade ak treba, tak mi pošlite číslo účtu a pošlem vám za radu odmenu ... len sa prosím vás na mne neodbavujte
Trejpa
Profil
peter_r:
Sice PHP a databázím vůbec nerozumím, ale RastyAmateur se ti už poněkolikáté snaží vysvětlit, že uvozovky stejného druhu nemůžeš zanořovat, sudá (párna) uvozovka ukončuje předchozí lichou (nepárnu).

Příklad: ' A ' B ' C ' se nechová jako ( A ( B ) C ), ale jako ( A ) B ( C ). A protože B je mimo, způsobí zápis chybu. Programovací jazyky to řeší druhým typem uvozovek ' A " B " C ', eskapováním ' A \' B \' C ' nebo obojím ' A " B \' C \' D " E '.

Mimochodem, ve tvém příkladu je lichý počet uvozovek, což je také chyba, pokud sudá není jinde v okolním kódu, který jsi tu nenapsal. To je také důvod, proč chtěl Kcko vidět celý kód.
RastyAmateur
Profil
peter_r:
Chceme, aby jsi na chybu přišel sám, protože tím se nejvíce naučíš. Když jsi došel až k databázím, tak mi neříkej, že nějaké proměnné ti dělají problém

$zamestnanci = Db::queryAll('SELECT * FROM zamestnanci WHERE meno LIKE "%' . $_POST["search"] . '%"');

to $_POST["search"] musíš ale nějak ošetřit. Jen záleží (jak psal Kcko), jaký přístup k databázi využíváš. Například v mysqli by to bylo

$zamestnanci = $mysqli->query('SELECT * FROM zamestnanci WHERE meno LIKE "%' . $mysqli->real_escape_string($_POST["search"]) . '%"')->fetchAll();

Ty ovšem evidentně mysqli nepoužíváš, takže ti to nebude fungovat. Ale pointa je stejná, musíš ošetřit ten vstup. Používáš-li například PDO, tak zadej do googlu pdo real escape string, první odkaz hned stackoverflow, který ti radí, abys použil prepared statement
peter_r
Profil
RastyAmateur:

ďakujem, že chcete aby som sa to naučil, ale v mojom veku sa mi už ťažko učí, a navyše som v časovej tiesni, lebo súrne potrebujem doriešiť tento "projekt", navyše musím priznať, že ja som sa väčšinou najviac naučil (neviem či to vôbec mám priznať) kopírovaním, to znamená že som niečo stiahol, nejaké už hotové stránky a ich prezeraním a úpravou som prišiel na veci, čo a ako

takže tu je kód stránky, kde je zoznam zamestnancov s formulárom pre vyhľadanie

       <?php
        
        require_once('Db.php');            
        Db::connect('127.0.0.1', 'firma', 'root', '');
        
        ?>
        
        <h2>Zoznam zamestnancov</h2>
        <a href="index.php">späť na hlavnú stránku</a><br><br>
        
        <form action="results.php" method="post">
        <input type="text" name="search" />
        <input type="submit" value="Hľadať" />
        </form>
        
        <br><br>
        
        <?php
                
        $zamestnanci = Db::queryAll('
            SELECT *
            FROM zamestnanci
            ORDER BY meno
        ');
        
        foreach ($zamestnanci as $u)
        {
            echo( "<a href=\"list.php?zam_id=".$u['zamestnanci_id']."\">".htmlspecialchars($u['meno'])."</a>");
            echo('<br>');
        }
        
        ?>

a sem je stránka results.php

        <?php
        
        require_once('Db.php');            
        Db::connect('127.0.0.1', 'firma', 'root', '');
        
        ?>
        
        <h2>Zoznam zamestnancov</h2>
        <a href="index.php">späť na hlavnú stránku</a><br><br>
        
        <?php
        
        $zamestnanci = Db::queryAll('
            SELECT *
            FROM zamestnanci WHERE meno LIKE '%$_POST['search']%'
        ');
        
        foreach ($zamestnanci as $u)
        {
            echo( "<a href=\"list.php?zam_id=".$u['zamestnanci_id']."\">".htmlspecialchars($u['meno'])."</a>");
            echo('<br>');
        }
                
        ?>
RastyAmateur
Profil
peter_r:
Nejsem natolik zkušený, abych poradil takto z fleku, tak poprosím ještě o soubor Db.php, případně pokud na začátku souboru je něco ve smyslu class Db extends něco {, tak to něco

Jinak "dočasná" oprava obsahující bezpečností chybu by byla upravit řádek 15 na:
FROM zamestnanci WHERE meno LIKE "%' . $_POST['search'] . '%"
peter_r
Profil
RastyAmateur:
Takže tá "dočasná" oprava pomohla, takže už to funguje správne, ďakujem veľmi pekne
Keeehi
Profil
peter_r:
Takže tá "dočasná" oprava pomohla, takže už to funguje správne, ďakujem veľmi pekne
Teď je ale absolutně nutné to opravit. Protože to je bezpečnostní díra kterou ti jakýkoliv útočník vytáhne obsah naprosto celé databáze. Chceš to vidět v akci? Tak si do vyhledávacího políčka zadej
Pavel%" OR 1=1 -- x
a uvidíš že to zobrazí nejen Pavly ale úplně všechny zaměstnance. Takže vhodně zvolenými znaky se dá způsobit něco, co bys vůbec neočekával, že se stane. Když do toho vstupu napíšu něco jiného, můžu si do toho seznamu zaměstnanců připojit informace z tabulky, platů, docházky, bůh ví čeho všeho co v databázi máš.
Doufám, že je z toho jasně vidět, jak závažný problém to je a že je opravdu potřeba to opravit.

Dle Db::queryAll soudím, že jde o to co se používá v seriálu na www.itnetwork.cz/php/databaze. Už jsem to tu párkrát viděl takže to bude nejspíše právě odtamtud. A používá se tam PDO. Vzhledem k tomu, jak v té obalové třídě fungují podobné metody, tak tipuji že správný zápis je
        $zamestnanci = Db::queryAll('
            SELECT *
            FROM zamestnanci WHERE meno LIKE "%?%"
        ', $_POST['search']);


Tomášeek:
Ne vždy jde jméno strojové oddělit.
Ve 100 % případů to nejde nikdy. Ale s kvalitním slovníkem jmen se tomu lze velmi přiblížit. A ty desetinky procent co ve slovníku nebudou, zpracuje člověk, tím se slovník zase zlepší a příště to už strojově půjde.
peter_r
Profil
Ďakujem Keeehi za radu, ale toto čo robím sa netýka zamestnancov a platov, to je len testovací príklad, a navyše nepôjde na net ale budeme to len využívať na firemnom serveri, a budú tam len údaje o našich výrobkoch potrebné pre všetkých pracovníkov, takže nič tajné ale ďakujem aj tak za upozornenie

máš pravdu, inšpiroval som sa stránkou www.itnetwork.cz

a ten zápis som skúšal ale vyhadzoval mi nejakú chybu, ale vzhľadom na to že to už funguje a tiež to čo som napísal vyššie, netreba robiť ďalšie bezpečnostné opatrenia

ešte raz ďakujem
juriad
Profil
peter_r:
Ono nejde jen o útoky hackerů; problém může být i kolega, který omylem zadá apostrof. Poté dotaz selže a stránka se ti nejspíš porouchá.
Escapovat je nutné nikoli jen kvůli útokům, ale pro zajištění základní funkce.

Je to podobné, jako by si někdo ze srandy dal přezdívku <big dick> a celá stránka by kvůli jeho přezdívce byla velkým písmem.
peter_r
Profil
Trejpa:
Sice PHP a databázím vůbec nerozumím, ale RastyAmateur se ti už poněkolikáté snaží vysvětlit, že uvozovky stejného druhu nemůžeš zanořovat, sudá (párna) uvozovka ukončuje předchozí lichou (nepárnu).
>
Příklad: ' A ' B ' C ' se nechová jako ( A ( B ) C ), ale jako ( A ) B ( C ). A protože B je mimo, způsobí zápis chybu. Programovací jazyky to řeší druhým typem uvozovek ' A " B " C ', eskapováním ' A \' B \' C ' nebo obojím ' A " B \' C \' D " E '.

Chcel by som sa ešte vrátiť k úvodzovkám, snažím sa to pochopiť ale akosi mi to nejde. čiže nemôžu byť dve rovnaké za sebou? takto, mám niečo takéto:

echo('<h2>Meno</h2>');

chcem aby mi text Meno nahradilo meno zamestnanca, tak dám

echo('<h2>' . htmlspecialchars($u['meno'])</h2>); tak je zle, tak som skúsil

echo('<h2>' . htmlspecialchars($u["meno"])'</h2>'); ak tiež zle, myslím že musím dať niečo pre /h2 ale skúšam hocijaké úvodzovky a nič

viem že pre vás to bude primitívne, ale chcem sa nejak poučiť


dal som to takto a vyzerá to byť dobre

echo('<h2>' . htmlspecialchars($u['nazov']). '</h2>');

ale zase mi vypisuje inú chybu Undefined variable: u pretože ho mám definované až za tým, ale som spokojný že som na to prišiel
RastyAmateur
Profil
peter_r:
Být tebou, raději ošetřím ten vstup, jak ti všichni radíme, než dělat toto.

echo('<h2>' . htmlspecialchars($u['meno']) . ' </h2>);

Jde o to, že každý druh uvozovek ti značí jistou část zanoření. Můžeš si to představit jako právě ty html tagy. Když si apostrof představíš jako divy, tak nemůžeš napsat <div><div></div></div> a předpokládat, že zvýrazněné divy budou patřit k sobě. Prostě když potřebuješ někam mezi apostrofy vložit další apostrof, použiješ dvojité uvozovky (nebo naopak). Trejpa to napsal docela dobře, podívej se znovu na jeho příklad:

' A ' B ' C '  --> ' A ' B ' C '
' A " B " C ' --> ' A " B " C '

A pak je tu escapování (\"), pomocí kterého můžeš uvnitř uvozovek použít další uvozovky, jen tomu řekneš, že se stále jedná o obsah těch prvních uvozovek, neboli řekneš tomu, že to nejsou právě ty uvozovky ohraničující konec

' A \' B ' --> ' A \' B '

Pak při výpisu a podobně se zpětné lomítko samosebou nezobrazuje

echo('Apostrof: \' :-) '); // output: Apostrof: ' :-)
Trejpa
Profil
peter_r:
Uvozovky značí řetězec. Na stejné úrovni můžeš spojit několik řetězců, v PHP tečkou.
echo('<h2>' . htmlspecialchars($u['meno']) . '</h2>');

Nemůžeš ale do jednoho řetězce vnořit druhý řetězec, aniž bys ho oddělil jiným druhem uvozovek. Stejné vnitřní uvozovky by program interpretoval jako ukončení vnějšího řetězce.

Špatně (záměr: řetězec s podřetězcem):
echo('<h2 class='nadpis'>');

Protože je to interpretováno jako dva nezávislé řetězce:
echo('<h2 class='nadpis'>');
tedy echo(řetězec [neznámý příkaz nadpis] řetězec).

Správně je použít jiné uvozovky:
echo('<h2 class="nadpis">');
« 1 2 »

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:

0