views:

7960

answers:

9

Hi

I am looking to register a reference to the main Database Adapter in the Registry during Bootstrapping so it can be used elsewhere in my site (specifically the Authorisation action).

I have implemented an ugly fix where i create a Database Table object and call the getAdapter() method on it and pass through that. However, this is a bad way of doing it and I would like it to be available via the registry.

Does anyone know how to do this? Any help or pointers in the right direction are appreciated!

Cheers Stuart

Ps. Im using Zend Framework 1.8.

+2  A: 

Check the zend-documentation at : 15.5.3.3. Storing a Database Adapter in the Registry

http://framework.zend.com/manual/en/zend.db.table.html

$db = Zend_Db::factory('PDO_MYSQL', $options);
Zend_Registry::set('my_db', $db);

// Later...

$table = new Bugs(array('db' => 'my_db'));

something like that you're looking for?

Edit:
to load your configuration from an ini-file, use:
parse_ini_file($inifile)

;configuration.ini
host = 127.0.0.1
user = username
password = blabla

;yourfile.php
$options = parse_ini_file('configuration.ini');

$db = Zend_Db::factory('PDO_MYSQL', $options);
Silfverstrom
That is what ive seen in docs and other sites but presumably the $options var holds username, password, dbName etc etc. But in my situation these are stored in the Application.ini file. Is there a way to use this file to populate the options? Thanks for the quick reply!
Stuart
Yeah, you can use parse_ini_file. check my edit
Silfverstrom
No. This is code repetition. What he means is how can you retrieve an instance of the default adapter without reading the config file again (which was done automatically in the Bootstrap class).
jamiei
ah, alright. mybad
Silfverstrom
Although I could very wrong about the OP intentions! Nice answer on Config File parsing though.
jamiei
Thanks very much for the help Silfverstrom!
Stuart
+1  A: 

I have a method in my bootstrap to add the adapter to the registry. I'd prefer a cleaner solution, but it works:

protected function _initRegistry(){

    $this->bootstrap('db');
    $db = $this->getResource('db');

    $db->setFetchMode(Zend_Db::FETCH_OBJ);

    Zend_Registry::set('db', $db);
}
David Caunt
+1  A: 

Here is what i do:

Inside the bootstrap:

define('CONFIG_FILE', '../config/general.ini');
define('APP_MODE', 'development');

Inside the Initializer:

 /**
 * Initialize data bases
 * 
 * @return void
 */
public function initDb ()
{
    $options = Zend_Registry::get('conf');
    $db = Zend_Db::factory($options->database);
    $db->query(new Zend_Db_Expr('SET NAMES utf8'));
    Zend_Registry::set('db', $db);
}

public function initConfig ()
{
    if (file_exists(CONFIG_FILE) && is_readable(CONFIG_FILE)) {
        $conf = new Zend_Config_Ini(CONFIG_FILE, APP_MODE);
        Zend_Registry::set('conf', $conf);
    } else {
        throw new Zend_Config_Exception('Unable to load config file');
    }
}

And finaly my config file looks like this:

[production]
database.adapter         = pdo_Mysql
database.params.host     = db.example.com
database.params.username = dbuser
database.params.password = secret
database.params.dbname   = dbname

; Overloaded configuration from production

[development : production]
database.params.host     = localhost
database.params.username = root
database.params.password =

Take a look at:

Boris Guéry
This is *not* the right way to do things! It is not necessary to load the config yourself in the Bootstrap, Zend_Application will do this automatically. Additionally, it has a resource for initialising the database. Simply specify the database in your application ini as per http://framework.zend.com/manual/en/zend.application.available-resources.html#zend.application.available-resources.db and the database will be initialised automatically
David Caunt
+2  A: 

Thanks for the replies. Ive decided to change the accepted answer and post the solution I finally used - which is insanely simple in the end!!

This is basically based on Dcaunt's comment...

In the bootstrap class..

protected function _initDb()
{
    $resource = $bootstrap->getPluginResource('db');

    $db = $resource->getDbAdapter();

    Zend_Registry::set("db", $db);
}

Then access that elsewhere with...

$dbAdapter = Zend_Registry::get("db");

Thanks for the help and hopefully this helps someone else.

Stuart
// While in bootstrap class, correct resource access is :$resource = $this->getPluginResource('db');
PulsarBlow
I've added my answer, which makes it even easier than this!
Andrew
+1  A: 

Your missing the best thing :)

If you use the Zend_Db_Table models (you should be) etc then you can set up a default adaptor - this way when you instantiate a model the DB connection it taken care off - this way you dont really need to save it in the registry or bother about connection before running a query through the model.

I do save it in the registry for later use if needed though - but I may remove this

protected function _initDB()
{
    // Check that the config contains the correct database array.
    if ($this->_config->db) {

        // Instantiate the DB factory
        $dbAdapter = Zend_Db::factory($this->_config->db);

        // Set the DB Table default adaptor for auto connection in the models
        Zend_Db_Table::setDefaultAdapter($dbAdapter);

        // Add the DB Adaptor to the registry if we need to call it outside of the modules.
        Zend_Registry::set('dbAdapter', $dbAdapter);
    }
}
Ian Warner
A: 

If you are using Zend Framework 1.8 just do something like this in your controller/action:

class CreateorderController extends Zend_Controller_Action
{
    public function testAction()
    {
        //more code
        $users_obj = new Default_Model_Users(); //this would load the model using the Default namespace
        //more code
    }
}

My Defaul_Model_Users class would look something like this:

<?php
/**
 * application/models/Users.php
 */
class Default_Model_Users extends Zend_Db_Table
{
    protected $_table;

    public function getTable()
    {
        if(null === $this->_table) {
            $this->_table = new Default_Model_DbTable_Users();
        }
        return $this->_table;
    }

    public function fetchAll()
    {
        $result = $this->getTable()->fetchAll();

        return $result;
    }
}

And the part of the model which "interacts" directly with the database tables is found inside DbTable directory will look like this:

<?php
/**
 * application/models/DbTable/Users.php
 */
class Default_Model_DbTable_Users extends Zend_Db_Table_Abstract
{
    /** Table name */
    protected $_name = 'users';

    public function init()
    {
        $this->_db->setFetchMode(Zend_Db::FETCH_OBJ);
    }
}

Then I would have the same application.ini generated by Zend Framework with this small addition:

resources.db.adapter               = "PDO_MYSQL"
resources.db.params.host           = "localhost"
resources.db.params.dbname         = "mydb"
resources.db.params.username       = "root"
resources.db.params.password       = "password"

That is how I did without without having to change the bootstrap files.

wenbert
+1  A: 

I didn't want to use the registry to store an object that I should be able to access, so I did a little digging. It turns out that the bootstrap is registered as the front controller parameter "bootstrap", which is accessible from any of your controllers as explained in this manual page for Zend_Application.

So in your controller classes you can get the db adapter that has been defined in your ini file like this:

$bootstrap = $this->getInvokeArg('bootstrap');
$resource = $bootstrap->getPluginResource('db');
$db = $resource->getDbAdapter();
Vishal Parpia
+8  A: 

If you're using Zend Framework 1.8+, and created your project with the command line tool, then it's as simple as registering your database settings in your application.ini config file.

resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "your.database.host"
resources.db.params.dbname = "database_name"
resources.db.params.username = "username"
resources.db.params.password = "password"
resources.db.isDefaultTableAdapter = true

If your database settings are preceded by resources.db you won't even need to do anything in your Bootstrap.php file because it will do it for you. Also, by setting the isDefaultTableAdapter setting to true, you can get an instance of your database adapter anywhere in your application.

$dbAdapter = Zend_Db_Table::getDefaultAdapter();
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
Andrew
A: 

My 2 cents...

How to grab the default DB Adapter:

From Bootstrap:

<?php    
$dbResource = $this->getPluginResource('db');
db = $dbResource->getDbAdapter();
var_dump($db);
?>

From a Controller there are two methods:

<?php
// Method 1
$bootstrap = $this->getInvokeArg('bootstrap');
$dbResource = $bootstrap->getPluginResource('db');
$dbAdapter = $dbResource->getDbAdapter();
var_dump($dbAdapter);

// Method 2
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
var_dump($dbAdapter);
?>
Julian