Za prvé a především:
Stalo se důležitější než kdy jindy, abyste se řídili touto radou, ext/MySQL je nyní zastaralý a jeho použití bude generovat E_DEPRECATED
chyby počínaje PHP 5.5, bude jednoho dne zcela odstraněna ze základního jazyka. Následující platí pro všechny ovladače pro všechny databáze.
Pro zbytek tohoto vysvětlení budu předpokládat, že z nějakého důvodu nemůžete používat MySQLi nebo PDO (všimněte si, že pouze Uspokojivým důvodem je, že nejsou k dispozici, „nevím, jak je používat“ není omluva) a že jste nuceni používat ext/MySQL. Pokud jste schopni použít některý z novějších ovladačů, můžete použít připravené příkazy a nic z toho neplatí. Takže s ohledem na to...
Dále se podívejme na to, co je špatného na předchozí odpovědi. To se soustředí na únik od uživatelského vstupu. Používá mysql_real_escape_string()
je způsob, který opravdu nedává žádný smysl. To by mělo být použito pro escapování jediného řetězcového literálu a vůbec nic jiného. Nelze jej použít k efektivnímu escapování čísel a nelze jej použít k escapovaným částem SQL, které nejsou pouze hodnotami.
Následující dva úryvky kódu ukazují správný způsob, jak toho dosáhnout, v závislosti na tom, o jaká data se jedná, a především na jejich typu.
Zde je to, co bychom udělali, kdyby hodnoty byly řetězce (obvykle CHAR
nebo VARCHAR
pole):
// First create an array of individually escaped values with quotes added
$deds = array();
foreach ($_POST['deductions'] as $ded) {
$deds[] = "'".mysql_real_escape_string($ded)."'";
}
// Now join them together in an SQL syntax
$deds_joined = join('), (', $deds);
// Now they can safely be used in the query
$query = "INSERT INTO mytable (deduction) VALUES ($deds_joined)";
Ale často v tomto scénáři by hodnoty byly jednoduše čísla a v tomto případě vše, co musíme udělat, je zajistit, aby je PHP reprezentovalo správným datovým typem, protože budou automaticky bezpečné, když budou převedeny zpět na řetězce, aby byly použitý v dotazu:
// First convert the array values to integers
$deds = array();
foreach ($_POST['deductions'] as $ded) {
$deds[] = (int) $ded;
}
// Now join them together in an SQL syntax
$deds_joined = join('), (', $deds);
// Now they can safely be used in the query
$query = "INSERT INTO mytable (deduction) VALUES ($deds_joined)";
Tento kód samozřejmě předpokládá, že data jsou celočíselného typu, floats lze snadno zpracovat jednoduchou změnou (int)
přenést do (float)
.
Za zmínku také stojí, že řetězcový přístup lze bezpečně a úspěšně použít i pro číselné hodnoty, protože MySQL také převede hodnoty na správný typ. Ale obecně je lepší a efektivnější předávat data se správnou reprezentací typu v rámci dotazu.