【问题标题】:How to handle user text input in PHP and PDO?如何在 PHP 和 PDO 中处理用户文本输入?
【发布时间】:2015-09-30 17:05:16
【问题描述】:

我应该使用 PDO quote(),然后在检索用户输入时去掉引号和斜杠,还是有更好的方法?

当从 PHP 表单将用户输入插入 MySQL 时,任何单引号(撇号)都会截断数据。我目前正在使用 PDO 准备好的语句和 bindValue() 语句。我不确定是否使用 PDO quote() 方法,该方法似乎将我所有的字符串封装在引号中,然后用反斜杠(“\”)转义字符串中的引号。据我所知,如果我使用这种方法,那么我需要在检索数据时从字符串中去掉引号。这是最好的方法吗?使用 PDO quote() 然后使用子字符串删除封装的单引号是否安全?

另外,我有点困惑为什么单引号会截断数据输入。我认为 PDO bindValue() 应该为我转义单引号。我可能对此有误解。手册不是很详细。

我检查过的东西:

  1. PHP 魔术引号不在我的 php.ini 文件中,因为我正在使用一个版本,因为它已被贬值。
  2. 阅读 PDO 的所有手册(bindParam()bindValue()prepare()quote()
  3. 在 StackOverflow 上阅读所有类似问题。

这是我正在使用的 PDO 插入的代码:

//create query string
$profile_update_query_text = "
UPDATE user_profile 
SET public=:public, headline=:headline, display_name=:display_name, skype=:skype, description=:description
WHERE user_id=:user_id";

//update table is required to modify existing user profile data
$query_profile_update_insert = $this->db_connection->prepare($profile_update_query_text);
$query_profile_update_insert->bindValue(':user_id', $_SESSION['user_id'], PDO::PARAM_INT);
$query_profile_update_insert->bindValue(':public', $public, PDO::PARAM_INT);
$query_profile_update_insert->bindValue(':headline', $headline, PDO::PARAM_STR);
$query_profile_update_insert->bindValue(':display_name', $display_name, PDO::PARAM_STR);
$query_profile_update_insert->bindValue(':skype', $skype, PDO::PARAM_STR);
$query_profile_update_insert->bindValue(':description', $description, PDO::PARAM_STR);

//execute profile insert 
$query_profile_update_insert->execute();

我还包括用于创建 PDO 连接的函数,因此可以验证我没有使用任何会导致问题的设置:

private function databaseConnection()
    {
        // connection already opened
        if ($this->db_connection != null) {
            return true;
        } else {
        // create a database connection, using the constants from config/config.php
        try {
            $this->db_connection = new PDO('mysql:host='. DB_HOST .';dbname='. DB_NAME . ';charset=utf8', DB_USER, DB_PASS);
            return true;
        // If an error is catched, database connection failed
        } catch (PDOException $e) {
            $this->errors[] = MESSAGE_DATABASE_ERROR;
            return false;
        }
    }
}

如果用户输入如下标题:

我是个滑雪高手

在 MySQL 中我得到:

我或“我是一个很棒的滑雪者”

取决于我是否使用 PDO quote()

PDO bindParam() 的运行方式是否存在问题,它应该转义单引号,还是有更好的处理方法?

编辑——我检查了是否使用以下命令打开了魔术引号:

if(get_magic_quotes_gpc()){
    echo "magic quotes on";
}else{
    echo "magic quotes off";
}

【问题讨论】:

    标签: php mysql pdo sql-injection


    【解决方案1】:

    我发现 PDO 正确地将数据插入到数据库中。但是,当输出回 HTML 时,我发现我正在使用以下行:

    echo "value='".$this->profile_data['headline']."'";
    

    但是,这导致来自数据库的字符串中的单引号出现问题。

    使用 htmlentities() 解决了这个问题。

    【讨论】:

      【解决方案2】:

      您不应该为此将 PDO quote() 与 MySQL 一起使用。只有在需要在语句中插入 SQL 时才真正有用,而 bindParam()/bindValue() 无法做到这一点。我有一种感觉,这里发生了其他事情,为什么引号会导致截断。 bindParam()/bindValue() 应该正确地转义您绑定的任何字符串,而无需修改或过滤它。

      【讨论】:

      • 这就是我的想法,也是我检查 php.ini 文件以查看是否打开了魔术引号的原因。我使用的是 PHP 版本 5.5.9-1,并且 php.ini 没有引用魔术引号。
      • 对,魔术引号现在已经消失了。在致电 bindParam() 之前尝试 var_dump() 输入您的输入,并确保这是您所期望的。
      • 实际上它被截断了,所以只有字母 I 被插入到数据库中。我还在另一台服务器上实时运行该站点,并且我检查了它在站点上与在 localhost 上运行它的开发机器上的相同。
      • 好的,等一下。它正确地插入到数据库中,但没有正确地出现在 HTML 中。输出回表单时,变量在 ' 处被截断。
      • 啊!好吧,这更有意义。在输出到页面之前,您需要使用htmlentities() 转义结果:)
      猜你喜欢
      • 2012-10-02
      • 2015-11-07
      • 2013-08-05
      • 1970-01-01
      • 2013-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-28
      相关资源
      最近更新 更多