Fórum Root.cz
Hlavní témata => Server => Téma založeno: Oriesok789 08. 05. 2019, 10:47:53
-
Dobry den.
Potrebujem vytiahnut mena uzivatelov + priezvyska.
Kod vyzera takto
$sql = "SELECT * FROM users WHERE firstname OR lastname LIKE '%$querystr%'";
Problem je ze sa to sprava tak akoby to preskocilo prvu premennu po WHERE proste ak zadam prve meno napriklad Janko nenajde nic ak dam Kocur najde mi pekne Janko Kocur. Skusil som to prehodit teda lastname je prve a firstname druhe. Napisem Janko najde Janko Kocur. Napisem len Kocur nenajde nic. Preco a ako to opravit?
-
SELECT column1, column2, ...
FROM table_name
WHERE condition1 OR condition2 OR condition3 ...;
-
Pozor na SQL injection! https://cs.wikipedia.org/wiki/SQL_injection
-
Dobry den.
Potrebujem vytiahnut mena uzivatelov + priezvyska.
Kod vyzera takto
$sql = "SELECT * FROM users WHERE firstname OR lastname LIKE '%$querystr%'";
Problem je ze sa to sprava tak akoby to preskocilo prvu premennu po WHERE proste ak zadam prve meno napriklad Janko nenajde nic ak dam Kocur najde mi pekne Janko Kocur. Skusil som to prehodit teda lastname je prve a firstname druhe. Napisem Janko najde Janko Kocur. Napisem len Kocur nenajde nic. Preco a ako to opravit?
OR se řadí mezi dva logické výrazy – když se přidají závorky, ten váš dotaz vypadá takhle:
SELECT * FROM users WHERE (firstname) OR (lastname LIKE '%$querystr%')
MySQL si s tím nějak poradí, firstname převede na logickou hodnotu (pravidla by se dala najít v dokumentaci).
Vy asi chcete toto:
SELECT * FROM users WHERE firstname LIKE '%$querystr%' OR lastname LIKE '%$querystr%'
A mimochodem, takhle vkládat uživatelský vstup rovnou do SQL příkazu, to je ukázková SQL injection. Použijte bindování proměnných (https://www.php.net/manual/en/mysqli-stmt.bind-param.php).
-
Filip Jirsak
Dakujem spravna odpoved. Inak ten select je az za osetrenim SQL Injection.
-
Dakujem spravna odpoved. Inak ten select je az za osetrenim SQL Injection.
Doporučuju rovnou se to naučit dělat správně pomocí bindování parametrů. „Ošetření SQL injection“ je jenom hack, který nemusí vždy fungovat správně, snadno se na něj zapomene a jenom zbytečně komplikuje kód. Ostatně je to vidět i na tomhle dotazu – vypadá to, že tam SQL injection je, vy ostatní ubezpečujete, že někde před tím kódem snad je nějaké ošetření. Což je přesně to, co udělá další programátor, až ten kód uvidí (nebo vy, až se k němu vrátíte po nějaké době) – budete doufat, že někde před tím je „ošetření“. A pak vám jednoho dne útočník ukáže, že tam nebylo.
-
Dakujem spravna odpoved. Inak ten select je az za osetrenim SQL Injection.
Doporučuju rovnou se to naučit dělat správně pomocí bindování parametrů. „Ošetření SQL injection“ je jenom hack, který nemusí vždy fungovat správně, snadno se na něj zapomene a jenom zbytečně komplikuje kód. Ostatně je to vidět i na tomhle dotazu – vypadá to, že tam SQL injection je, vy ostatní ubezpečujete, že někde před tím kódem snad je nějaké ošetření. Což je přesně to, co udělá další programátor, až ten kód uvidí (nebo vy, až se k němu vrátíte po nějaké době) – budete doufat, že někde před tím je „ošetření“. A pak vám jednoho dne útočník ukáže, že tam nebylo.
S tím vším se dá jen souhlasit, má to ale jeden praktický háček: v tomto konkrétním případě se nepoužívá hodnota přímo, ale odvozený řetězec (jsou tam přidaná procenta na začátek a konec).
Takže jedině něco jako:
SELECT * FROM users WHERE firstname LIKE '%'||?||'%' OR lastname LIKE '%'||?||'%'
V každém případě: tento dotaz vždy a v každé databázi dělá FULL TABLE SCAN! Takže pokud tam někdy bude netriviální množství uživatelů, tak se databáze utaví. Na druhou stranu, pravděpodobnost je asi malá :-)
-
S tím vším se dá jen souhlasit, má to ale jeden praktický háček: v tomto konkrétním případě se nepoužívá hodnota přímo, ale odvozený řetězec (jsou tam přidaná procenta na začátek a konec).
Takže jedině něco jako:
SELECT * FROM users WHERE firstname LIKE '%'||?||'%' OR lastname LIKE '%'||?||'%'
Děkuji za názornou ukázku toho, proč by se měli lidé rovnou učit používat bindování parametrů. To, co jste napsal, je celé špatně. Ten odvozený řetězec v PHP triviálně vytvoříte kódem "%" . $querystr . "%". Mně ten kód v PHP připadá asi tak stokrát čitelnější, než libovolné skládání v SQL.
V každém případě: tento dotaz vždy a v každé databázi dělá FULL TABLE SCAN! Takže pokud tam někdy bude netriviální množství uživatelů, tak se databáze utaví. Na druhou stranu, pravděpodobnost je asi malá :-)
V každé databázi ne, jenom v těch, které neumí LIKE přeložit na použití fulltextového indexu. Relační databáze to sice většinou nedělají a raději vás nechají použít speciální operátory pro fulltext, ale nezapomeňte, že i spousta NoSQL databází umožňuje používat pro dotazování jazyk SQL.
-
Dakujem spravna odpoved. Inak ten select je az za osetrenim SQL Injection.
Doporučuju rovnou se to naučit dělat správně pomocí bindování parametrů. „Ošetření SQL injection“ je jenom hack, který nemusí vždy fungovat správně, snadno se na něj zapomene a jenom zbytečně komplikuje kód. Ostatně je to vidět i na tomhle dotazu – vypadá to, že tam SQL injection je, vy ostatní ubezpečujete, že někde před tím kódem snad je nějaké ošetření. Což je přesně to, co udělá další programátor, až ten kód uvidí (nebo vy, až se k němu vrátíte po nějaké době) – budete doufat, že někde před tím je „ošetření“. A pak vám jednoho dne útočník ukáže, že tam nebylo.
S tím vším se dá jen souhlasit, má to ale jeden praktický háček: v tomto konkrétním případě se nepoužívá hodnota přímo, ale odvozený řetězec (jsou tam přidaná procenta na začátek a konec).
Takže jedině něco jako:
SELECT * FROM users WHERE firstname LIKE '%'||?||'%' OR lastname LIKE '%'||?||'%'
SQL jsem naposledy použil asi před 15 lety takže už si to přesně nepamatuju, nicméně opravdu nelze ten parametr pro LIKE sestavit včetně wildchars (%) před tím než ho binduju?!
-
opat skvela vlastnost tohto fora vlozit prispevok do inej temy, nez tej na ktoru reagujem, a vymazat sa prispevok neda
-
S tím vším se dá jen souhlasit, má to ale jeden praktický háček: v tomto konkrétním případě se nepoužívá hodnota přímo, ale odvozený řetězec (jsou tam přidaná procenta na začátek a konec).
Takže jedině něco jako:
SELECT * FROM users WHERE firstname LIKE '%'||?||'%' OR lastname LIKE '%'||?||'%'
Děkuji za názornou ukázku toho, proč by se měli lidé rovnou učit používat bindování parametrů. To, co jste napsal, je celé špatně. Ten odvozený řetězec v PHP triviálně vytvoříte kódem "%" . $querystr . "%". Mně ten kód v PHP připadá asi tak stokrát čitelnější, než libovolné skládání v SQL.
V každém případě: tento dotaz vždy a v každé databázi dělá FULL TABLE SCAN! Takže pokud tam někdy bude netriviální množství uživatelů, tak se databáze utaví. Na druhou stranu, pravděpodobnost je asi malá :-)
V každé databázi ne, jenom v těch, které neumí LIKE přeložit na použití fulltextového indexu. Relační databáze to sice většinou nedělají a raději vás nechají použít speciální operátory pro fulltext, ale nezapomeňte, že i spousta NoSQL databází umožňuje používat pro dotazování jazyk SQL.
$lastnameParam = '%' . $lastname . '%';
$sth = $dbh->prepare("SELECT * FROM users WHERE firstname OR lastname LIKE :lastname");
$sth->bindParam(':lastname', $lastnameParam, PDO::PARAM_STR);
$sth->execute();
-
$lastnameParam = '%' . $lastname . '%';
$sth = $dbh->prepare("SELECT * FROM users WHERE firstname OR lastname LIKE :lastname");
$sth->bindParam(':lastname', $lastnameParam, PDO::PARAM_STR);
$sth->execute();
Až na to, že je tam zase ta chyba s OR jako v původním příspěvku…
-
$sql = "SELECT * FROM users WHERE firstname LIKE '%$querystr%' OR lastname LIKE '%$querystr%'";
zaklady jak prase
ve vsech pripadech predtim rikate "najdi mi cokoliv, kde je sloupec fistname vyplnen (neni falsy) NEBO kde lastname LIKE xxx"
ps: necetl jsem zbyle prispevky