脚本根据cli php的application.ini中的设置创建Zend_Db_Adapter

时间:2011-02-21 16:17:38

标签: php zend-framework command-line-interface zend-db zend-application

我使用Zend Framework 1.10进行Web应用程序,我想使用Zend_Db_Adapter(也许我的一些模型)用于cli php中将与cron一起使用的脚本。 你能告诉我如何根据application.ini中的设置创建Zend_Db_Adapter吗? 在我需要Zend_Db_Adapter的应用程序模型中,我在任何地方使用过这样的东西:

    $this->_db = Zend_Db_Table::getDefaultAdapter();

将它用于cli也会很好。 例如,我在这里创建了一个文件cron_job,$ resource为null。          set_include_path(implode(PATH_SEPARATOR,array(                 $ zendPath,                 get_include_path()             )));

// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH',
/*              realpath(dirname(__FILE__) . '/../application')*/
              '/var/application');

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV',
              (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV')
                                         : 'production'));

// Register autoloader
require_once($zendPath . '/Zend/Loader/Autoloader.php');
Zend_Loader_Autoloader::getInstance();

$application = new Zend_Application(
        APPLICATION_ENV,
        APPLICATION_PATH . '/configs/application.ini'
    );
$resource = $application->getBootstrap()->getPluginResource('db');  
var_dump($resource);

在application.ini中我有设置:

resources.db.adapter = PDO_MYSQL    
resources.db.params.host = localhost

resources.db.params.username = user    
resources.db.params.password = password

resources.db.params.unix_socket = "/var/run/mysqld/mysqld.sock"    
resources.db.params.dbname = db_name
resources.db.isDefaultTableAdapter = true

根据我的应用程序的application.ini创建Zend_Db_Adapter的最佳方法是什么,不要为cli脚本创建另一个配置? 我的Web应用程序的引导程序是这样的:

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    /**
     * Initilize Action helper in a broker
     */
    protected function _initActionHelpers()
    {

        Zend_Controller_Action_HelperBroker::addPrefix('Common_Helper');        
    }



    /**
     * Init plugins
     */
    protected function _initPlugins()
    {
        $fc = Zend_Controller_Front::getInstance();
        $fc->registerPlugin(new Plugin_AccessCheck());              
    }


    /**
     * Set transport for mail
     */
    protected function _initEmail()
    {

        //parameters to send mail
        $emailConfig = $this->getOption('email');

        //send parameters for sending email
        $transport = new Zend_Mail_Transport_Smtp($emailConfig['server'],
         $emailConfig);


        Zend_Mail::setDefaultTransport($transport);

        //object for sending mail
        $mailer = new Common_Mail();
        $mailer->setFrom($emailConfig['from_address'], $emailConfig['from_name']);  
        //congigure and store mailer for sending email      
        Zend_Registry::set('mailer', $mailer);          
    }


}

谢谢。

2 个答案:

答案 0 :(得分:0)

我认为你的脚本没有给你一个db,因为你需要首先引导数据库。

试试这个: $应用 - > getBootStrap() - >自举('分贝);

那么

$ resource = $ application-> getBootstrap() - > getPluginResource('db');


更一般地说:

**你可以从同一个Bootstrap文件中完成web应用程序和cli的东西,这样,你可以用类似的方式为两者启动事物。这意味着您可以将db设置处理到Bootstrap.php文件,并将该Bootstrap文件用于Web应用程序和您执行的任何cli操作。您可以使用引导机制的依赖性机制以多种灵活的方式引导,例如,一个用于Web,一个用于cli。**

在你的bootstrap中添加:

protected function _initTheDb
{
   //Following will automatically go to Zend_Application_Resource_Db,
   //if it can't find anything else named db to bootstrap
   $this->bootstrap('db');
   //do the above instead of the loader script 
   //which had: $resource = $application->getBootstrap()->getPluginResource('db'); 
   //Now setting up the db works for both cli and web,
   //if you add a _initCli() to your bootstrap.
}

扩展讨论:

假设你有像这样的Bootstrap.php文件

protected function _initX
protected function _initTheDb
protected function _initZ

WHERE _initTheDb和_initZ是你想在web和cli中做的事情,_initX是你不想在cli中做的事情。

为cli创建一个额外的_init:

protected function _initCli()
{
    $this->bootstrap('TheDb');
    $this->bootstrap('Z');
    //BUT NOT $this->bootstrap('X'); since that that does apply for CLI.
}

现在在您的cli loader脚本中,只需确保为cli启动。 (这将引导数据库部分以及您添加到_initCli的其他任何部分。)

$application->getBootStrap()->bootstrap('cli');

问题:您如何阻止Web引导过程引导'cli'部分,因为_initCli现在出现在您的Bootstrap中?

X仅受Web应用程序启动(位于Bootstrap文件的顶部)。 如果已经引导,则必须在Web环境中执行。 使用这些知识跳过引导cli部分:

protected function _initCli()
{
    if ($this->hasResource('X'))
    {
        //We know that we are boot-strapping for web.
        return;
    }

    //If we get here, we know that we are cli
    $this->bootstrap('TheDb');
    $this->bootstrap('Z');
}

答案 1 :(得分:0)

看起来很有效。我创建了init.php,我打算参与将用于cron的所有脚本。

<?php
// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', '/var/application');

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));


/** Zend_Application */
require_once 'Zend/Application.php';

// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);
$application->getBootStrap()->bootstrap('db');

看起来在包含这个文件之后我可以使用这样的东西:

$db = Zend_Db_Table::getDefaultAdapter();

看起来没有必要在application.ini中设置

resources.db.isDefaultTableAdapter = true

我认为在Zend Framework的代码中默认设置为true。