【问题标题】:How to setup a Zend_Application with an application.ini and a user.ini如何使用 application.ini 和 user.ini 设置 Zend_Application
【发布时间】:2010-01-10 11:53:24
【问题描述】:

我正在使用 Zend_Application,但在我的 application.ini 中混合应用程序和用户配置感觉不对。

我的意思如下。例如,我的应用程序需要命名空间 MyApp_ 中的一些库类。所以在 application.ini 我把 autoloaderNamespaces[] = "MyApp_"。这是纯粹的应用程序配置,除了程序员之外没有人会改变这些。另一方面,我在那里放置了一个数据库配置,系统管理员会更改它。

我的想法是我会在 application.ini 和 user.ini 之间拆分选项,其中 user.ini 中的选项具有优先权(因此我可以在 application.ini 中定义标准值)。

这是个好主意吗?我怎样才能最好地实现这一点?我的想法是

  • 扩展 Zend_Application 以获取多个配置文件
  • 在加载 user.ini 的 Bootstrap 中创建一个 init 函数
  • 解析我的 index.php 中的配置文件并将它们传递给 Zend_Application(听起来很难看)

我该怎么办?我想要为未来准备的“最干净”的解决方案(较新的 ZF 版本,以及开发同一应用程序的其他开发人员)

【问题讨论】:

    标签: php zend-framework configuration zend-application


    【解决方案1】:

    我找到了这个问题的解决方案,它可能是框架版本 1.10 的新内容。创建 Zend Application 对象时,您可以在合并在一起的选项数组中传入 2 个配置文件路径:

    $application = new Zend_Application(
        APPLICATION_ENV,
        array(
            'config' => array(
                APPLICATION_PATH . '/configs/application.ini',
                APPLICATION_PATH . '/configs/user.ini'
            ),
        )
    );
    

    【讨论】:

    • 我在 ZF 1.8.4 中尝试过这个并得到 警告:pathinfo() 期望参数 1 是字符串,给定数组 (Zend/Application.php:341) ... Zend_Application_Exception:提供的配置文件无效;未知配置类型 (Zend/Application.php:362) :(
    【解决方案2】:

    你知道这会合并尽可能多的 inis 吗?

    在 application.ini 中

    [production]
    config[] = APPLICATION_PATH "/configs/dsn.ini"
    config[] = APPLICATION_PATH "/configs/error.ini"
    ...
    

    【讨论】:

    • 这是新的吗?还是只是没有记录?
    【解决方案3】:

    这没什么错,我也做了类似的事情。我建议使用你的第二个选择。我只有一个 _initConfig() 方法,它负责使用 Zend_Config_Ini 加载用户配置。我不会扩展 Zend_App,这似乎有点太多了。

    编辑:

    对于您的评论,您只需这样做:

    $this->bootstrap('config');
    

    因此,为确保在 DB 之前加载配置,您将拥有如下内容:

    protected function _initConfig()
    {
        $config = new Zend_Config_Ini('/path/to/user.ini');
        return $config;
    }
    
    protected function _initDb()
    {
        $this->bootstrap('config');
        $config = $this->getResource('Config');
    
        /* ... */
    }
    

    不需要使用 Zend_Registry,因为 Bootstrap _init 方法返回的任何内容都可以使用 getResource() 访问

    【讨论】:

    • 如何确保在所有其他 _init 方法之前调用 _initConfig?
    • 在我看来这很丑陋。在每个方法中添加对引导的“配置”的依赖不是很通用且容易出错(下一个从事该项目的开发人员可能不会注意到他必须将其添加到他的新 init 方法中。然后他将幸运的是,配置早先被引导了一段时间,直到有人重构并更改了 init 方法的名称/顺序,以及 bwam,一个不错的大错误)
    • 不管感觉如何,这就是 Zend_Application 处理依赖关系跟踪的方式。如果下一个开发人员遵循最佳实践,他不应该需要 $config 而不明确知道他需要配置。这个幻影开发者应该问自己,“我如何获得配置?我知道它已经加载了......”然后现有代码和 ZF 文档都很好地告诉他他可以使用 getResource()。
    • 此外,这个选项仍然比您的其他两个建议更好,因为它是 Zend_Application 的一种标准方式。如果您扩展 Zend_App 并添加其他功能,或者在 index.php 中执行一些复杂的配置合并巫毒,它将为您的应用程序定制,并且下一个开发人员可能从未见过。
    【解决方案4】:

    一个配置文件可以有 'config' 项,它引用另一个配置文件。 Zend_Application 将包含这个配置文件。包含的配置文件将具有优先权,并覆盖标准配置文件中已经定义的键。

    昨天在Zend Framework mailing list也开了个贴

    示例

    应用程序.ini:

    [production]
    config = APPLICATION_PATH "/configs/config.ini"
    resources.db.adapter = "Mysqli"
    resources.db.host = "localhost"
    

    config.ini:

    [production]
    resources.db.host = "mysql.server.com"
    resources.db.username = "myuser"
    

    公共/index.php:

    $application = new Zend_Application(
        APPLICATION_ENV,
        APPLICATION_PATH . '/configs/application.ini'
    );
    

    【讨论】:

    • 谢谢。就我而言,config.ini 中的值似乎并不优先于 application.ini 中的值。
    【解决方案5】:

    在类似的场景中,我看到可以在实例化应用程序时以编程方式提供特定于应用程序的参数。这有助于在 config.ini 中放置与配置相关的参数

    我实际上是这样做的:

    在 index.php 中启动应用程序

         $application = new Zend_Application(APPLICATION_ENV, array(
                    'resources' => array(
                       'FrontController' => array(
                           'controllerDirectory' => APPLICATION_PATH . '/main/controllers',
                        ),
                    'layout' => array(
                        'layoutpath' => APPLICATION_PATH . "/layouts/scripts"
                        ),
                    ),
                ));
    
    and then inside the bootstrap parse the config.ini inidependently
    
        protected function _initConfigFile() {
            try {
                $configuration = new Zend_Config_Ini(
                    APPLICATION_PATH . '/config/app.ini',
                    APPLICATION_ENV );
                $registry->configuration = $configuration;
            } catch (Zend_Exception $zExp) {
                echo "Could not read application ini file (app.ini). "
                    . " Please check that it exists and has the appropriate structure.\n";
                echo("\n");
                var_dump($zExp);
                exit(1);
            }
        }
    

    在引导程序中

    【讨论】:

    • 如何做到这一点? Zend_Application 需要一个 php-array 或一个 config.ini,而不是两者,不是吗?
    【解决方案6】:

    您可以通过在其他引导方法(需要配置对象)中指定如下内容来确保在其他引导方法之前调用 _initConfig() 引导方法:

    $this->bootstrap('config');
    

    更完整的示例(Bootstrap 类的上下文):

    protected function _initConfig() {
        $config = new Zend_Config_Ini('[filename]');
        Zend_Registry::set('config',$config);
    }
    
    protected function _initSomething() {
        $this->bootstrap('config');
        $config = Zend_Registry::get('config');
        // you can now do whatever you like with the $config object
    }
    

    更新:

    正如现在在其他答案中提到的,如果仅在引导程序中需要配置,我会说使用 $this->getResource('Config') 方法。我使用注册表,以便可以在我的应用程序的其他部分轻松访问配置。

    【讨论】:

    • 没有必要使用 Zend_Registry,因为只需返回 $config 就可以通过引导程序访问它。
    • 是的,但我喜欢将我的配置保存在注册表中,以便以后执行时需要它的任何其他人都可以访问它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多