【问题标题】:PHP MYSQL ERROR when inserting data插入数据时出现PHP MYSQL错误
【发布时间】:2016-04-26 20:25:13
【问题描述】:

我收到以下错误:

2016-04-26 15:11:56 --- 调试:将用户数据插入旧数据库时发生错误:Database_Exception [ 0 ]:[1064] 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行 ~ APPPATH/classes/database/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

【问题讨论】:

  • password 字段的类型是VARCHAR,所以值$user['password'] 应该用单引号括起来。
  • 单引号还是双引号?
  • 请不要同时标记mysqlsql-server。它们是 2 个完全不同的数据库,它们不是一回事。
  • @apandey,单引号。
  • @RajdeepPaul 我确实添加了单引号,但我仍然遇到同样的错误?

标签: php mysql mysqli kohana


【解决方案1】:

您需要在 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 语句的逻辑。

您可以在the PHP manual 中阅读有关准备好的语句的更多信息。

所以你的 SQL真正应该是这样的:

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

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

【讨论】:

  • @Sean 很可能他使用了一些整数列,尽管单引号从来没有真正受到伤害,所以我想我会发布一些不管他的架构细节如何都可以工作的东西。
  • 再看OPs的列类型,除了password之外,都是int/tinyint,所以虽然引用其他值是可行的,但完全没有必要。
【解决方案2】:

由于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 reserved word 时才需要反引号,但最好避免使用保留字。

旁注:使用PDO prepare 来防止您的数据库遭受任何形式的SQL 注入。

来自 PDO::prepare

为将使用不同参数值多次发出的语句调用 PDO::prepare() 和 PDOStatement::execute() 通过允许驱动程序协商客户端和/或服务器端缓存查询计划和元信息,无需手动引用参数,有助于防止 SQL 注入攻击。

【讨论】:

    猜你喜欢
    • 2011-09-04
    • 1970-01-01
    • 2018-09-18
    • 1970-01-01
    • 2013-07-15
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多