【问题标题】:Norwegian characters problem挪威语字符问题
【发布时间】:2010-01-01 22:08:06
【问题描述】:

我创建一个文件夹如下。

function create(){
if ($this->input->post('name')){
    ...
            ...
    $folder = $this->input->post('name');
    $folder = strtolower($folder);
    $forbidden = array(" ", "å", "ø", "æ", "Å", "Ø", "Æ");
    $folder = str_replace($forbidden, "_", $folder);
    $folder = 'images/'.$folder;
    $this->_create_path($folder);
            ...

但它不会用 _(在小节下)替换挪威字符

例如,Åtest øre 将创建一个名为 ã…test_ã¸re 的文件夹。

我有

<meta http-equiv="content-type" content="text/html; charset=utf-8" />

在标题中。

我在 XAMPP/Windows Vista 上使用 PHP/codeigniter。

我该如何解决这个问题?

【问题讨论】:

    标签: php


    【解决方案1】:

    您必须记住以正确的编码保存您的 PHP 文件。尝试将其保存为 ISO-8859-1 或 UTF8。还记得保存后重新打开它,以便您查看它是否正确保存或字符是否已转换。您的 IDE 可能会将它们转换为字节(奇怪的字符)而不在编辑器中显示更改。

    1. 写出文件时,另存为..
    2. filename.php 和它下面应该说编码。在这里您应该选择 ISO-8859-1(或 Latin-1)或 UTF8。如果您使用记事本,这将不是一个选项,您需要获取a proper editor
    3. 对该应用程序中的所有其他 PHP 文件应用相同的编码。我认为 ISO-8859-1 可以,但 UTF8 是一个很好的默认值,所以如果适用,请选择它。

    【讨论】:

    • 怎么做? lz能详细点吗?
    【解决方案2】:

    尝试显式设置 PHP 使用的内部编码:

    mb_internal_encoding('UTF-8');
    

    编辑:实际上,现在我考虑了一下...我建议使用strtr。它支持多字节字符并且会更快:

    $from  = ' 帿ŨÆ';
    $to    = '_______';
    $fixed = strtr($string, $from, $to);
    

    【讨论】:

    • mb_internal_encoding 放在脚本的最顶部。至于另一点,只需使用概念代替您现在拥有的即可。
    【解决方案3】:

    如果有的话,大多数普通字符串函数都不能很好地处理 Unicode 字符。

    在这种情况下,您可以使用正则表达式来解决这个问题。

    <?php
    $string = 'Åtest øre';
    $regexp = '/( |å|ø|æ)/iu';
    $replace_char = '_';
    
    echo preg_replace($regexp, $replace_char, $string)
    ?>
    

    返回:

    _test__re
    

    【讨论】:

    • åtest øtest 输出 Ã¥test_øtest 在 C 盘中。
    • 您是否将文件保存为 UTF8?这样做很重要,否则测试字符串可能不会被读取为 Unicode,这会弄乱正则表达式。 - 你可以看到我如何在我的测试服务器上使用它的例子 - atli.advefir.com/test/chars.php
    【解决方案4】:

    从 PHP 到 Windows 文件系统的接口是 C 标准库之一。 Windows 使用系统默认代码页将其 Unicode 文件系统命名方案映射到 PHP 的字节中。如果您在挪威,您的系统默认代码页可能是 1252 西欧,但这是一个部署细节,当您将其放到实时服务器上时,它可能会发生变化,而且这不是一件容易修复的事情。

    您的页面/网站编码是 UTF-8。不幸的是,虽然现代 Linux 服务器通常使用 UTF-8 作为其文件系统访问编码,但 Windows 不能,因为默认代码页从来不是 UTF-8。您可以使用 iconv 将 UTF-8 字符串转换为 cp1252;自然,所有不适合此代码页的字符都会丢失或损坏。另一种方法是让整个站点使用charset=iso-8859-1,它可以(在大多数情况下)存储在cp1252 中。不过,使用非 UTF-8 字符集有点倒退,当然,如果将其部署到使用不同默认代码页的机器上,它仍然会中断。

    出于这个原因和其他原因,文件名很难。您应该尽一切可能避免使用任意字符串生成文件名。您需要阻止更多字符以使字符串适合 Windows 上的文件名并避免目录遍历攻击。最好在文件系统上存储像123.jpeg 这样的 ID,如果你想让它出现在不同的字符串名称下,可以使用脚本访问或 URL 重写。

    如果您必须从任意字符串创建一个 Windows 友好的文件名,最简单的方法是执行类似于 slug 生成的操作:preg_replace away all 不适合的字符(Unicode 或其他)已知安全的,如`[A-Za-z0-9_-],检查结果是否为空并且不匹配bad filenames之一(如果是,请在前面加上下划线),最后添加扩展名。

    【讨论】:

      【解决方案5】:

      使用这个。

      $string = $this->input->post('name');
      $regexp = '/( |å|ø|æ|Å|Ø|Æ|Ã¥|ø|æ|Ã…|Ø|Æ)/iU';
      $replace_char = '_';
      

      【讨论】:

      • 这并不能真正解决编码问题,它只是有点......忽略了它。 - 更好的解决方案是正确编码文本并将其用作 Unicode。 - 还;此正则表达式中不需要 iU 修饰符。您手动包含大写和小写字母,U (un-greedy) 修饰符在此不起作用。 u (Unicode) 也不会,因为这假定文本是 ASCII)
      猜你喜欢
      • 2014-06-29
      • 1970-01-01
      • 2015-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多