代码之家  ›  专栏  ›  技术社区  ›  Dennis

Mysqli bind_param()无法按预期工作

  •  0
  • Dennis  · 技术社区  · 11 年前

    有人能告诉我我做错了什么吗? 当我执行并获取这个时,我将成为正确的结果。

    $message = '100';
    if($stmt = $mysqli->prepare("select english from table where message=? LIMIT 1")) {
    $stmt = bind_param("i", $message);
    } //Return the Message in English
    

    但当我将语言放入变量并使用bind_param()时。 我只是将新变量作为结果返回例如:

    $message = '100';
    $language = 'english';
    if($stmt = $mysqli->prepare("select ? from table where message=? LIMIT 1")) {
    $stmt = bind_param("si", $language, $message);
    } //Returns "english"
    

    我想问题是“$language”被绑定为“String”。正确的类型是什么?已尝试将其更改为blob或double,但没有结果。

    1 回复  |  直到 11 年前
        1
  •  1
  •   Sasha    11 年前

    让我们看看是什么 bind_param

    $stmt = $mysqli->prepare("select * from users where name=?");
    $stmt->bind_param("s", "Dennis");
    

    大致相当于

    $stmt = $mysqli->prepare("select * from users where name='Dennis'");
    

    然而,使用bind_param比手动将值插入SQL查询要安全得多。因为在手动插入值时,需要小心处理特殊字符;否则恶意构造的值会使SQL解析器将部分值视为命令、表名、列名等,而不是值;有了bind_param,你就不用担心了 Dennis 应该变成 'Dennis' 插入SQL查询之前,但是 Dennis O'Brian 应该变成 'Dennis O\'Brian' (不是 'Dennis O'Brian' ),和 NUL-character 应该变成 '\0' (不保留为NUL字符)。

    bind_param仅适用于插入 价值观 转换为SQL查询。因为当您需要插入 列或表名称 在SQL查询中,您实际上需要相反的方法——您需要将列名直接插入SQL查询中(不添加任何引号等)。因此,您实际上需要:

    select english from table where message=... LIMIT 1
    

    select 'english' from table where message=... LIMIT 1
    

    所以,就这样做:

    $message = '100';
    $language = 'english';
    $sql = "select " . $language . " from table where message=? LIMIT 1";
    if($stmt = $mysqli->prepare($sql)) {
        $stmt->bind_param("i", $message);
    }
    

    唯一的问题是你 必须确定 $language 包含有效的列名 。否则,如果用户强制传递坏消息 $语言 ,你会得到 SQL-injection .

    $message = ...;
    $language = ...;
    ...;
    if(!in_array($language, array('english', 'german', 'french'), true))
        $language = 'english';
    $sql = "select " . $language . " from table where message=? LIMIT 1";
    if($stmt = $mysqli->prepare($sql)) {
        $stmt->bind_param("i", $message);
    }