如何在PHP和PDO中处理用户文本输入?

时间:2015-07-12 09:34:29

标签: php mysql pdo sql-injection

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

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

另外,我有点困惑为什么单引号截断数据输入。我认为PDO bindValue()应该为我单引号。我可能弄错了。手册不是很具描述性。

我检查过的事情:

  1. PHP魔术引号不在我的php.ini文件中,因为我使用的是版本,因为它已被折旧。
  2. 阅读PDO的所有手册(bindParam()bindValue()prepare()quote()
  3. 阅读StackOverflow上的所有类似问题。
  4. 以下是我正在使用的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";
    }
    

2 个答案:

答案 0 :(得分:3)

您不应该为此使用PDO quote()和MySQL。只有当您需要在语句中插入SQL时,它才真正有用,而bindParam() / bindValue()无法完成。我有一种感觉,这里还有其他的东西,为什么引号会导致截断。 bindParam() / bindValue()应该正确地转义您绑定的任何字符串,而不必修改或过滤它。

答案 1 :(得分:1)

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

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

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

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