【问题标题】:Custom functions for non-select queries Cake Query Builder非选择查询的自定义函数 Cake Query Builder
【发布时间】:2021-03-04 07:52:11
【问题描述】:

我想在带有 Cakephp 查询生成器的插入查询中使用 mariadb INET_ATON()

INSERT INTO failed_logins 
SET email = 'example@test.com', ip_address = INET_ATON('192.168.0.1'), sent_email = 1;

然后我想在选择查询中使用INET_NTOA() 检索数据。

SELECT id, email, INET_NTOA(ip_address) AS ip_address, sent_email FROM failed_logins;

如何在 Cake Query Builder 上将这些函数与插入和选择一起使用?
我看到了Using SQL functions,但无法解决我的问题。

【问题讨论】:

  • 参考手册的自定义功能部分似乎是您问题的答案。试试吧!
  • 可能,但我太笨了,无法从中做出什么。 func() 方法用于查询对象,我使用 $this->connection->insert('table', $row) 进行插入,不涉及任何查询,但我错过了一些我知道的东西。
  • 您是否有特定的理由使用连接而不是 ORM,甚至是查询构建器?
  • @ndm 我发布了一个编辑。
  • 我不是说你不需要使用insert(),如果你想创建一个插入查询,你肯定需要调用insert(),但你不一定有使用连接的便利功能,它只是查询构建器插入的包装器,带有连接的重试策略。

标签: mysql mariadb query-builder cakephp-4.x


【解决方案1】:

在玩了很多之后,我设法让它工作了。

$this->connection->newQuery()->into('failed_logins');
$newIp = $query->func()->inet_aton([$ip]);
$query->insert(['email', 'ip_address', 'sent_email'])->values(
    ['email' => $email, 'ip_address' => $newIp, 'sent_email' => $sentEmail]
)->execute()->lastInsertId();

相当复杂,我的 IDE 和 PHPStan 向我显示未定义函数“inet_aton”的警告。
如果在values() 数组中我可以像['ip_address' => "INET_ATON($ip)"] 那样完成它,我会喜欢它。编辑:这不是一个好主意,请参阅 cmets。但是可以使用->bind()(下面的代码 sn-p)来完成类似的安全操作。

编辑:从代码 sn-p 中删除 'literal'(感谢 @ndm)

IDE 和分析工具 - 友好的解决方案

$this->connection->newQuery()->into('failed_logins');

$query->insert(
    [
        'email',
        'ip_address',
        'sent_email',
    ]
)->values(
    [
        'email' => $email,
        'ip_address' => $query->newExpr("INET_ATON(:ip)"),
        'sent_email' => $sentEmail,
    ]
)->bind(':ip', $ip, 'string')->execute()->lastInsertId();

【讨论】:

  • 我可以向您保证,您不会喜欢它,因为这将需要不绑定/转义右侧的值,这会使您的代码对 SQL 注入敞开大门! ;) 作为表达式的替代方案,您始终可以在查询生成器上使用 manual bindings 'INET_ATON(:ip)' 然后 ->bind(':ip', $ip, 'string')。 ps,请注意literal,即按原样插入数据(但它需要在值方面才能工作),这又容易发生SQL注入!跨度>
  • 你完全正确。在这种情况下,$ip 来自$_SERVER['REMOTE_ADDR'],这是安全的,因为客户端无法随意修改它。我看到我可以(肮脏地)用$query->newExpr("INET_ATON($ip)"); 归档我想要的东西,但很明显,这不能与不受信任的值一起使用,但你会在这里允许吗?手动装订很有趣,我不知道!我想我会这样做;对我来说最有意义。
  • 我绝对不会这样做,除非在技术上实际需要 1001%!但即便如此,如果适用,我也会使用白名单或手动转义输入。虽然您的代码现在可能使用来自安全来源的值,但不能保证它会保持这种状态,有一天您在更改代码时可能会有点粗心,或者其他不知道的人关于值的使用位置/方式会发生变化,突然输入来自不受信任的来源。你永远不知道未来会怎样。
  • 对,这很有可能。始终保持安全并绑定我会记住的东西。我现在喜欢->bind 的编辑,非常感谢这个建议。
猜你喜欢
  • 1970-01-01
  • 2014-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-19
  • 2019-06-30
  • 1970-01-01
  • 2021-10-02
相关资源
最近更新 更多