【问题标题】:Problems with space within parameters of a php functionphp函数参数中的空格问题
【发布时间】:2010-02-15 11:16:29
【问题描述】:

很抱歉没有格式化我的代码。工具栏不见了……

我想在 mysql 数据库中插入一些数据。我在 php 中写了一个函数:

function add_ID($ID, $token)  {
 $add = "INSERT INTO ids (ID, token) VALUES ('$ID', '$token')";
 mysql_query($add);
 echo 'added successfully';
}  
if(isset($_GET['addDeviceID'])) {
 add_ID($_GET['ID'], $_GET['token']);
}

在我的 Browswe 的 URL 字段中,我正在调用这样的函数: http://www.justanexample.com/example.php?ID=123123123&token=qwertzuiop

这行得通。

如果我在其中一个参数中添加一个空格,例如: http://www.justanexample.com/example.php?ID=123123123&token=qwertzuiop

我的 mysql 数据库中没有添加任何内容。

如果能得到一些帮助会很棒:) 谢谢!

【问题讨论】:

标签: php mysql get space


【解决方案1】:

您应该在将输入发送到数据库之前对其进行验证。或者,如果无法验证,请过滤和/或转义该值。

验证

如果您希望 ID 是大于零的整数:

if (!ctype_digit($ID)) {
    // invalid ID
}

如果您希望 token 是一个字母数字字符串:

if (!ctype_alnum($token)) {
    // invalid token
}

过滤

过滤正在删除输入的无效部分,使其变为有效:

if (!ctype_digit($ID)) {
    $ID = preg_replace('/\D+/', '', $ID);
    // $ID does now only contain digits
}
if (!ctype_alnum($token)) {
    $token = preg_replace('/\D+/', '', $token);
    // $token does now only contain alphanumeric characters
}

转义

转义是替换特定上下文的元字符,某些字符串将被放入其中。对于 MySQL 查询,您应该使用一个函数来转义 context string declaration in MySQL 的元字符。 PHP 有 mysql_real_escape_string function 用于此目的:

$add = "INSERT INTO ids (ID, token) VALUES ('".mysql_real_escape_string($ID)."', '".mysql_real_escape_string($token)."')";

【讨论】:

    【解决方案2】:

    您的函数容易受到 SQL 注入的攻击。您应该在 SQL 查询中使用它们之前验证所有用户接收到的参数,并通过 mysql_real_escape_string 传递任何字符串,因为这样我就可以传递类似 example.php?token='; DROP DATABASE; 的东西并彻底搞砸您的应用程序。

    在您的情况下,您应该首先检查接收到的参数是否符合您的预期,如果没有,则向用户返回错误,然后才将它们传递给 SQL 查询。

    function add_ID($ID, $token)  {
      $id = mysql_real_escape_string($id);
      $token = mysql_real_escape_string($token);
    
      $add = "INSERT INTO ids (ID, token) VALUES ('$ID', '$token')";
      mysql_query($add);
      echo 'added successfully';
    }  
    
    if(isset($_GET['addDeviceID'])) {
      $id    = isset($_GET['id']) ? $_GET['id'] : 0; // in case no ID has been passed in
      $token = isset($_GET['token']) ? $_GET['token'] : '';
    
      if (!is_numeric($id) {
        die('ID is not a number');
      } 
    
      // validate token here as well
    
      add_ID($id, $token);
    }
    

    您还应该研究参数化查询,这是一种使用参数进行 SQL 查询的总体上比仅使用字符串连接更好的方法。为此,请考虑使用 mysqli 扩展而不是 mysql,或者更高级别的 PDO。

    【讨论】:

    • 谢谢大家!这对我真的很有帮助,而且我学到了很多关于 SQL 的知识。上面代码的一个问题: isset($_GET['id']) ? $_GET['id'] : 0;这是做什么的?是吗?和 0 ?谢谢你:)
    • 该行检查以确保 $_GET 数组中存在“id”索引,然后再尝试访问它,否则会导致警告。 ?: 运算符称为三元运算符,它的工作方式类似于内联if。如果条件为真(索引存在),则返回数组中的值,否则返回0。看这里:php.net/manual/en/language.operators.comparison.php
    【解决方案3】:

    使用str_replace 函数从它们中删除空间,例如:

     $ID = str_replace(' ', '', $ID);
     $token= str_replace(' ', '', $token);
    
     $add = "INSERT INTO ids (ID, token) VALUES ('$ID', '$token')";
    

    另外,我怀疑您的 $ID 是表中的整数字段,因此您可以在不指定引号的情况下运行查询,例如:

     $add = "INSERT INTO ids (ID, token) VALUES ($ID, '$token')";
    

    【讨论】:

    • 仅从字符串的开头和结尾修剪删除空格
    • @Adelf:如果开头或结尾有空格,trim 将删除它,如果字符串中间有空格 str_replace 会解决问题,所以我考虑了这两种情况。谢谢
    • 如果您使用 str_replace,修剪 - 只是不必要的运算符。
    【解决方案4】:

    您的代码假设查询成功完成,而无需检查是否有错误。我猜这将是由于空格导致的语法错误。如果您的 ID 字段是整数类型,那么执行 ID=123 123 将是语法错误。包括其他答案中的所有 SQL 注入和数据清理建议,您应该重写 add_ID 函数,如下所示:

    function add_ID($ID, $token) {
      $query = 'blah blah blah';
      mysql_query($query);
      if (mysql_error()) {
           echo 'ruhroh, someone set us up the bomb: ', mysql_error();
      } else {
           echo 'woohoo, it worked!';
      }
    }
    

    至少这会告诉你查询是否真的成功了,如果没有成功,会发生什么。永远不要假设任何类型的数据库查询都会成功。导致它崩溃的方式太多了(服务器死机、事务死锁、连接池耗尽、磁盘空间不足等),甚至没有像上面那样简单的错误处理。

    【讨论】:

      【解决方案5】:

      您可以使用 str_replace 删除空格。但这不是一个好习惯。 如何修改 URL?在正常情况下,这是不真实的。 相反,您应该测试来自用户的所有输入值(ID 必须是整数,Token 不应包含“'”符号和其他检查)。阅读有关 sql 注入的信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-10
        • 2010-11-28
        • 2011-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多