URL 编码和过滤清理输出问题

URL encode and filter sanitize output problems

我想弄清楚为什么经过 URL 编码后经过清理的字符串与未经过清理的字符串的输出方式不同。

我不知道这叫什么,但我搜索了 URL encode and sanitization 并尝试了 google 但我找不到任何解释。

我在发布视频后无意中发现了这个,问题是我在数据库中插入标题,取出它们并用它创建一个URL。

示例 URL(由于问题无法正常工作)

localhost/proviin/video/kojima%26%2339%3Bs+cancelled+masterpiece+-+investigating+silent+hills/16

我进行了单页测试,以测试发生了什么以及您在下面看到的行为。

我需要怎样的结果(但这并没有被净化):

$title = "Kojima's Cancelled Masterpiece - Investigating Silent Hills";
echo $title;
echo "<br>";
echo urlencode($title);

输出:(在 URL 中有效)

怎么样

$title = sanitize("Kojima's Cancelled Masterpiece - Investigating Silent Hills", "str");
echo $title;
echo "<br>";
echo urlencode($title);

输出:(在 URL 中不起作用,但已清理)

清理函数

function sanitize($item, $type) {
    switch ($type) {
        case "str":
            return filter_var($item, FILTER_SANITIZE_STRING);
            break;
        case "mail":
            return filter_var($item, FILTER_SANITIZE_EMAIL);
            break;
        case "url":
            return filter_var($item, FILTER_SANITIZE_URL);
            break;
        case "int":
            return filter_var($item, FILTER_SANITIZE_NUMBER_INT);
            break;
        case "float":
            return filter_var($item, FILTER_SANITIZE_NUMBER_FLOAT);
            break;
        default:
            return false;
    }
}

据我所知:

您在将数据插入数据库之前清理数据。

回显时转义 (htmlspecialchars)

但是 为什么 使用 urlencode() 时经过清理的字符串输出不同?

如果这是正常行为,在将字符串插入数据库 table 并在 URL 和 urlencode() 中使用它们之前,我究竟如何清理字符串?

在添加到数据库之前进行清理的主要目的是避免 SQL 注入。其中一个易受攻击的符号是单引号 '。这就是为什么它被其他看起来相同但对数据库没有任何影响的符号替换的原因。

所以当你清理时,你替换了易受攻击的符号。在 URL 编码之后,这个符号有不同的代码。为防止 URL 不兼容,请始终在清理后或至少在相同操作后对字符串进行编码。

每当我使用输入文本作为文件名或文件夹时,我都会使用此功能来清理它。

/* urlsafe - Return a URL safe string */
public static function urlsafe($t)
{
    $t = strtolower($t);
    $t = preg_replace( "/[^a-z0-9]/", " ", $t);
    $t = trim($t);
    $t = preg_replace("/[ ]+/", "-", $t);
    return($t);
}

您正在对字符串进行双重转义。您不应将清理函数的 return 值传递给 urlencode()。两者都转义数据,但方式不同,所以它们不能像你在这里做的那样被链接起来(并不是说任何转义函数都应该 运行 两次)。

所以不,在将数据插入数据库之前,您不需要像这样清理数据。您需要使用准备好的语句对它进行转义,以便它在从数据库中 returned 时以相同的方式返回,为 urlencode()htmlentities() 发挥它们的魔力做好准备。除非您需要以特定方式存储数据,否则 preg_replace 可能更好。

此外,请注意,出于完全相同的原因,用户输入也不应 unserialized()http://php.net/manual/en/function.unserialize.php