简体   繁体   中英

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. (Example of a possible dodgy hostname: 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'

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.

Thanks

Info: MariaDB
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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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