【问题标题】:Yii2: How to force using fallback MessageFormatter method?Yii2:如何强制使用后备 MessageFormatter 方法?
【发布时间】:2018-02-07 20:48:58
【问题描述】:

我的网站有一个托管服务提供商,它在服务器上提供 MessageFormatter 类(Linux,PHP 7.0.27),但它是一个旧的 ICU 版本(4.2.1),不支持我的消息 {number,plural,=0{# available} =1{# available} other{# available}} 和给出错误:

消息模式无效:构造函数失败

msgfmt_create:消息格式化程序创建失败:U_ILLEGAL_CHARACTER

...因为 =1=2 符号。

我无法对服务器进行更改,如何强制使用 Yii2 提供的回退方法,效果很好?

【问题讨论】:

  • 您是否安装了php_intl 扩展程序?
  • @MuhammadOmerAslam 是的,这就是问题所在。如果只是没有安装旧版本,则不会有问题,因为会自动使用回退方法。
  • 至少应该安装ICU 4.8,并且有一个需求检查脚本,将/requirements.php复制到/web/requirements.php,然后使用浏览器通过http://localhost/requirements.php或终端php requirements.php访问它看看它打印了什么。并且应该有更多关于错误日志的信息。关于这个错误。
  • 您在哪个环境中拥有ICU < 4.8?甚至 Debian oldoldstable (wheezy) 也有 ICU 4.8
  • @MuhammadOmerAslam 看起来我的托管服务提供商正在使用 Red Hat 4.4.7(从 2012 年左右开始?),Linux 版本 2.6.32。 requirements.php 也这么说 - ICU 太旧,ICU 数据丢失。而且他们不想在服务器上进行任何更改。

标签: php yii2 internationalization


【解决方案1】:

您可以尝试这种 hacky 方法。

yii\i18n\MessageFormatter 代码复制到一个新文件。将其命名为 MessageFormatter.php 并放置在您的应用程序中的某个位置(但不在 vendor 文件夹中)。

在这个新文件中,将format() 方法更改为:

public function format($pattern, $params, $language)
{
    $this->_errorCode = 0;
    $this->_errorMessage = '';

    if ($params === []) {
        return $pattern;
    }

    return $this->fallbackFormat($pattern, $params, $language);
}

不要更改任何其他内容(包括命名空间)。

现在让我们使用 Yii 映射。

在您的应用程序中找到一个位置,您可以将每次运行的代码放在bootstrapping phase 中。如果您正在使用类似“高级模板”的项目,则可以使用common/config/bootstrap.php

在此处添加这一行:

Yii::$classMap['yii\i18n\MessageFormatter'] = 'path/to/your/MessageFormatter.php';

显然将路径更改为您选择的路径。现在 Yii 自动加载器将从你的文件而不是原始的 Yii 供应商文件夹中加载这个类(如指南的Class Autoloading 部分所述)。

在修改后的文件MessageFormatter 方法中从未检查过intl 库的存在,因此默认使用回退。

这个技巧的缺点是每次更改原始 Yii 文件时都需要手动更新文件(因此几乎每次升级 Yii 版本时)。


另一种方法是在您的应用程序中配置 I18N 组件以使用您的自定义 MessageFormatter,您可以在其中扩展原始文件并在不修改类映射的情况下覆盖内部的 format() 方法。

【讨论】:

  • 是的,您可以这样做,但这种方法的另一个缺点是回退不适用于非默认语言,并且与intl 相比,其功能非常有限。否则,OP 必须更改托管或说服他们更新。
  • OP 要求强制回退,所以我给了他答案。
  • 是的,我只是想补充一下答案。以便 OP 在继续前进之前可以了解所有方面。
  • 谢谢,这甚至让我找到了几种可能的解决方案!
猜你喜欢
  • 2015-02-15
  • 1970-01-01
  • 1970-01-01
  • 2023-02-03
  • 1970-01-01
  • 2012-06-10
  • 2017-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多