Diskuze: Pole v parametru funkce
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Tvůrce
Zobrazeno 9 zpráv z 9.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Nevím jestli jsem to pochopil správně, ale zkus
implode(" ", $result)
převede pole na String, kde bude mezi slovy mezera (první parametr)
Celý kód by tedy měl vypadat takto:
$pole = array("param1", "param2", "param3");
$result = select($pole);
function select($where)
{
$string = implode(" ", $where);
... WHERE name IN (:where) ...
... bindParam(':where', $where) ...
}
Ahoj, já asi chápu, co potřebuješ, přičemž řešení, co navrhuje Pavel Junek je sice správné, ale já si dovolím sem zatáhnout ještě bezpečnost, hlavně co se týče SQL injection - http://www.itnetwork.cz/…on-a-obrana/.
Já bych to viděl asi nějak takhle, s tím, že v $connection budeš mít uložené PDO spojení:
function select($where)
{
// Vytvoříš SQL statement.
$statement = $connection->prepare('... WHERE name IN (:where) ...');
/* Dosadíš parametry s použitím Pavlova řešení, akorát tam patří ',', a zároveň to spustíš.
Alternativně by jsi mohl použít 'bindParam()' a pak to teprve spustit.
Tohle řešení by mělo být bezpečné právě vůči SQL injection - viz. odkaz. */
$statement->execute([':where' => implode(",", $where)]);
// Pak už jsi můžeš s výsledkem dělat co chceš, např. vrátit všechny výsledky jako pole.
return $statement->fetchAll();
}
No a na závěr si k tomu dovolím ještě jednu poznámku. Správně by jsi to totiž měl ještě celé obalit do try-catch bloku a očekávat PDOException při chybě nebo alternativně ty funkce vracejí FALSE při neúspěchu. To už ale záleží na tom, jak máš nastavené PHP. No a s tímto už Tě jenom odkáži do dokumentace PDO - http://php.net/…book.pdo.php.
Prostě to nejde, vyzkoušel sem snad všechno. Ale nefachá to
$zadani_uzivatele = "item1, item2, item3";
$pole = explode(", ", $zadani_uzivatele);
select($pole);
funkce select
function select($where)
{
$stmt = $conn->prepare(" .... WHERE item IN (:items) .....");
$stmt->bindParam(':items', implode(',', $where));
$stmt->execute();
return $stmt->fetchAll();
}
Nevím co tam mám špatně. Když si nechám vypsat jenom to pole v tý funkci tak to funguje. Ale dál to nešlape.
Tak jsem se v tom ještě vrtal a postup je správný, jenomže bindování parametrů zakazuje použití určitý znaků, právě kvůli obraně proti SQL injection. No a jedním z takových znaků je i ","... To ve zkratce znamená, že nemůžeš nabindovat do jednoho identifikátoru hodnotu, ve které jsou jednotlivé sub-hodnoty odděleny čárkami.
Takže musíš použít takovou menší kličku a pro to bindování si v tom statementu vygenerovat odpovídající počet parametrů už rovnou oddělených čárkami, přičemž pak se to může celé nabindovat přímo jako to pole.
function select(array $where)
{
$query = implode(',', array_fill(0, count($where), '?'));
$stmt = $conn->prepare("... WHERE item IN ({$query}) ...");
$stmt->execute($where);
return $stmt->fetchAll();
}
Teď už by to opravdu mělo vrátit správný výsledek, mám to i odzkoušené.
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters' in D:\Programy\XAMPP\htdocs\Searching_Test\db.php:50 Stack trace: #0 D:\Programy\XAMPP\htdocs\Searching_Test\db.php(50): PDO->prepare('\r\n ...') #1 D:\Programy\XAMPP\htdocs\Searching_Test\index.php(10): DB::select(Array) #2 {main} thrown in D:\Programy\XAMPP\htdocs\Searching_Test\db.php on line 50
Udělal jsem to podle tvýho návodu, ale někde je tam chyba. :/
Ach jo... To je tím, že sem prostě neuvádíš celý ten kód. Ty totiž nemůžeš mixovat např. ":item" a pouhý "?" v jednom dotazu. Takže když já používám pro ty položky v poli "?", nemůžeš tam pro další parametry použít nic jiného než "?".
S těmi otazníky je to sice jednoduší, ale pro jistotu sem uvedu i tu druhou variantu:
function select(array $where)
{
$keys = array_map(function ($value) {
return ":item{$value}";
}, range(1, count($where)));
$query = implode(',', $keys);
$stmt = $conn->prepare("... WHERE item IN ({$query}) ...");
$stmt->execute(array_combine($keys, $where));
return $stmt->fetchAll();
}
A ještě upozorním, že jelikož se ty parametry jmenují ":item1", ":item2" atd., nesmíš tam nikde používat stejný název pro další vlastní parametry.
Zobrazeno 9 zpráv z 9.