【问题标题】:PHP Sanitize DataPHP 清理数据
【发布时间】:2011-08-17 08:04:59
【问题描述】:

我是编码和 PHP 领域的新手,因此想了解什么是清理表单数据以避免格式错误的页面、代码注入等的最佳方法。我在下面找到的示例脚本是一个很好的例子吗?

代码最初发布于http://codeassembly.com/How-to-sanitize-your-php-input/

/**
 * Sanitize only one variable .
 * Returns the variable sanitized according to the desired type or true/false 
 * for certain data types if the variable does not correspond to the given data type.
 * 
 * NOTE: True/False is returned only for telephone, pin, id_card data types
 *
 * @param mixed The variable itself
 * @param string A string containing the desired variable type
 * @return The sanitized variable or true/false
 */

function sanitizeOne($var, $type)
{       
    switch ( $type ) {
    case 'int': // integer
        $var = (int) $var;
        break;

    case 'str': // trim string
        $var = trim ( $var );
        break;

    case 'nohtml': // trim string, no HTML allowed
        $var = htmlentities ( trim ( $var ), ENT_QUOTES );
        break;

    case 'plain': // trim string, no HTML allowed, plain text
        $var =  htmlentities ( trim ( $var ) , ENT_NOQUOTES )  ;
        break;

    case 'upper_word': // trim string, upper case words
        $var = ucwords ( strtolower ( trim ( $var ) ) );
        break;

    case 'ucfirst': // trim string, upper case first word
        $var = ucfirst ( strtolower ( trim ( $var ) ) );
        break;

    case 'lower': // trim string, lower case words
        $var = strtolower ( trim ( $var ) );
        break;

    case 'urle': // trim string, url encoded
        $var = urlencode ( trim ( $var ) );
        break;

    case 'trim_urle': // trim string, url decoded
        $var = urldecode ( trim ( $var ) );
        break;

    case 'telephone': // True/False for a telephone number
        $size = strlen ($var) ;
        for ($x=0;$x<$size;$x++)
        {
            if ( ! ( ( ctype_digit($var[$x] ) || ($var[$x]=='+') || ($var[$x]=='*') || ($var[$x]=='p')) ) )
            {
                return false;
            }
        }
        return true;
        break;

    case 'pin': // True/False for a PIN
        if ( (strlen($var) != 13) || (ctype_digit($var)!=true) )
        {
            return false;
        }
        return true;
        break;

    case 'id_card': // True/False for an ID CARD
        if ( (ctype_alpha( substr( $var , 0 , 2) ) != true ) || (ctype_digit( substr( $var , 2 , 6) ) != true ) || ( strlen($var) != 8))
        {
            return false;
        }
        return true;
        break;

    case 'sql': // True/False if the given string is SQL injection safe
        //  insert code here, I usually use ADODB -> qstr() but depending on your needs you can use mysql_real_escape();
        return mysql_real_escape_string($var);
        break;
    }       
    return $var;
}

【问题讨论】:

  • 它看起来确实很有用。尽管htmlentities 应替换为htmlspecialchars 并声明字符集参数。

标签: php sanitize


【解决方案1】:

该脚本有一些不错的功能,但在清理方面做得不好!

根据您的需要(并希望接受),您可以使用:

  • abs() 用于正数(注意它也接受浮点数

  • preg_replace('/[^a-zA-Z0-9 .-]/','',$var) 用于清除字符串中的任何特殊字符或preg_replace('/\D/','',$var) 用于清除所有非数字字符

  • ctype_* functions 例如。 ctype_digit($var)

  • filter_var()filter_input() 函数

  • type-cast 例如。 (int)$_GET['id']

  • 转换例如。 $id=$_GET['id']+0;

【讨论】:

  • 谢谢。使用正则表达式去除特殊字符会更好吗?为什么不使用 htmlspecialchars?
【解决方案2】:

您的示例脚本不是很好 - 所谓的字符串净化只是修剪每一端的空白。依赖它会很快给你带来很多麻烦。

没有一种万能的解决方案。您需要对您的应用程序进行正确的清理,这完全取决于您需要什么输入以及在何处使用它。在任何情况下,您都应该在多个级别进行清理 - 最有可能在您接收数据、存储数据以及渲染数据时进行。

值得一读,可能是骗子:

What's the best method for sanitizing user input with PHP?

Clean & Safe string in PHP

【讨论】:

  • 谢谢。您如何测试所有可能的场景或至少是其中的一个子集?
  • @PeanutsMonkey - 您的示例中使用的 方法 很好 - 即调用一个通用的清理功能,该功能只允许您特别定义的数据,以及您特别要求的类型。那部分很好。问题是消毒需要足够强大。清理数字很容易(类似于$i = (float) $i;),问题通常出在字符串上,因为它们容易受到 SQL 注入和 XSS 攻击。你真的需要知道你的字符串是用来做什么的。例如。他们必须支持外来字符吗?
【解决方案3】:

作为一般规则,如果您使用 PHP 和 MySQL,您需要像这样对进入 MySQL 的数据进行清理:

$something = mysql_real_escape_string($_POST['your_form_data']);

http://php.net/manual/en/function.mysql-real-escape-string.php

【讨论】:

    【解决方案4】:

    还不错。

    对于 SQL,最好通过使用 PDO 将参数插入到查询中来完全避免这种情况的风险。

    【讨论】:

    • 你可以用 mysqli 达到同样的效果。如果您只打算使用 MySQL,这可能会稍微好一些。 mysqli prepared statements
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    相关资源
    最近更新 更多