【问题标题】:modules and language in codeigniter 4codeigniter 4中的模块和语言
【发布时间】:2020-07-09 13:26:14
【问题描述】:

假设文件结构如下

  • 应用程序
    • 配置 .....直到
    • 模块
      • Admin(在 Admin 文件夹内将是控制器和视图模型配置和语言)
        • 语言
          • zh
            • home.php
          • ar
            • home.php

所以,我的问题是当我想使用 lang 函数时,我会输入文件名,然后输入要检索的内容的键。因此,假设我这样调用函数 lang('home.title') home 表示文件名,title 表示键。但它不会从文件中检索任何内容并返回 home.title 所以我需要把我所有的翻译文件 在一个文件夹中,哪个是 app 文件夹中的那个?或者有什么解决办法?

【问题讨论】:

  • 如果你能告诉我们我的回答是否有帮助会很好
  • 哦,我刚刚注意到有人回复了我的问题。我很感谢你回答我的问题。我已经跳过了这个问题,我试图找到任何解决方案但没有找到任何东西。所以我只是跳过它。我不确定您的答案是否是解决方案,但我真的很感谢您回答这个问题。谢谢

标签: php codeigniter codeigniter-4


【解决方案1】:

我目前正在测试这个框架,也想构建一个模块化的类似 HMVC 的应用程序。我像你一样构建它并偶然发现了同样的问题。看了下核心代码,发现了问题(文末有说明)。

假设命名空间为例如管理模块中的控制器看起来像“\App\Modules\Admin\Controllers”,而 Autoload 配置类中的 $psr4 变量看起来像

public $psr4 = [
    APP_NAMESPACE => APPPATH,
    'Config'      => APPPATH . 'Config',
    'App'      => APPPATH, // This might be missing
];

您只需要包含模块的命名空间和路径:

public $psr4 = [
    APP_NAMESPACE => APPPATH,
    'Config'      => APPPATH . 'Config',
    'App'      => APPPATH, // This might be missing
    'App\Modules\Admin'      => APPPATH . 'Modules' . DIRECTORY_SEPARATOR . 'Admin',
];

如果您不想手动添加所有路径,您可以定义 Autoload 类的构造函数,如下所示:

public function __construct()
{
    parent::__construct();

    $dir = new DirectoryIterator(APPPATH . 'Modules');
    foreach ($dir as $fileinfo) {
        if ($fileinfo->isDir() && !$fileinfo->isDot()) {
            $this->psr4['App\Modules\\' . $fileinfo->getFilename()] = $fileinfo->getRealPath();
        }
    }
}

问题

问题在于,在解析过程中,语言文件的路径有些硬编码,稍后将附加到自动加载器已知的路径之一(例如 $psr4 中的那些元素):

$path = "Language/{$locale}/{$file}.php"; // system\Language\Language.php line 314
...
$namespace['path'] . $path // system\Autoloader\FileLocator.php line 248

【讨论】:

    【解决方案2】:

    不确定是否还有人感兴趣,但我通过调试 CodeIgniter 4 的一些类解决了这个问题。主要是BaseService::locatorFileLocator::search

    我注意到 CodeIgniter 正在寻找在其前面添加命名空间的语言路径,并循环遍历所有自动加载的目录和命名空间。

    为了清楚起见,这是一个示例

    /var/www/html/app/Config/Helpers/url_helper.php
    /var/www/html/modules/admin/Helpers/url_helper.php
    /var/www/html/modules/install/Helpers/url_helper.php
    /var/www/html/modules/lobby/Helpers/url_helper.php
    /var/www/html/system/Helpers/url_helper.php
    /var/www/html/app/Config/Registrar.php
    /var/www/html/app/Config/Config/Registrar.php
    /var/www/html/modules/admin/Config/Registrar.php
    /var/www/html/modules/install/Config/Registrar.php
    /var/www/html/modules/lobby/Config/Registrar.php
    /var/www/html/system/Config/Registrar.php
    /var/www/html/app/Config/Events.php
    /var/www/html/app/Config/Config/Events.php
    /var/www/html/modules/admin/Config/Events.php
    /var/www/html/modules/install/Config/Events.php
    /var/www/html/modules/lobby/Config/Events.php
    /var/www/html/system/Config/Events.php
    /var/www/html/app/Config/Routes.php
    /var/www/html/app/Config/Config/Routes.php
    /var/www/html/modules/admin/Config/Routes.php
    /var/www/html/modules/install/Config/Routes.php
    /var/www/html/modules/lobby/Config/Routes.php
    /var/www/html/system/Config/Routes.php
    

    一旦我理解了正确的程序,我就能够正确地修改我的 app/Config/Autoload.php 文件。

    这是它的样子

    public $psr4 = [
        APP_NAMESPACE => APPPATH, // For custom app namespace
        'Config' => APPPATH . 'Config',
        'Modules\Admin' => ROOTPATH . 'modules/admin',
        'Modules\Game' => ROOTPATH . 'modules/install',
        'Modules\Lobby' => ROOTPATH . 'modules/lobby',
    ];
    

    在我这样做之后,将以下 URL 添加到上面的列表中

    /var/www/html/app/Language/en/home/home_lang.php
    /var/www/html/app/Config/Language/en/home/home_lang.php
    /var/www/html/modules/admin/Language/en/home/home_lang.php
    /var/www/html/modules/install/Language/en/home/home_lang.php
    /var/www/html/modules/lobby/Language/en/home/home_lang.php
    /var/www/html/system/Language/en/home/home_lang.php
    

    我没有进一步探索,所以我不知道为什么 CodeIgniter 不考虑这样的事情:

    public $psr4 = [
        APP_NAMESPACE => APPPATH, // For custom app namespace
        'Config' => APPPATH . 'Config',
        'Modules' => ROOTPATH . 'modules',
    ];
    

    我原以为框架会探索其中的所有目录,但我猜它仅限于向下一层。

    最后,这是我的目录结构:

    • 应用程序
    • 公开
    • 系统
    • 可写
    • 模块
      • 管理员
        • 控制器
        • 语言
          • zh
      • 安装
        • 控制器
        • 语言
          • zh
      • 大厅
        • 控制器
        • 语言
          • zh

    所以我的建议有两点:

    • 按照 CI 文档的建议,将您的模块放在 app 文件夹之外。
    • 明确告诉 CI 你的模块在哪里。

    【讨论】:

    • 感谢您的贡献。这是有益的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    • 2021-06-16
    • 1970-01-01
    • 2016-10-18
    • 2014-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多