【问题标题】:PHP `Create Table` is including quote marks in the table namePHP`Create Table`在表名中包含引号
【发布时间】:2020-10-03 07:35:26
【问题描述】:

我遇到了一个奇怪的问题,即创建表会将反引号添加到数据库中的表名。

public function create_table($name)
{
    $sql = "
        CREATE TABLE IF NOT EXISTS `?` (
          id int(11) NOT NULL AUTO_INCREMENT,
          url varchar(255) NOT NULL,
          resolved tinyint(1) NOT NULL,
          PRIMARY KEY (id)
        )";

    $query = $this->_pdo->prepare($sql);


    $query->bindValue(1, $name);

    if($query->execute())
    {
        print("Created");
    }
    else
    {
        var_dump($query->errorInfo());
    }   
}

我这样做并绑定$name 的原因是它将由我正在制作的网络爬虫动态完成以查找常见的文件和目录名称,并且由于大量路径可收集为每个站点确定一个表,并根据其主机名生成其名称。 (可能的狡猾主机名示例:https://whe.re/

但这导致了这个。

所以我尝试不使用它们,但它会引发错误

“您的 SQL 语法有错误;请查看与您的 MariaDB 服务器版本相对应的手册,了解在 ''random_site' 附近使用的正确语法

我没有看到或想到什么,自从我使用 PHP 已经有一段时间了,我很茫然,因为我的所有搜索都让我明白为什么在进行查询时表名应该用反引号括起来不是我的问题。

谢谢

信息:MariaDB
PHP:7.4.6

【问题讨论】:

  • 这些是引号,而不是反引号。您不能绑定表名。它被引用是因为你绑定了它,然后它在反引号中执行,所以你说的实际名称是' + NAME +'。您应该创建一个包含所有可能名称的数组并与之进行比较。看whitelist检查。
  • @user3783243 谢谢,这就是我的想法,只是不确定所以在这里问。
  • 我实际上认为您当前的实现可以被注入。我认为准备好的语句不会触及反引号或),因此恶意用户可以关闭create 命令并执行其他操作。 (假设仿真开启)
  • $name 的确切值是多少?
  • @Martin $name 本来是动态的,但在阅读了@GMB 的回答后,我想我会改变我要做的方式

标签: php mysql database-design mariadb create-table


【解决方案1】:

那是因为你正在绑定一个字符串值,所以它被注入了周围的单引号。但最重要的是,您不能在查询中将表名作为参数传递。绑定机制旨在传递文字值,而表名显然不是。

在这种特定情况下,除了字符串连接,您别无选择:

$sql = "
    CREATE TABLE IF NOT EXISTS `$name` (
      id int(11) NOT NULL AUTO_INCREMENT,
      url varchar(255) NOT NULL,
      resolved tinyint(1) NOT NULL,
      PRIMARY KEY (id)
    )";

$query = $this->_pdo->prepare($sql);
if ($query->execute()) { 
    ... 
} else {
    ... 
}

这意味着在将变量传递给查询之前,您需要在应用程序端彻底验证变量,这不是一件容易的事。

这最终提出了一个问题:为什么每个站点都有一个单独的表格。我不推荐这种设计,它违反了基本的规范化规则,并且很快就会变成维护的噩梦。相反,您应该有一个列出站点的引用表和一个包含所有路径的表,其中包含一个引用站点表的外键列。使用正确的架构和索引,您不太可能遇到性能问题,除非您有数以亿计的行(在这种情况下可以使用其他选项,例如逻辑分区)。

【讨论】:

  • 我正在考虑对名称应用程序端进行清理并像这样连接它是解决方案,但我想我会在这里问,以防我遗漏了什么。谢谢,非常感谢。
  • @akaBase:您可能想读到最后的答案。简而言之,我认为你应该改变你的设计......
  • @GMB 请分析这个copy-pasta:stackoverflow.com/q/68721008/2943403你的回答真的有用吗?我错过了什么?
猜你喜欢
  • 2020-03-21
  • 1970-01-01
  • 2011-12-24
  • 2014-06-11
  • 2014-06-02
  • 2019-02-11
  • 2016-03-05
  • 1970-01-01
  • 2016-04-24
相关资源
最近更新 更多