首页  >  问答  >  正文

如何在 MySQL 语句中包含 PHP 变量

<p>我正在尝试在内容表中插入值。如果我在 VALUES 中没有 PHP 变量,它就可以正常工作。当我将变量 <code>$type</code> 放入 <code>VALUES</code> 中时,这不起作用。我做错了什么?</p> <pre class="brush:php;toolbar:false;">$type = 'testing'; mysql_query("INSERT INTO contents (type, reporter, description) VALUES($type, 'john', 'whatever')");</pre> <p><br /></p>
P粉738248522P粉738248522395 天前532

全部回复(2)我来回复

  • P粉949848849

    P粉9498488492023-08-24 16:07:56

    为避免 SQL 注入,插入语句带有 be

    $type = 'testing';
    $name = 'john';
    $description = 'whatever';
    
    $con = new mysqli($user, $pass, $db);
    $stmt = $con->prepare("INSERT INTO contents (type, reporter, description) VALUES (?, ?, ?)");
    $stmt->bind_param("sss", $type , $name, $description);
    $stmt->execute();

    回复
    0
  • P粉883223328

    P粉8832233282023-08-24 15:43:16

    在任何 MySQL 语句中添加 PHP 变量的规则都是简单明了的:

    1。使用准备好的语句

    此规则涵盖 99% 的查询,特别是您的查询。任何表示SQL 数据文字的变量(或者,简单地说 - SQL 字符串或数字)都必须通过准备好的语句添加。 没有例外

    此方法涉及四个基本步骤

    • 在 SQL 语句中,将所有变量替换为占位符
    • 准备结果查询
    • 将变量绑定到占位符
    • 执行查询

    以下是如何使用所有流行的 PHP 数据库驱动程序执行此操作:

    使用mysqli添加数据文字

    当前的 PHP 版本允许您在一次调用中完成准备/绑定/执行:

    $type = 'testing';
    $reporter = "John O'Hara";
    $query = "INSERT INTO contents (type, reporter, description) 
                 VALUES(?, ?, 'whatever')";
    $mysqli->execute_query($query, [$type, $reporter]);

    如果您的 PHP 版本较旧,则必须显式完成准备/绑定/执行:

    $type = 'testing';
    $reporter = "John O'Hara";
    $query = "INSERT INTO contents (type, reporter, description) 
                 VALUES(?, ?, 'whatever')";
    $stmt = $mysqli->prepare($query);
    $stmt->bind_param("ss", $type, $reporter);
    $stmt->execute();

    代码有点复杂,但是所有这些运算符的详细解释可以在我的文章中找到,如何使用 Mysqli 运行 INSERT 查询,以及显着简化该过程的解决方案。

    对于 SELECT 查询,您可以使用与上面相同的方法:

    $reporter = "John O'Hara";
    $result = $mysqli->execute_query("SELECT * FROM users WHERE name=?", [$reporter]);
    $row = $result->fetch_assoc(); // or while (...)

    但是,如果您的 PHP 版本较旧,您将需要执行准备/绑定/执行例程,并添加对 get_result() 方法的调用,以获得熟悉的< code>mysqli_result 您可以通过通常的方式从中获取数据:

    $reporter = "John O'Hara";
    $stmt = $mysqli->prepare("SELECT * FROM users WHERE name=?");
    $stmt->bind_param("s", $reporter);
    $stmt->execute();
    $result = $stmt->get_result();
    $row = $result->fetch_assoc(); // or while (...)
    使用 PDO 添加数据文字
    $type = 'testing';
    $reporter = "John O'Hara";
    $query = "INSERT INTO contents (type, reporter, description) 
                 VALUES(?, ?, 'whatever')";
    $stmt = $pdo->prepare($query);
    $stmt->execute([$type, $reporter]);

    在PDO中,我们可以将bind和execute部分结合起来,非常方便。 PDO 还支持命名占位符,有些人觉得这非常方便。

    2。使用白名单过滤

    任何其他查询部分,例如 SQL 关键字、表或字段名称或运算符 - 必须通过白名单进行过滤。

    有时我们必须添加一个代表查询另一部分的变量,例如关键字或标识符(数据库、表或字段名称)。这种情况很少见,但最好做好准备。

    在这种情况下,必须对照脚本中显式写入的值列表检查您的变量。我的另一篇文章根据用户的选择在 ORDER BY 子句中添加字段名称对此进行了解释:

    这是一个例子:

    $orderby = $_GET['orderby'] ?: "name"; // set the default value
    $allowed = ["name","price","qty"]; // the white list of allowed field names
    $key = array_search($orderby, $allowed, true); // see if we have such a name
    if ($key === false) { 
        throw new InvalidArgumentException("Invalid field name"); 
    }
    $direction = $_GET['direction'] ?: "ASC";
    $allowed = ["ASC","DESC"];
    $key = array_search($direction, $allowed, true);
    if ($key === false) { 
        throw new InvalidArgumentException("Invalid ORDER BY direction"); 
    }

    在这样的代码之后,$direction$orderby 变量都可以安全地放入 SQL 查询中,因为它们要么等于允许的变体之一,要么将会抛出一个错误。

    关于标识符最后要提到的是,它们还必须根据特定的数据库语法进行格式化。对于 MySQL,它应该是标识符周围的反引号字符。因此,我们的订单示例的最终查询字符串将是

    $query = "SELECT * FROM `table` ORDER BY `$orderby` $direction";

    回复
    0
  • 取消回复