【问题标题】:Stop SQL from inserting duplicates (php)阻止 SQL 插入重复项 (php)
【发布时间】:2023-03-28 21:30:01
【问题描述】:

似乎只用SQL语句做不到,所以我写了一个php检查,完全被脚本忽略了。 $resource 数组保存正确的数据。

public function handleUpdates($updates) {

    $stmt = $this->database->connect()->prepare("SELECT ? FROM users"); //<-
    $stmt->execute(["username"]); //<-
    $resource = $stmt->fetch(PDO::FETCH_ASSOC); //<-

    foreach ($updates["result"] as $update) {

        $text = $update["message"]["text"];
        $args = $update["message"]["chat"]["username"];

        if ($text === "/start") {              
            if ($resource['username'] !== $args) //this here is ignored
                $this->database->add($args); 
        }
    }
}

【问题讨论】:

  • $update["message"] 的内容是什么?您是否尝试过调试(例如打印其内容)?
  • 忽略?那么$resourse['username']$args 的值是多少呢?您获得的值可能与您的预期不同。
  • 注意表/列名不能绑定,但可以白名单
  • $resourse$resource 不同
  • 这段代码$resourse['username'] !== $args 无效,因为$resourse['username'] 是一个数组,而$args 我猜是一个字符串。如果要检查用户名是否存在于数组中,请使用in_arrayarray_key_exists

标签: php sql database oop pdo


【解决方案1】:

根据我对 PDO/SQL 的记忆(前段时间我转到 MVC/Doctrine),这部分似乎有点多余

$stmt = $this->database->connect()->prepare("SELECT ? FROM users"); //<-
$stmt->execute(["username"]); //<-

并且可以替换为

$stmt = $this->database->connect()->prepare("SELECT username FROM users"); //<-

由于您只想获取在用户名列中找到的数据,因此无需绑定它(无论如何,这在 PDO 中并不完全可能)。


您的查询失败的原因是您使用fetch 而不是fetchAll,它只返回第一行结果,而这将运行它不会给出所需的结果(我猜这是检查如果用户名已经存在)。即使那样(正如 Ivan Vartanyan 指出的那样),您仍需要 foreachin_array 而不是 $resource,因为它的结果无论如何都会作为数组发送。

实际上您不需要搜索和遍历 PHP 中的所有数据,请考虑使用 SQL 搜索您传递的用户名数据(代码未经测试);

public function handleUpdates($updates) {
    $stmt = $this->database->connect()->prepare("SELECT username FROM users WHERE username = ?");
    $stmt->execute(array($update["message"]["chat"]["username"]));
    $resource = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$resource) {
        foreach ($updates["result"] as $update) {
            $text = $update["message"]["text"];
            $args = $update["message"]["chat"]["username"];
            if ($text === "/start") {   
                $this->database->add($args); 
            }
        }
    }
}

【讨论】:

  • 这仍然会用一个相同的查询来淹没数据库(因为我猜我是在 while(true) 循环中运行这个方法
  • @danielserendipity 差不多了,你不需要把return true 放在这里吗?
  • 看起来不像,因为它不能打破循环public function execute () { while (true) { $t = $this-&gt;getLastChat($this-&gt;getUpdates()); $this-&gt;sendMessage ($t[0],$t[1]); $updates = $this-&gt;getUpdates(); if (count($updates["result"]) &gt; 0) $this-&gt;handleUpdates($updates); sleep(1); } }
  • @DanielSerendipity 使用while(true) 只会无限循环,除非您在while 语句或break 在循环某处放置条件
  • 不能停止循环,因为这是一个聊天机器人
猜你喜欢
  • 2016-02-19
  • 2022-01-02
  • 2016-08-17
  • 2017-05-02
  • 2015-12-19
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多