Codeigniter 4命名的准备语句抛出错误代码500:“变量数必须与预准备语句中的参数数匹配”

h4cxqtbf  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(181)

我使用的是Codeigniter 4,当使用“?”占位符作为预准备语句时,一切都运行得很好。但我更喜欢使用命名绑定,因为条目太多了,但它会抛出错误代码500:
变量的数目必须与预准备语句中的参数数目匹配

$db = \Config\Database::connect();
$pQuery = $db->prepare(static function ($db){
    $sql = 'INSERT INTO tbl_posts (content, author_id, display_image, video, posted_anonymously, foreign_image, foreign_title, foreign_url, foreign_description, date_created) VALUES (:content, :author_id, :display_image, :video, :posted_anonymously, :foreign_image, :foreign_title, :foreign_url, :foreign_description, :date_created)';
        return (new Query($db))->setQuery($sql);
});

$author_id = session()->get('my_id');
$date_created = date("Y-m-d H:i:s");
$result = $pQuery->execute([":content" => $post['content'], ":author_id" => $author_id, ":display_image" => $post['display_image'], ":video" => $post['video'], ":posted_anonymously" => $post['posted_anonymously'], ":foreign_image" => $post['foreign_image'], ":foreign_title" => $post['foreign_title'], ":foreign_url" => $post['foreign_url'], ":foreign_description" => $post['foreign_description'], ":date_created" => $date_created]);
3phpmpom

3phpmpom1#

TL. DRCI 4的预准备语句只支持位置占位符。这是由于execute()方法接受参数的方式所致;它需要一个可变长度的参数列表而不是一个关联数组。

use CodeIgniter\Database\Query;

$pQuery = $db->prepare(static function ($db) {
    $sql = 'INSERT INTO tbl_posts (...) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';

    return (new Query($db))->setQuery($sql);
});

// The order of arguments must match the placeholder order
$result = $pQuery->execute(
    $post['content'],
    $author_id,
    $post['display_image'],
    $post['video'],
    $post['posted_anonymously'],
    $post['foreign_image'],
    $post['foreign_title'],
    $post['foreign_url'],
    $post['foreign_description'],
    $date_created
);

一个可能更糟糕的选择
API支持一个更简单的查询格式,使用命名绑定,依赖于转义值而不是绑定它们。但是,与PDO命名绑定不同,* 查询中的每个名称必须用冒号包围**。

$sql = 'INSERT ... VALUES (:content:, :author_id:, ...)';
$db->query($sql, [
    'content'   => $post['content'],
    'author_id' => $author_id,
    // etc
]);

意见时间

这种方法是次优的,并试图用一些肯定是过早的优化警告来吓跑其潜在用户。
相反,请注意安全专业人员的警告。从OWASP SQL注入预防速查表...

防御选项4:转义所有用户提供的输入

只有在上述方法都不可行的情况下,才应将此技术作为最后的手段。输入验证可能是更好的选择,因为与其他防御方法相比,此方法很脆弱,而且我们不能保证它在所有情况下都能防止所有SQL注入。

相关问题