插入数据时出现 PHP MYSQL 错误


PHP MYSQL ERROR when inserting data

我收到以下错误:

2016-04-26 15:11:56 --- 调试:将用户数据插入旧数据库时出错:D atabase_Exception [ 0 ]: [1064] 您的 SQL 语法有错误;请查看与您的 MySQL 服务器版本对应的手册,了解在第 1 行的")"附近使用的正确语法 ~ APPPATH/类/数据库/mysqli.php [ 179 ]

对于 php 查询:

$result = $usdb->query(Database::INSERT, "INSERT INTO users (id, `password`, group_id , active, created, updated) VALUES ({$user['id']}, {$user['password']}, {$user['group_id']}, {$user['active']}, {$user['created']}, {$user['updated']})");

以下是列类型:

id : int AI PK
password : varchar
group_id : int
active : tinyint
created : int
updated : int
您需要在

SQL 查询中的值周围'单引号,假设它们是数据库中的字符串(而不是整数)。

列和表引用可以用反引号封装,尽管它们不必这样做,假设它们没有使用保留关键字。另一方面,值通常需要在它们周围加上单引号(当然,除非您通过预准备语句准备值;或者如果您确定数据库架构使用整数类型)。

将单引号

括在整数周围也同样有效,因此用单引号将任何值括起来可能是安全的,如下所示:

$result = $usdb->query(
    Database::INSERT, 
    "INSERT INTO users (id, `password`, group_id , active, created, updated) 
        VALUES (
            '{$user['id']}', 
            '{$user['password']}', 
            '{$user['group_id']}', 
            '{$user['active']}', 
            '{$user['created']}', 
            '{$user['updated']}'
        )
    "
);

注意:

您应该始终使用参数化查询(预准备语句)。将原始 PHP 变量注入 SQL 查询是非常不安全的。如果你有一个带单引号的变量,它将破坏你的SQL语句的逻辑。

您可以在 PHP 手册中阅读有关预准备语句的更多信息。

所以你的SQL应该是什么样子的:

$sql = "
    INSERT INTO users (id, `password`, group_id , active, created, updated) 
    VALUES (
        :id, 
        :password, 
        :group_id, 
        :active, 
        :created, 
        :updated
    )
";

然后将您的实际值绑定到准备好的语句中。

由于password列的类型是VARCHAR因此$user['password']的值应封装在单引号中。由于其余列的类型为 INTTINYINT因此不需要单引号。

所以你的查询应该是这样的:

$result = $usdb->query(Database::INSERT, "INSERT INTO users (`id`, `password`, `group_id` , `active`, `created`, `updated`) 
          VALUES (" . $user['id'] . ", '" 
          . $user['password'] . "', " 
          . $user['group_id'] . ", " 
          . $user['active'] . ", " 
          . $user['created'] . ", " 
          . $user['updated'] 
          . ")");

表名和列名应使用反引号 ('),字符串应使用单引号 (')。仅当表名或列名是 MySQL 保留字时,才需要反引号,但最佳做法是避免使用保留字。

旁注:使用 PDO 准备来防止数据库进行任何类型的 SQL 注入。

来自PDO::p repare

调用 PDO::p repare() 和 PDOStatement::execute() 对于将使用不同参数值多次发出的语句,通过允许驱动程序协商查询计划和元信息的客户端和/或服务器端缓存来优化应用程序的性能,并通过消除手动引用参数的需要来帮助防止 SQL 注入攻击。