views:

685

answers:

3

I have here a medium sized intranet site which is written entirely in Zend FW. The database for the intranet is located on another server. Now I need to extend the intranet with some new functionality. In order to do this I need to connect to another database on the same server (and same DBMS).

The question is now: What is the best way to do this? Should I create a new Zend_Config object and a new Zend_Db_Adapter? Or should I use the existing one and try with the "use otherdbname;" statement to connect within the same session to the new database?

Or is there an even better way to do it?

+4  A: 

One option is to register 2 database handles from within your bootstrap.php, one for each connection. E.g.:

$parameters = array(
                    'host'     => 'xx.xxx.xxx.xxx',
                    'username' => 'test',
                    'password' => 'test',
                    'dbname'   => 'test'
                   );
try {
    $db = Zend_Db::factory('Pdo_Mysql', $parameters);
    $db->getConnection();
} catch (Zend_Db_Adapter_Exception $e) {
    echo $e->getMessage();
    die('Could not connect to database.');
} catch (Zend_Exception $e) {
    echo $e->getMessage();
    die('Could not connect to database.');
}
Zend_Registry::set('db', $db);

$parameters = array(
                    'host'     => 'xx.xxx.xxx.xxx',
                    'username' => 'test',
                    'password' => 'test',
                    'dbname'   => 'test'
                   );
try {
    $db = Zend_Db::factory('Pdo_Mysql', $parameters);
    $db->getConnection();
} catch (Zend_Db_Adapter_Exception $e) {
    echo $e->getMessage();
    die('Could not connect to database.');
} catch (Zend_Exception $e) {
    echo $e->getMessage();
    die('Could not connect to database.');
}
Zend_Registry::set('db2', $db);

In your controllers (e.g.):

public function init()
{
     $this->db = Zend_Registry::get('db');
     $this->db2 = Zend_Registry::get('db2');
}

public function fooAction()
{
    $data = $this->db2->fetchAll('select foo from blah');
    ...
}
karim79
This would be a solution. But then I would not be using Zend_Db_Table. I would have to be able to choose the Zend_Db_Adapter within Zend_Db_Table. But your answer already helped.
Raffael Luthiger
@Raffael Luthiger - I made no mention of Zend_Db_Table, I don't see where that fits in to my answer :)
karim79
@karim79: I thinks he's talking about the default database adapter for Zend_Db_Table. If he uses two differen adapters he'll have to associate his table-classes with the correct db-adapter respectively. That's why I proposed using the fully qualified table-name syntax.
Stefan Gehrig
@Stefan Gehrig - ah, I get it now. I'm not familiar with Zend_Db_Table, that comment confused me a bit. Thanks for the clarification.
karim79
@Stefan. Correct. Thank you for clarifying it. You couldn't have wrote it better myself.
Raffael Luthiger
I have taken your answer now. Thanks!.. One remark: If you are instantiating DbTable object then you can provide the name of the adapter like this: $table = new Default_Model_DbTable_Users(array('db' => 'dbAdapter2'));This way you do not have to use Zend_Registry::get('dbAdapter2');
Raffael Luthiger
+3  A: 

I think this depends on how often you have to switch databases. Using two different adapters will differentiate between the two databases more cleanly and would be my preference.

When you're switching databases on your single adapter you'll surely have a hard time tracing which database is currently active - keep in mind that your database connection is most likely a singleton which is passed on between modules, their controllers and their respective models.

The third option would be to use explicit table names throughout your application. MySQL for example provides the db_name.table_name-syntax to address tables in different databases on the same server. The default database does not matter this way and Zend_Db_Table and Zend_Db_Select support this syntax out of the box.

EDIT:

I must add that option 2 and 3 will only work if your database user has the appropriate access rights on all the databases, tables and columns you want to use. Option 1 will be the only option left, if your database requires a different user on each of your databases.

Stefan Gehrig
I will have the same user for both databases. So option 2 and 3 would work. I have to say that I tried option 3 but it did not work. But it could very well could have been a problem with my syntax.
Raffael Luthiger
Which DBMS? Which errors do you get? When using MySQL you perhaps will have to quote the db-name as well as the table-name using back-ticks.
Stefan Gehrig
Sadly it is not MySQL. My customer "forced" me to use MSSQL. According to the documentation I have to use there db.dbo.table. But probably my problem is with the different quoting and the spaces in the table names. The quoting is normally like this: [table name].[column name] But Zend_DB is change by default to standard "table name".
Raffael Luthiger
+1  A: 

Hi ! ; I am Using this Config.ini you can you can use it also :

[production]
#Debug output
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
# Include path
includePaths.library = APPLICATION_PATH "/../library"
# Bootstrap
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
# Front Controller
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.env = APPLICATION_ENV
# Layout
#resources.layout.layout = "layout"
#resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
# Views
resources.view.encoding = "UTF-8"
resources.view.basePath = APPLICATION_PATH "/views/"
# Database
resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "root"
resources.db.params.password = ""
resources.db.params.dbname = "world"
resources.db.isDefaultTableAdapter = true
# Session
resources.session.save_path = APPLICATION_PATH "/../data/session"
resources.session.remember_me_seconds = 864000
[testing : production]
#Debug output
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
# Database
resources.db.params.dbname = "myproject_testing"
[development : production]
#Debug output
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
# Database
resources.db.params.dbname = "myproject_development"

you can use it for production , testing and development enviroment if you need to connect to another DB at the same time you can double the config of database like :

resources.db2.adapter = "pdo_mysql"
resources.db2.params.host = "localhost"
resources.db2.params.username = "root"
resources.db2.params.password = ""
resources.db2.params.dbname = "world"
resources.db2.isDefaultTableAdapter = true

then you can load it on the bootstap or where ever you like :) and its also easy

tawfekov
Thanks for the information. It is about the same as Karim79 proposed. You are doing it with the config file only. It would have been nice you would have copied only the relevant code.. and put it within pre tags. then it would have been better readably. But thanks anyway.
Raffael Luthiger
Thank you for reformatting your answer. I gave you one point because I will use your answer together with answer from Karim79.
Raffael Luthiger
Thank you Raffael very much , i am really appreciate it :)
tawfekov