如何在 URL 中将波斯字符串作为参数传递?

How to pass a Persian string as a argument in the URL?

我有一个 URL 像这样的模式:

www.example.com/ClassName/MethodName/Arg1/Arg2

还有我的 .htaccess 文件:

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ index.php?rt= [L,QSA]

ErrorDocument 404 /error404.html

这是我的路由系统:

if (empty($_GET['rt'])) {
    require_once('application/home.php');
} else {
    require_once('application/search.php');
    $url  =  rtrim ($_GET['rt'], '/');
    $url  =  explode('/', $url);

    $ClassName  =   array_shift($url);
    $MethodName =   array_shift($url);
    $Arg1       =   array_shift($url);
    $Arg2       =   array_shift($url);
}

现在有什么问题?好吧,一切都很好..!当我在 URL 中使用 م 时,每个 URLs 除了 的路由是完全正确的。 (م是波斯语字符)

例如

www.example.com/ClassName/Methodname/124/روز خوب      // it is fine
www.example.com/ClassName/Methodname/254/سلام بر       // it isn't fine
//                       because there is م ^ in the URL

所以当我在 URL 中使用 م 时,我将面临 404 Not Found 页面:


嗯,我不知道那个问题来自哪里..你知道吗?我该如何解决?是编码问题吗?或者什么?

注意: 我使用 Xampp v3.2.1 (apache)。


编辑: 如评论中所述,我添加了这两个示例:

<?php

$str = "www.example.com/ClassName/Methodname/124/روز خوب";
$url = explode('/', $str);
echo "<pre>";
print_r($url);

/*
Array
(
    [0] => www.example.com
    [1] => ClassName
    [2] => Methodname
    [3] => 124
    [4] => روز خوب
)
*/

两个:(这指向 404 Not Found)

<?php

$str = "www.example.com/ClassName/Methodname/254/سلام بر";
$url = explode('/', $str);
echo "<pre>";
print_r($url);

/*    
Array
(
    [0] => www.example.com
    [1] => ClassName
    [2] => Methodname
    [3] => 254
    [4] => سلام بر
)
*/

EDIT2: 根据一些测试,我找出了我的重写规则(index.php)应该调用的脚本,它甚至没有得到打电话。


EDIT3: 我在 Apache 上启用了重写日志记录,当我检查结果时,有一件有趣的事情:

(这两个样本与上面的例子没有关系)

工作路由示例:

[Sat Jan 02 22:17:00.276918 2016] [rewrite:trace3] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#28661a0/initial] [perdir C:/xampp/htdocs/myweb/] add path info postfix: C:/xampp/htdocs/myweb/islamic_sources -> C:/xampp/htdocs/myweb/islamic_sources/sahifeh_sajadiyeh/1580/\xd9\x86\xd8\xa8\xd9\x88\xd8\xaa, referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.276918 2016] [rewrite:trace3] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#28661a0/initial] [perdir C:/xampp/htdocs/myweb/] strip per-dir prefix: C:/xampp/htdocs/myweb/islamic_sources/sahifeh_sajadiyeh/1580/\xd9\x86\xd8\xa8\xd9\x88\xd8\xaa -> islamic_sources/sahifeh_sajadiyeh/1580/\xd9\x86\xd8\xa8\xd9\x88\xd8\xaa, referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.276918 2016] [rewrite:trace3] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#28661a0/initial] [perdir C:/xampp/htdocs/myweb/] applying pattern '^(.*)$' to uri 'islamic_sources/sahifeh_sajadiyeh/1580/\xd9\x86\xd8\xa8\xd9\x88\xd8\xaa', referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.276918 2016] [rewrite:trace4] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#28661a0/initial] [perdir C:/xampp/htdocs/myweb/] RewriteCond: input='C:/xampp/htdocs/myweb/islamic_sources' pattern='!-f' => matched, referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.276918 2016] [rewrite:trace4] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#28661a0/initial] [perdir C:/xampp/htdocs/myweb/] RewriteCond: input='C:/xampp/htdocs/myweb/islamic_sources' pattern='!-d' => matched, referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.276918 2016] [rewrite:trace2] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#28661a0/initial] [perdir C:/xampp/htdocs/myweb/] rewrite 'islamic_sources/sahifeh_sajadiyeh/1580/\xd9\x86\xd8\xa8\xd9\x88\xd8\xaa' -> 'index.php?rt=islamic_sources/sahifeh_sajadiyeh/1580/\xd9\x86\xd8\xa8\xd9\x88\xd8\xaa', referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.276918 2016] [rewrite:trace3] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#28661a0/initial] split uri=index.php?rt=islamic_sources/sahifeh_sajadiyeh/1580/\xd9\x86\xd8\xa8\xd9\x88\xd8\xaa -> uri=index.php, args=rt=islamic_sources/sahifeh_sajadiyeh/1580/\xd9\x86\xd8\xa8\xd9\x88\xd8\xaa, referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.277919 2016] [rewrite:trace3] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#28661a0/initial] [perdir C:/xampp/htdocs/myweb/] add per-dir prefix: index.php -> C:/xampp/htdocs/myweb/index.php, referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.277919 2016] [rewrite:trace2] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#28661a0/initial] [perdir C:/xampp/htdocs/myweb/] strip document_root prefix: C:/xampp/htdocs/myweb/index.php -> /myweb/index.php, referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.277919 2016] [rewrite:trace1] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#28661a0/initial] [perdir C:/xampp/htdocs/myweb/] internal redirect with /myweb/index.php [INTERNAL REDIRECT], referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.277919 2016] [rewrite:trace3] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#286c8b0/initial/redir#1] [perdir C:/xampp/htdocs/myweb/] strip per-dir prefix: C:/xampp/htdocs/myweb/index.php -> index.php, referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.277919 2016] [rewrite:trace3] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#286c8b0/initial/redir#1] [perdir C:/xampp/htdocs/myweb/] applying pattern '^(.*)$' to uri 'index.php', referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.277919 2016] [rewrite:trace4] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#286c8b0/initial/redir#1] [perdir C:/xampp/htdocs/myweb/] RewriteCond: input='C:/xampp/htdocs/myweb/index.php' pattern='!-f' => not-matched, referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.277919 2016] [rewrite:trace1] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#286c8b0/initial/redir#1] [perdir C:/xampp/htdocs/myweb/] pass through C:/xampp/htdocs/myweb/index.php, referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.470250 2016] [rewrite:trace3] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#286c1b8/initial] [perdir C:/xampp/htdocs/myweb/] strip per-dir prefix: C:/xampp/htdocs/myweb/fonts/taha/QuranTaha.woff -> fonts/taha/QuranTaha.woff, referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.470250 2016] [rewrite:trace3] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#286c1b8/initial] [perdir C:/xampp/htdocs/myweb/] applying pattern '^(.*)$' to uri 'fonts/taha/QuranTaha.woff', referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.470250 2016] [rewrite:trace4] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#286c1b8/initial] [perdir C:/xampp/htdocs/myweb/] RewriteCond: input='C:/xampp/htdocs/myweb/fonts/taha/QuranTaha.woff' pattern='!-f' => not-matched, referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85
[Sat Jan 02 22:17:00.470250 2016] [rewrite:trace1] [pid 3188:tid 1728] mod_rewrite.c(475): [client ::1:49413] ::1 - - [localhost/sid#c397b0][rid#286c1b8/initial] [perdir C:/xampp/htdocs/myweb/] pass through C:/xampp/htdocs/myweb/fonts/taha/QuranTaha.woff, referer: http://localhost/myweb/search?s=islamic_sources&q=%D8%B3%D9%84%D8%A7%D9%85

不工作(重定向到 404 未找到)示例:

[Sat Jan 02 22:07:09.734092 2016] [rewrite:trace3] [pid 3188:tid 1712] mod_rewrite.c(475): [client ::1:64955] ::1 - - [localhost/sid#c397b0][rid#83ec138/initial] [perdir C:/xampp/htdocs/myweb/] add path info postfix: C:/xampp/htdocs/myweb/islamic_sources -> C:/xampp/htdocs/myweb/islamic_sources/sahifeh_sajadiyeh/306/\xd9\x85\xd8\xa8
[Sat Jan 02 22:07:09.734092 2016] [rewrite:trace3] [pid 3188:tid 1712] mod_rewrite.c(475): [client ::1:64955] ::1 - - [localhost/sid#c397b0][rid#83ec138/initial] [perdir C:/xampp/htdocs/myweb/] strip per-dir prefix: C:/xampp/htdocs/myweb/islamic_sources/sahifeh_sajadiyeh/306/\xd9\x85\xd8\xa8 -> islamic_sources/sahifeh_sajadiyeh/306/\xd9\x85\xd8\xa8
[Sat Jan 02 22:07:09.734092 2016] [rewrite:trace3] [pid 3188:tid 1712] mod_rewrite.c(475): [client ::1:64955] ::1 - - [localhost/sid#c397b0][rid#83ec138/initial] [perdir C:/xampp/htdocs/myweb/] applying pattern '^(.*)$' to uri 'islamic_sources/sahifeh_sajadiyeh/306/\xd9\x85\xd8\xa8'
[Sat Jan 02 22:07:09.734092 2016] [rewrite:trace1] [pid 3188:tid 1712] mod_rewrite.c(475): [client ::1:64955] ::1 - - [localhost/sid#c397b0][rid#83ec138/initial] [perdir C:/xampp/htdocs/myweb/] pass through C:/xampp/htdocs/myweb/islamic_sources

有趣的一点:当路由正常时,波斯字符串将是这样的:(只是解码):

%D8%B3%D9%84%D8%A7%D9%85

但是当路由是404 not found时,波斯字符串会是这样的:

\xd9\x86\xd8\xa8\xd9\x88\xd8\xaa

似乎有两种不同的编码..

使用URL编码器:

String encodedURL = "www.example.com/ClassName/Methodname/254/" + URLEncoder.encode("Any text in any language", "utf-8");

UTF-8 当然是要使用的编码。

您可以在这里阅读更多内容:https://docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html

您可以试试这个可能效果更好的变体:

RewriteRule ^([\s\S]*)$ index.php?rt= [L,B,QSA]

这样做的变化是:

1:使用 [\s\S] 完全匹配任何字符,而不是 . 匹配除换行符以外的任何字符。

虽然您通常不希望换行符 (%0A) 出现在您的 URL 中,但我怀疑 Apache 的正则表达式匹配器将您的输入路径视为采用 ISO-8859-1 编码。

IRI 字符 U+0645 阿拉伯字母 Meem م UTF-8-URL-encodes 到 URI 序列 %D9%85,而字节 0xD9 在 ISO-8859-1 中是可以的, 0x85 解码为 U+0085 下一行 (NEL),这是一种不受欢迎的遗留控制字符,通常被视为换行符。因此,如果发生这种情况,表达式 .* 将不会匹配它。

说了这么多,这是相当理论化的,因为你的例子对我来说是有效的 as-is,在一个旧的 XAMPP 1.8.2 上,我一直在 WinXP 上闲逛。

2:使用[B]rewrite flag,确保参数中所有字节都以correctly-URL-encoded形式传递。

否则,在 Apache 通过 Windows 环境变量将查询字符串发送到 PHP 的情况下,non-ASCII 个字符会中断。 Windows 环境是 Unicode,因此 Apache 必须在写入时解码字节,PHP 必须在读取时再次编码,不幸的是这些编码不匹配。

Apache 使用 ISO-8859-1,PHP(通过 C stdlib)使用 ANSI 代码页,这取决于 Windows 安装的区域设置。在 Western 安装中,您获得代码页 1252,它接近 ISO-8859-1,因此只有一些字节是错误的(同样,这包括 م 中的 0x85);在具有其他 ANSI 代码页的其他语言环境中,所有 non-ASCII 字符都将大错特错。

这不一定适用于您,因为 XAMPP 使用 mod_php,不需要使用环境来传递字符串。但它会在其他托管环境中产生影响。在任何情况下,如果没有 [B],您会发现字符串中的 URL-special 个字符(与符号、加号、百分比)会破坏查询解析器。