【问题标题】:PHP character encoding (Umlaute in MediaWiki)PHP 字符编码(MediaWiki 中的变音符号)
【发布时间】:2012-12-28 22:23:37
【问题描述】:

我在 Windows 7 下的本地计算机上运行 Apache/PHP/MySQL 服务器 (xampp)。在那里我安装了 MediaWiki 软件以及许多扩展。我的目标是从维基百科下载一些页面并在本地显示。一切运行良好,除了一个大问题:

德语维基百科中的图像文件的文件名中包含德语变音符号(ä、ö、ü)。这无法更改,因为文章链接到带有元音变音的名称。

当我尝试导入这些图像(通过maintenance/importImages.php 脚本)时,它不起作用。我追踪了代码并找出了原因:

当 PHP 扫描目录中的文件时,它会将文件名读取为 ANSI 字符串。 MediaWiki 内部要求所​​有字符串都是 utf-8。因此,文件名中的元音变音符号被解释为(不存在的)unicode 字符的一部分,这会破坏脚本。

如果我在脚本中手动添加对utf8_encode() 的调用,则名称很好,并且已正确添加到数据库中。但是实际写入“images”目录的文件有一个损坏的名称 - 两个特殊字符而不是变音符号。原因是 PHP 脚本将 utf-8 字符串发送到文件系统函数(“copy”,...),但操作系统需要 ANSI 字符串。我可以在每个文件系统调用之前手动添加对utf8_decode() 的调用,但是有成千上万个!

再次简而言之:操作系统在 ANSI 中运行(这对于 Windows 来说不容易更改),PHP 服务器内的 MediaWiki 软件在 utf-8 中运行(也无法更改)。有没有办法在文件名字符串每次进出 PHP 服务器时自动编码/解码?

我已经在使用mb_internal_encoding()mb_http_output(),但这并没有改变任何东西:MediaWiki 使用仅适用于 utf-8 字符串的硬编码函数。

【问题讨论】:

  • 您可以在哪里进行更改?示例:您能否将 utf-8 变音符号更改为字母 a、o 或 u,并且仍然可以创建有效的解决方案?
  • 也许这里的答案可能有用-> stackoverflow.com/questions/1089966/…
  • 是的,我解决了。 Apache RewriteRule 的想法很棒。无需更改 PHP 代码。我在我的 httpd.conf 中添加了以下重写规则(仅适用于 Umlaut:ä)RewriteEngine On RewriteRule ^(/?mywiki\/images/.*/[^/]*?)\xC3\xA4([^/]* ?\xC3\xA4[^/]*)$ $1\%C3\%83\%C2\%A4$2 [NE,N] RewriteRule ^(/?mywiki\/images/.*/[^/]*? )\xC3\xA4([^/\xC3\xA4]*)$ $1\%C3\%83\%C2\%A4$2 [NE,R=301] 它所做的只是将每个 'ä' 替换为 ' %C3%83%C2%A4' 在指向 /mywiki/images/* 的 URL 中。因此 MediaWiki 可以访问 Windows 文件系统中名称损坏的文件。

标签: php windows encoding mediawiki


【解决方案1】:

您需要在导入之前重命名文件系统上的所有文件,以便它们与数据库中的数据匹配。

只要确保文件名的 UTF-8 编码二进制序列命中文件系统时,就可以找到文件。

$fileANSI; // you have this
$fileUTF8 = ut8_encode($fileANSI); // you do this already
// insert etc, when MW is ready do:
rename($fileANSI, $fileUTF8);

因此,您需要将每个文件从当前名称重命名为命中时的二进制序列。

对于您的网络服务器,您可能还需要引入一个重写规则来处理传入的 HTTP 请求,因为网络服务器可能使用 PHP 本身以外的其他文件系统处理。

还要检查文件系统的系统配置,使用哪个代码页。这可能会有所不同。

【讨论】:

  • 我已经在考虑了。在 MediaWiki 内部,这个解决方案看起来一切正常。在 Windows 中,文件名包含不可读的字符,但这很好。但问题仍然存在:MediaWiki 创建指向文件的链接没有特殊字符,而是使用元音变音符号(因为浏览器理解 uft-8)。浏览器找不到那个文件,因为它正在寻找带有元音变音的文件,但是在文件系统上,只有带有奇怪符号的文件。还有什么提示吗?
  • 好吧,也许我可以用 Apache 重写规则来解决这个问题。我没有创建重写规则的经验。有人可以告诉我在重写规则中我需要什么来将 Umlaute 转换为 utf-8 中的两个特殊字符吗?
  • @user1934614:您捕获这些 URL,然后它们应该适用于 PHP 的文件系统函数,然后您应该能够 readfile 那些。或者,您需要以重定向的形式提供二进制序列,但出于调试目的,我会首先获得 readfile 变体。
猜你喜欢
  • 2012-01-31
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 2012-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-08
相关资源
最近更新 更多