【问题标题】:Escaping Strings in PHP在 PHP 中转义字符串
【发布时间】:2014-03-13 02:46:59
【问题描述】:

这个 sn-p 工作得很好,直到它到达带有撇号的数据库条目。我看到我需要在拉动它们后逃离它们。作为 PHP 新手,我不确定如何处理有关 PDO 和“->”以及 mysqli_real_escape_string() 的所有这些信息。我对这一切有点困惑。如何转义 $team1rows 和 $team2rows 以便将它们传回我的页面?谢谢。

$team1rows = mysqli_num_rows(mysqli_query($connection,"SELECT * FROM $page WHERE vote = '$team1'"));
$team2rows = mysqli_num_rows(mysqli_query($connection,"SELECT * FROM $page WHERE vote = '$team2'"));

echo $team1rows . "|" . $team2rows;

在遇到撇号之前,回声可以正常工作。

【问题讨论】:

标签: php escaping


【解决方案1】:

改为使用 PDO,如果使用正确,prepare 语句可以防止 SQL 注入。 mysqli_query 是不应再使用的旧方法。请参阅下面列出的示例:

<?php
$pdo = new PDO('sqlite:users.db');
$stmt = $pdo->prepare('SELECT name FROM users WHERE id = :id');
$stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT); // <-- Automatically sanitized by PDO
$stmt->execute();

来源: http://www.phptherightway.com/#databases

-> 表示您正在处理对象的方法。 所以: $pdo 是一个对象 然后您可以使用 -> 访问其中的方法(函数) $pdo->例如准备

【讨论】:

  • 听起来如果我想切换到 PDO,我需要重新开始。不幸的是,我正在关注的教程没有使用它,我几乎没有坚持下去。下一个项目的 PDO 更有可能,感谢您的推动。同时,$team1number = mysqli_real_escape_string($connection,$team1rows);也没有用。
  • @Layne 我同意此时不要切换到 PDO(虽然我会推荐它用于新项目),但是 mysqli also 支持准备好的语句,只需要最少更改要使用的查询。
【解决方案2】:

tldr; use placeholders (aka parameterized queries / prepared statements)。这将消除所有 SQL Injection,包括当数据包含撇号时意外中断的查询!

由于mysqli supports placeholders,无需切换到PDO!尽管我建议使用 mysqli-object API,但我将代码保留在非 OOP mysqli 语法中。以下代码执行任何“转义” - 如果这样做,它只是一个实现细节。

# Create prepared statement, bind parameters - no apostrophe-induced error!
# - With placeholders there is need to worry about quoting at all
# - I recommend explicitly selecting columns
# - $page is NOT data in the query and cannot be bound in a placeholder
$stmt = mysqli_prepare($connection, "SELECT * FROM $page WHERE vote = ?");
mysqli_stmt_bind_param($stmt, "s", $vote);

# Execute prepared statement
$result = mysqli_stmt_execute($stmt);

# Use results somehow;
# Make sure check $result/execution for errors!
# (PDO is nice because it allows escalation of query errors to exceptions.)
$count = mysqli_num_rows($result);

现在,如上所述,$page 不能绑定在占位符中,因为它与 查询形状 相关,但不是数据。处理这种特殊情况的一种可接受的方法 - 如果不重新设计一般模式 - 是use a whitelist approach。例如,

$approvedPages = array("people", "tools", "pageX");
if (!in_array($page, $approvedPages)) {
   # Wasn't a known page - might have been something mischievous!
   # Choose default approved page or throw error or something.
   $page = $approvedPages[0];
}

【讨论】:

    【解决方案3】:

    我发现我做错了什么。我的业余错误。我试图逃避查询的结果。但在这种情况下,结果是行数。所以逃避结果不是问题,因为它只是一个数字。我很困惑,因为该数字与一个带有撇号的值相关联。我想所以查询中使用的字符串没有被转义,这导致它失败,而不是结果。

    因此,首先像这样转义我在查询中使用的变量...

    $page = mysqli_real_escape_string($connection, $page);
    $team1 = mysqli_real_escape_string($connection, $team1);
    $team2 = mysqli_real_escape_string($connection, $team2);
    

    这给了我很好的字符串用于以下查询。

    $team1number = mysqli_num_rows(mysqli_query($connection,"SELECT * FROM $page WHERE vote = '$team1'"));
    $team2number = mysqli_num_rows(mysqli_query($connection,"SELECT * FROM $page WHERE vote = '$team2'"));
    
    echo $team1number . "|" . $team2number;
    

    再次,我把这一切都倒退了,并试图逃避结果。菜鸟在我方面有所行动,但由于这一发现而学到了很多东西。谢谢大家。

    【讨论】:

    猜你喜欢
    • 2017-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-05
    相关资源
    最近更新 更多