【问题标题】:How Does the Zend Application / Bootstrapping Work?Zend 应用程序/引导程序如何工作?
【发布时间】:2010-01-26 09:44:00
【问题描述】:

关于 Zend Framework 1.9 基础的几个问题。

  1. 我遵循了快速入门指南,基本上,引导涉及到,

    一个。来自 index.php:

    $ZEND_FRAMEWORK_LIB_PATH = '/appl/ZendFramework-1.9.7/library';
    defined('APPLICATION_PATH') || define('APPLICATION_PATH', (realpath(dirname(__FILE__) . '/../application')));
    defined('APPLICATION_ENV') || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));
    set_include_path(implode(PATH_SEPARATOR, array((dirname(dirname(__FILE__)) . '/library'), $ZEND_FRAMEWORK_LIB_PATH, get_include_path(),)));
    require_once 'Zend/Application.php';
    $application = new Zend_Application(APPLICATION_ENV, (APPLICATION_PATH . '/configs/application.ini'));
    $application->bootstrap()->run();
    

    b.然后在 Bootstrap.php 中,我有

    protected function _initAutoload()
    {
        $autoloader = new Zend_Application_Module_Autoloader(array("namespace" => "Default_", "basePath" => dirname(__FILE__),));
        return $autoloader;
    }
    
    protected function _initDoctype()
    {
        $this->bootstrap("view");
        $view = $this->getResource("view");
        $view->doctype("XHTML1_STRICT");
    }
    
  2. 首先,有几件事我不明白:

    一个。如果用户不是通过默认的 index.php 访问站点,这是否意味着引导(实际上,index.php 中的所有代码,包括环境设置等,都将被绕过?)

    b.没有明确调用 Bootstrap 的 _initAutoload()_initDoctype() 方法的地方。那么这些方法是什么时候隐式调用的呢?

    c。由于在 index.php 中,我已经将配置文件 '/configs/application.ini'“传递”到 Zend_Application 构造函数,有没有办法在其他地方检索配置条目?

  3. 在我的应用程序中,我必须使用不同的数据库(所以我不能只使用resources.db.*)。所以在同一个 application.ini 文件中,我有,例如

    custdb.adapter = "PDO_MYSQL"
    custdb.params.host = "localhost"
    custdb.params.username = "username"
    custdb.params.password = "password"
    custdb.params.dbname = "custdb"
    

    管理数据库适配器的最佳做法是什么?

    一个。是否可以(并且应该)在 index.php 或 Bootstrap.php 中创建数据库适配器,并在需要时(以及如何)在其他地方检索它?

    b.或者是否可以(并且应该)只在其他地方检索配置条目(如何?)并在需要时实例化 DB 适配器?

谢谢!

【问题讨论】:

    标签: php zend-framework


    【解决方案1】:

    这里有几个答案。

    2a。所有请求都重定向到 index.php。这是通过 mod_rewrite 完成的,并在 .htaccess 文件中指定。

    2b。引导程序调用以_init 为前缀的任何方法。见Zend Framework - Theory of Operation

    2c。是的。 Zend::Config。您可以在Zend::Registry 中存储一个实例以便于访问。例如:

    $config = new Zend_Config((APPLICATION_PATH . '/configs/application.ini')); 
    $application = new Zend_Application(APPLICATION_ENV, $config);
    Zend_Registry::set('config', $config);
    

    查看 API 参考以查看这两个类的构造函数。

    我认为快速入门没有那么有用。我建议买一本书。我喜欢 Keith Pope 的“Zend Framework 1.8 Web 应用程序开发”。

    【讨论】:

    • 感谢您的回答! 2b。不幸的是,操作理论让我更加困惑。在这种情况下,它谈到了 $bootstrap->bootstrap('foo'); $bootstrap->bootstrap(array('foo', 'bar')); $bootstrap->bootstrap();但这些都不在 index.php 中。 (除非 $application->bootstrap()->run(); 和 $bootstrap->bootstrap() 一样吗?) 2c.由于我已经将配置文件名传递给 Zend_Application 构造函数,有没有办法从 $application 检索 Zend_Config 实例(放入注册表)而不是在同一个 .ini 文件上实例化一个新的 Zend_Config_Ini?
    • 哦,另一件事。正如您所说,每个请求都被重定向到 index.php。这是否意味着那里的任何代码(读取配置、实例化 Zend_Application、调用 $bootstrap.run())都会一遍又一遍地发生?
    • 是的。整个应用程序都被引导并随每个请求一起运行。 HTTP 是一个无状态协议,唯一跨请求持久化的是 $_SESSION。如果您担心性能,我强烈建议您实现页面缓存,它可以在不启动完整应用程序的情况下提供页面。
    • 谢谢,好的,如果应用程序在每次请求时都被引导,那将很有意义。
    【解决方案2】:

    为了回答问题 3,ZF 使用 Application Resource Plugin Zend_Application_Resource_Db 提取配置并创建数据库适配器实例。

    如果您需要多个数据库是环境问题,您可以轻松地在 application.ini 文件中命名您的数据库参数。

    [production]
    resources.db.adapter = PDO_MYSQL
    resources.db.params.host = localhost
    resources.db.params.username = user
    resources.db.params.password = pass
    resources.db.params.dbname = production_db
    
    [staging : production]
    resources.db.params.dbname = staging_db
    
    [development : production]
    resources.db.params.dbname = development_db
    

    在此示例中,我们在 [production] 部分设置公共信息,并为我们的暂存和开发环境覆盖它。应用哪个配置由应用的.htaccess中的环境变量控制

    如果您需要在单个应用程序中访问多个数据库,那么我建议您使用自己的应用程序资源插件,并创建某种结构来容纳多个连接。

    这并不像看起来那么困难。阅读here 并创建Zend_Application_Resource_ResourceAbstract 的子类。使用这个类,你可以很容易地在你的配置文件中获取resources.*

    $this->getBootstrap()-getResource('mydb')`
    

    然后您将可以通过引导对象访问您的插件:

    $bootstrap->getPluginResource('mydb')
    

    希望对您有所帮助。

    编辑:我忘了提一下,如果你有一个资源插件作为你的 application.ini 的一部分,Zend_Application 引导程序会自动知道将它作为引导过程的一部分,所以你不需要定义任何 @引导文件中的 987654330@ 方法。就是这么神奇。

    另外,就存储适配器实例而言,我可能只是使用 Zend_Registry。

    【讨论】:

    • 您好,感谢您的回复! 1.关于子类化资源,我看到的是例如resources.db “映射到” Zend_Application_Resource_Db。如果我自己写,例如Custom_Application_Resource_MultiDb,并添加配置resources.multidb.*,我如何将resources.multidb“映射”到Custom_Application_Resource_MultiDb? 2. 我还是有点迷茫。现在我看到可以从 $bootstrap 获得各种东西。但是,由于没有单例实例 getter 函数,如何首先获得 $bootstrap 。我是否将 $bootstrap 放在 Zend_Registry 中?
    【解决方案3】:

    感谢您的所有回复!它确实帮助我理解了 ZF 的概念。

    我也浏览了参考资料和源代码以获得更深入的理解,这就是我采用的:

    在我的 application.ini 中我有:

    custom.db.customers.adapter = "PDO_MYSQL"
    custom.db.customers.params.host = "localhost"
    custom.db.customers.params.username = "username"
    custom.db.customers.params.password = "password"
    custom.db.customers.params.dbname = "custdb"
    

    然后,在我的 Bootstrap.php 中有:

    protected function _initCustomDbCustomers()
    {
        $config = $this->getOptions();
        $cfgCustom = $config['custom'];
        if (null != $cfgCustom)
        {
            $cfgCustomDb = $cfgCustom['db'];
            if (null != $cfgCustomDb)
            {
                $cfgCustomDbCustomers = $cfgCustom['customers'];
                if (null != $cfgCustomDbCustomers)
                {
                    $resrcCustomDbCustomers = new Zend_Application_Resource_Db($cfgCustomDbCustomers);
                    return $resrcCustomDbCustomers
                }
            }
        }
    }
    

    当然,在我的 index.php 中,我调用:

    $application->bootstrap();
    $application->run();
    

    然后,在我需要获取数据库适配器的控制器中,我这样做:

    $bootstrap = $this->getInvokeArg('bootstrap');
    $resrcCustomDbCustomers = $bootstrap->getResource('customDbCustomers');
    $adpCustomDbCustomers = $resrcCustomDbCustomers->getDbAdapter();
    // Do Stuffs With DB Adapter
    

    这是一种好/坏的做事方式吗?有什么我应该注意的陷阱吗?

    谢谢!

    【讨论】:

    • 这是一个很好的讨论,但这应该是一个单独的线程,或者您应该编辑您的原始帖子,以便更好地回答。
    • 如果您还有其他问题,请点击 按钮进行提问。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 2013-04-25
    相关资源
    最近更新 更多