如何将 PHP $_GET 变量与 Unicode 字符一起使用


how to use php $_GET variable with unicode characters?

<div class="linkL">STRAŠNI MIKROSKOP</div>
<?php
    $chapter = "chapters/" . $_GET["ch"] . ".php";
    include $chapter;
?>

.js

$(".linkL").click(function() {
    var a = $(this).html();
    var b = a.split(' ').join('-');
    var c = b.toLowerCase();
    location.href = "index.php?ch=" + c;
});

单击地址栏后,我有index.php?ch=strašni-mikroskop.没关系,但是不包括文件chapters/strašni-mikroskop!?

如果我用s替换š - 一切正常。

那么,如何使用š unicode 字符使用上面的代码呢?

所有文件都编码为 utf8。

location.href = "index.php?ch=" + c;

你需要在这里encodeURIComponent(c)。否则,URL 中任何特殊的字符(如 %& (都会破坏 URL。此外,这可确保 URL 中使用的编码为 UTF-8;如果没有显式编码,则由浏览器决定会发生什么,您可能会得到不一致的结果。

$chapter = "chapters/" . $_GET["ch"] . ".php";
include $chapter;

问题 1:文件名的编码需要与 URL 中的编码相同。这意味着您需要将文件传输工具配置为使用 UTF-8(如何执行此操作取决于工具(。如果你的服务器是Windows,你不能使用UTF-8,所以你必须故意错误地编码你的文件名。(例如,对于西欧服务器,它将使用代码页 1252,在这种情况下,您必须拼错文件straÅ¡ni-mikroskop.php

可能不值得尝试这样做,因为它很脆弱,当您移动到不同的工具和服务器时会损坏。

问题2:这是安全漏洞。攻击者可以提供任意相对路径名(如 ../someotherdirectory/x(来执行您意想不到的文件。这可能会与文件上传等其他功能相结合,使攻击者能够在您的服务器上执行任意代码。或者可以只包含index.php本身以获得无限循环并DoS您的服务器。

使用安全编码方案可以避免这两个问题。例如,使用 bin2hex(c) 您可以将文件称为73747261c5a16e692d6d696b726f736b6f70.php,这将在任何地方工作,并避免使用路径特殊字符,如 / .

但一般来说,最好不要允许用户选择任意的PHP文件。通常最好在脚本中有一个静态的可能性列表;然后,您可以随心所欲地调用文件。例如

switch ($_GET['ch']) {
    case 'strašni-mikroskop': include 'chapters/strasni-mikroskop.php'; break;
    case '☃':                 include 'chapters/snowman.php';           break;
    ...
}

问题 3.用<div>标记链接对可访问性、可用性和 SEO 非常不利。为什么不直接使用普通<a>链接?