script create Zend_Db_Adapter based on settings in application.ini for cli php

1k views Asked by At

I use Zend Framework 1.10 for web application and I'd like to use Zend_Db_Adapter (and maybe some of my models) for script in cli php that will be used with cron. Could you please tell how to create Zend_Db_Adapter based on settings in application.ini? In the model of application when I needed Zend_Db_Adapter I used everywhere something like this:

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

It would be good to use it for cli too. For example I created a file cron_job and $resource is null here. 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);

In application.ini I have settings:

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

What is the best way to make create Zend_Db_Adapter here base on application.ini of my application not to create another configuration for cli scripts? my bootstrap for web application is something like that:

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);          
    }


}

Thank you.

2

There are 2 answers

0
Oleg On BEST ANSWER

It looks like it works. I created init.php that I plan to inlcude in all scripts that will be used for 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');

It looks like after including of this file I can use something like this:

$db = Zend_Db_Table::getDefaultAdapter();

It looks like it's not necessary to in application.ini to set

resources.db.isDefaultTableAdapter = true

I think this is set true by default in the code of Zend Framework.

20
DWright On

I think your script is not giving you back a db, because you need to first bootstrap the db.

Try this: $application->getBootStrap()->bootstrap('db);

THEN do

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


On a more general note:

** you can do both web application stuff and cli stuff off of the same Bootstrap file, that way, you can have things bootstrapped in similar ways for both. This means that you would move dealing with the db setup to your Bootstrap.php file and use that Bootstrap file for both your web application and any cli stuff you do. You can use the dependency mechanism of the bootstrap mechanism to bootstrap in multiple, flexible ways, say, one for web, one for cli.**

In your bootstrap add this:

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.
}

Extended discussion:

Let's say you have Bootstrap.php file like this

protected function _initX
protected function _initTheDb
protected function _initZ

WHERE _initTheDb and _initZ are things you want to do both in web and cli, and _initX is something you don't want to do in cli.

create an additional _init for cli:

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

Now in your cli loader script, just make sure you boot-strap for the cli. (This will bootstrap the db section and whatever other sections you've added to _initCli).

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

Question: How do you prevent the web bootstrap process from also bootstrapping the 'cli' section, since _initCli is now present in your Bootstrap?

X only gets boot-strapped by the web application (at the top of the Bootstrap file). If it has been bootstrapped, you must be executing in the web environment. Use this knowledge to skip bootstrapping the cli section:

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');
}