简体   繁体   English

PHP `Create Table` 在表名中包含引号

[英]PHP `Create Table` is including quote marks in the table name

I'm having an odd issue where creating a table adds the back ticks to the table name in the database.我遇到了一个奇怪的问题,即创建表会将反引号添加到数据库中的表名中。

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());
    }   
}

The reason I am doing it like that and binding the $name is that it will be done dynamically by a web crawler I'm making to look for common file and directory names and due to the large amounts of paths gatherable ive decided on a table for each site and its name generated from its hostname.我这样做并绑定$name的原因是它将由 web 爬虫动态完成,我正在寻找常见的文件和目录名称,并且由于大量路径可收集,我决定在一张桌子上对于每个站点及其从其主机名生成的名称。 (Example of a possible dodgy hostname: https://whe.re/ ) (可能的狡猾主机名示例: https://whe.re/

But this has led to this.但这导致了这一点。

在此处输入图像描述

So I tried without them and it throws an error所以我在没有它们的情况下尝试过,它会引发错误

"You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''random_site' “您的 SQL 语法有错误;请查看与您的 MariaDB 服务器版本相对应的手册,了解在 ''random_site' 附近使用的正确语法

What am I not seeing or thinking, it's been a while since I've used PHP and I'm at a loss as all my searches lead me to why table names should be surrounded with back ticks when making a query which isn't my issue.我没有看到或想到什么,自从我使用 PHP 以来已经有一段时间了,我很茫然,因为我的所有搜索都让我明白为什么在进行不属于我的查询时表名应该用反引号括起来问题。

Thanks谢谢

Info: MariaDB信息:MariaDB
PHP: 7.4.6 PHP:7.4.6

That's because your are binding a string value, so it is injected with surrounding single quotes.那是因为你正在绑定一个字符串值,所以它被注入了周围的单引号。 But bottom line, you just can't pass a table name as a parameter in the query.但最重要的是,您不能在查询中将表名作为参数传递。 The binding mechanism is meant to pass literal values, which obviously a table name is not.绑定机制旨在传递文字值,而表名显然不是。

In this specific situation, you don't have another choice than string concatenation:在这种特定情况下,除了字符串连接之外,您别无选择:

$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 {
    ... 
}

This implies that you need to throughly validate the variable on application side before passing it to the query, which is not an easy task.这意味着您需要在将变量传递给查询之前在应用程序端彻底验证变量,这不是一件容易的事。

This ultimately raises the question of why you would have a separate table for each site.这最终提出了一个问题,即为什么每个站点都有一个单独的表。 I would not recommend this design, which violates the basic normalization rules, and can quickly turn to a maintenance nightmare.我不推荐这种设计,它违反了基本的规范化规则,并且很快就会变成维护的噩梦。 Instead, you should have a reference table that lists the sites, and a single table for all paths, with a foreign key column that references the sites table.相反,您应该有一个列出站点的引用表和一个包含所有路径的表,其中包含一个引用站点表的外键列。 With proper schema and indexing, you are not likely to experience performance issues, unless you have zillions of rows (in which case other options are available, such as logical partitioning).使用适当的模式和索引,您不太可能遇到性能问题,除非您有数以亿计的行(在这种情况下,其他选项可用,例如逻辑分区)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM