【问题标题】:matching with name containing apostrophe in php与 php 中包含撇号的名称匹配
【发布时间】:2013-12-18 13:56:35
【问题描述】:

我有一个查询,我想在其中匹配 fname 和 lname

$result = $mysqli->query('SELECT * FROM user WHERE userId = "'.$_SESSION["userId"].'" AND FriendFirstName = "'.htmlentities($firstName, ENT_QUOTES,"UTF-8").'" AND FriendLastName = "'.htmlentities($lastName, ENT_QUOTES,"UTF-8").'"   AND   FriendStatusCode="verified" AND friendId!='.$fid.' AND ViewableRow <> "0" ')  or die($mysqli->error);
echo 'SELECT * FROM user WHERE userId = "'.$_SESSION["userId"].'" AND FriendFirstName = "'.htmlentities($firstName, ENT_QUOTES,"UTF-8").'" AND FriendLastName = "'.htmlentities($lastName, ENT_QUOTES,"UTF-8").'"   AND   FriendStatusCode="verified" AND friendId!='.$fid.' AND ViewableRow <> "0" ';

如果我有一个名字 John'y,那么它不会产生任何结果,它不会返回任何行,我会回显查询,如果我运行相同的查询,我会在我的 sql 中得到结果。

输出变成这样


SELECT * 
FROM user_friend_detail
WHERE userId = "9306" AND FriendFirstName = "Aa\'tid"
AND FriendLastName = "Kenddy" 
AND FriendStatusCode="verified" AND friendId!=9366 AND ViewableRow  "0"

它在mysql中返回行。我关闭了魔术引号,我认为这是一个非常简单的问题,但它浪费了我很多时间。

The FNAME is Aa'tid
The lname is Kenddy

我错过了什么吗?

【问题讨论】:

  • HTML 转义和反转义是必需的。
  • @duffymo htmlentites 用于相同目的
  • 这是htmlentities 根据文档 (php.net/htmlentities) 的预期行为。我会退后一步,考虑在 MySQLi 中使用准备好的语句(参见php.net/manual/en/mysqli.quickstart.prepared-statements.php),而不是直接将字符串添加到查询中并在 PHP 中转义它们。无论如何,这是一种更优雅、更安全的做法,而且它可以匹配引号而不会出现复杂情况。
  • @Anton 我试过了,如何在 select 的情况下从准备好的语句中获取结果,$stmt->bind_param('issi', $_SESSION['userId'], $firstName, $lastName, $fid); $stmt->执行();

标签: php mysql sql magic-quotes-gpc mysql-escape-string


【解决方案1】:

由于我们已经讨论过在 cmets 中更改为准备好的语句,因此您可以执行以下操作(这是面向对象的方法,与旧的程序方法不同):

// this code will use the following variables that you must set somewhere before running your query:
//     $firstName
//     $lastName
//     $fid
// it also uses:
//     $_SESSION["userId"]

// connect to the database (fill in values for your database below)
$mysqli = new mysqli('host','username','password','default database');

// build query with parameters
$query = "SELECT * FROM user WHERE userId = ? AND FriendFirstName = ? AND FriendLastName = ? AND FriendStatusCode='verified' AND friendId != ? AND ViewableRow <> '0'";

// prepare statement
if ($stmt = $mysqli->prepare($query)) {

    // bind parameters
    $stmt->bind_param("issi", $_SESSION['userId'], $firstName, $lastName, $fid);

    // execute statement
    $stmt->execute();

    // set the variables to use to store the values of the results for each row (I made the variables up, in this case, let's assume your query returns 3 columns, `userId`, `firstName`, and `lastName`)
    $stmt->bind_result($returnUserId, $returnFirstName, $returnLastName);

    // loop through each row
    while ($stmt->fetch()) {

        // output the variables being looped through
        printf ("%d: %s %s\n", $returnUserId, $returnFirstName, $returnLastName);

    }

    // close statement
    $stmt->close();

}

// close connection
$mysqli->close();

这个例子没有使用错误处理,但它应该使用。还有很多其他方法可以处理结果集(例如关联数组),您可以查看要使用的文档。在此示例中,我使用 bind_result 循环遍历行并实际分配变量,因为我相信当您有大量代码时它会更简洁且更易于跟踪。

【讨论】:

  • 这是唯一的解决方案,如果不使用准备好的语句,我不能这样做吗?
  • 可以,但我不建议您走构建查询字符串的路径,将变量直接插入到文本中;这是不好的做法,可能会带来严重的安全问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-20
  • 2014-06-02
  • 2013-09-06
  • 2014-10-13
相关资源
最近更新 更多