为了防止SQL注入,为查询准备动态MySQL JSON Select 器的最佳/适当方式是什么?例如,假设我想执行以下查询:

SELECT `key` ->> "$.key.path" AS `setting_value`
FROM `settings`
LIMIT 1

但我想使关键路径成为动态路径,例如:

$sql = <<<SQL
    SELECT `key` ->> "{$path}" AS `setting_value`
    FROM `settings`
    LIMIT 1
SQL;

有了条件值,我可以使用PDO为准备好的语句构建SQL,例如:

$sql = <<<SQL
    SELECT *
    FROM `settings`
    WHERE `other_field` = :field_val
    LIMIT 1
SQL;

$statement = $this->handle()->prepare($sql);
$statement->execute([':field_val' => 'some val']);
$records = $statement->fetchAll(PDO::FETCH_OBJ);

将类似以下内容添加到我的数据库适配器(甚至添加到我的助手函数)似乎相当不雅致,并且容易出现错误/问题:

    public function cleanJsonSelector(string $selector) : string {
        return preg_replace('/[^-\$a-zA-Z0-9_\[\].*\s]/', '', $selector);
    }

idea /帮助?

推荐答案

->->>运算符仅支持string literals.它们不包含表达式、变量或参数.

但是您可以在等价的JSON函数JSON_EXTRACT()中使用任何表达式--包括参数占位符.

->>运算符类似于JSON_UNQUOTE(JSON_EXTRACT(json_doc, path))

$sql = <<<SQL
    SELECT JSON_UNQUOTE(JSON_EXTRACT(`key`, :path)) AS `setting_value`
    FROM `settings`
    LIMIT 1
SQL;

这似乎是MySQL的JSON操作符的功能中不必要的不一致,但这就是它在当前MySQL版本8.3中的实现方式.


如果使用PDO并设置为PDO::ATTR_EMULATE_PREPARES => true(缺省值),则参数不是真正的参数,它们是在解析SQL查询之前对其进行字符串替换.因此,就MySQL而言,看起来像是参数化查询实际上使用了字符串,并且->>运算符是成功的.

如果使用PDO和SET PDO::ATTR_EMULATE_PREPARES => false,那么MySQL将在准备步骤中解析参数占位符.由于不支持将参数作为->>运算符的参数,因此此操作将失败.

MySQLI只支持真参数,所以总是会失败.

Php相关问答推荐

dockerized laravel服务器拒绝POST请求

未在moodle上运行的计划任务

一列必须指定多个变量的Laravel查询

向在添加到购物车上动态创建的WooCommerce产品添加发货类别

在WooCommerce中添加基于类别的固定费用

WooCommerce我的帐户:从帖子作者处获取自定义帖子类型帖子ID

在PHP 8.2 Gloogle云引擎上加载大型php文件速度缓慢

PHP根据特定索引值从中删除子数组

在 WooCommerce 订阅续订订单中设置送货方式

如何将不同的 Woocommerce 费用合并为一个名称?

php var_dump(1) 返回字符串(4)

使用 Eloquent 更新现有的外键值

Php 的新WeakMap - 枚举曾经被垃圾收集过吗?

构建 [Controller] 时目标 [Interface] 不可实例化

使用 splat 运算符时按引用传递 (...)

WordPress 函数 get_post(post_id) 是否查询数据库?

mysql / sql修复多对多数据库中的行

我想更新表格中的结果并将它们发布到浏览器,但它不起作用

如何通过本地主机在同一台 PC 上同时运行 Microsoft IIS 和 WAMP

递归数组处理