How to establish DB connection only once using zend frame work - php

I am newbie to the zend framework. I am using Zend_Db_Table_Abstract for doing database operations. Now, i want to know that Zend_Db_Table_Abstract will make single db connection for through out the application or will it create for every request.
this is my class which extends zend_db_table_abstract
<?php
class Model_AppsandBills extends Zend_Db_Table_Abstract {
protected $_name="appsandbills_master";
}
?>
Sorry for my poor English. Thanks for help in advance.

Creating an instance of an Adapter class does not immediately connect to the RDBMS server. The Adapter saves the connection parameters, and makes the actual connection on demand, the first time you need to execute a query. This ensures that creating an Adapter object is quick and inexpensive. You can create an instance of an Adapter even if you are not certain that you need to run any database queries during the current request your application is serving.
If you need to force the Adapter to connect to the RDBMS, use the getConnection() method. This method returns an object for the connection as represented by the respective PHP database extension. For example, if you use any of the Adapter classes for PDO drivers, then getConnection() returns the PDO object, after initiating it as a live connection to the specific database.
It can be useful to force the connection if you want to catch any exceptions it throws as a result of invalid account credentials, or other failure to connect to the RDBMS server. These exceptions are not thrown until the connection is made, so it can help simplify your application code if you handle the exceptions in one place, instead of at the time of the first query against the database.
Additionally, an adapter can get serialized to store it, for example, in a session variable. This can be very useful not only for the adapter itself, but for other objects that aggregate it, like a Zend_Db_Select object. By default, adapters are allowed to be serialized, if you don't want it, you should consider passing the Zend_Db::ALLOW_SERIALIZATION option with FALSE, see the example above. To respect lazy connections principle, the adapter won't reconnect itself after being unserialized. You must then call getConnection() yourself. You can make the adapter auto-reconnect by passing the Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE with TRUE as an adapter option.
Source: http://framework.zend.com/manual/1.12/en/zend.db.adapter.html#zend.db.adapter.connecting.getconnection
Also refer: How Zend DB Manage Database Connections

Related

Share mysqli connection

I recently switched from ext/mysql to mysqli in a PHP project. In that project, I extensively used the connection reuse feature of mysql_connect by setting the new_link parameter set to false.
As far as I understand, there is no such mechanism in mysqli_connect; it will always return a new connection even though the same host and user is used. Is this correct? Is there some other function that can mimic the reuse-behaviour?
NB: I see that with prepending the host with p: will create a persistent connection. However, this cannot be used in my case, as part of my project relies on temporary tables.
Update:
The actual mysqli object is embedded in a DB handler class which manages access to the database. This handler is always used to interact with the DB.
I oversimplified my problem because I just wanted to focus on the question if mysqli can automatically reuse a single connection by multiple calls to mysqli_connect with identical parameters. My project is an extenstion to a framework and provides multiple entry points and hooks. I cannot control the order or number of function calles from the hosting framework into my extension. Each part of my extension creates an instance of the DB handler, but could reuse the actual underlying connection.
The creation of the DB handler is done though a db-factory. So I will probabely have to implement some sort of connection-caching there myself...
Nope, mysqli ext doesn't follow that lazy mysql ext behavior, and for a reason.
So, you have to always explicitly address mysqli object. The only problem, though, is with variable scope. But as long as you have $mysqli object visible, you can use it all right.
However, there is another problem: you shouldn't address $mysqli object in your application code at all. That was a problem with old mysql ext and it is a problem with mysqli ext as well - it is not intended to be used in the application code as is.
One have to create a some sort of wrapper, to encapsulate all the database related stuff, and in the application code always use this wrapper class only.
So, get yourself such a wrapper, create an instance of it, and then pass into every class and function as a parameter.

PHPUnit testing database with Zend_Test_PHPUnit_DatabaseTestCase and database adapter issue

I have implemented the abstract class from Database testing with Zend Framework and PHPUnit which implements Zend_Test_PHPUnit_DatabaseTestCase, however I am having issues with the way my database abstraction layer uses the Zend_Db_Adapter and how the unit test uses its own database connection, createZendDbConnection
The code in question is:
public function testSaveInsert()
{
$hostModel = new MyLibrary_Model_Host();
$hostModel->setName('PHPUnit - Host Test 1')
->setDescription('Host Test Description 1');
$databaseAPI = new MyLibrary_DatabaseAPI();
$databaseAPI->addHost($hostModel);
$hosts = $databaseAPI->getHosts();
Zend_Debug::dump($hosts);
// get data from the testing database
$dataSet = new Zend_Test_PHPUnit_Db_DataSet_QueryDataSet($this->getConnection());
$dataSet->addTable('HOST', "SELECT host.NAME
, host.DESCRIPTION
FROM HOST_TABLE host WHERE name like 'PHPUnit -%'");
// verify expected vs actual
$this->assertDataSetsMatchXML('hostInsertIntoAssertion.xml', $dataSet);
}
The MyLibrary_DatabaseAPI() class has a constructor
$hostDb = Zend_Registry::get('config')->dbConnectionIds->hostDb;
$this->appDb = Zend_Registry::get($hostDb);
The addHost method takes the host model attributes and converts them to parameters to be passed into the package function, using the database connection set in the registry. I have a flag in the method call to commit (business requirements determine this), so I can chose when to do this.
At the time of Zend_Debug::dumping the results the host has been added to the database table, however when I run the assertDataSetsMatchXML test it is not picking up a host was added and is failing.
I suspect is the issue is when I instantiate Zend_Test_PHPUnit...($this->getConnection) it uses createZendDbConnection which creates a new database session which isn't aware of the previous one and because I haven't 'committed' the addHost it isn't aware of it?
If I run the method call and commit the record it is added to the host table and the test passes, but I cannot rollback the results using the createZendDbConnection so the record remains in the table, which i dont want. Essentially I want a silent test, come in, test and leave no footprint.
Any ideas on how I can resolve this issue? The basis behind testing this way is the database has an api to tables so i don't directly CRUD in the database. The PHP database API class reflects the calls I can make to the database API so I want to test each of these methods.
You should allow your classes to inject the dependencies they have instead of fetching them from the registry. This is a pattern called "dependency injection" and comes in about two different types: Inject via constructor pattern, or via a setter.
That way, your DatabaseAPI would accept a database connection when instantiated, instead of fetching one from "somewhere", and that database connection can be a mock object instead of the real thing.
The mock can be configured to wait for certain method calls, can check if the parameters are correct, and might even return a defined result. All those mock calls are part of the test.
The biggest benefit: Mocks are only taking place in memory, they do not affect any permanent storage like a database. That means they are way faster than the real database access, and they leave no trace behind after their variable is unset or forgotten.
The only places where software really needs to use the underlying hardware is in those classes that must do the actual work. Fortunately for you, you are using the classes of the Zend framework, and you can consider them tested need not do it yourself again (unless you suspect an error).

zend - connect to a database from a controller

I have the following setup for a game:
One database with all users, one database with users that didn't complete the tutorial. In the first database I have a flag that tells me if user "Gogu" completed the tutorial or not. If he didn't, I need to connect to the second database and get some data. After some research I found this: connecting to two different databases with Zend Framework.
The thing is that since only like 5% of the users will be in tutorial progress is no use to keep both connections so I only need to connect while in a controller, get what I need and close the connection.
Any idea how to do this?
You don't have to worry about 2 connections, because Zend_Db "lazy loads" the connection. From the ZF manual:
Creating an instance of an Adapter class does not immediately connect to the RDBMS server. The Adapter saves the connection parameters, and makes the actual connection on demand, the first time you need to execute a query. This ensures that creating an Adapter object is quick and inexpensive. You can create an instance of an Adapter even if you are not certain that you need to run any database queries during the current request your application is serving.
http://framework.zend.com/manual/en/zend.db.adapter.html#zend.db.adapter.connecting.getconnection
Just note that the method used in the accepted answer you referred calls $db->getConnection() from the bootstrap. This not recommended because it will defeat the purpose of lazy loading. You could also consider Zend_Application_Resource_Multidb, which is perhaps a more elegant approach:
http://framework.zend.com/manual/en/zend.application.available-resources.html#zend.application.available-resources.multidb

PHP PDO: Multiple objects extend dbwrapper; How many MySQL connections?

The Situation:
I am using a db class as a wrapper (dbwrapper) to open and close db connections via PHP PDO
I have 3 separate classes which extend this db wrapper
I instantiate 3 objects from said classes and in the course of their existence they each make db queries
MySQL used in this case.
When the methods of the 3 classes require db access they each create PDO objects internally, making use of the dbwrapper which they extended. Each object is storing its PDO object in a member/field for reference by itself.
The Question: My question is this... is each object creating a separate connection to the database, making 3 in total? Is each client of Apache creating only one connection to the database or is each object using the db in a php application creating a connection. (sounds inefficient!)
The Reason: I would like to understand how these connections are handled.
I am trying to decide if it would be better to have each class extend the dbwrapper or if it would be better to initialize the dbwrapper without making an automatic connection the db, handle that when its needed. Instead I would pass the dbwrapper to each objects constructor as they are initialized... letting them use that reference. If multiple db connections are happening then I think this would be the best way to minimize overhead while overcoming issues of object's scope and access.
Thanks in advance!
is each object creating a separate connection to the database, making 3 in total?
Maybe. I don't know, but here's how to find out. While your script is running, connect to MySQL via your client of choice (like the command line) and issue the command SHOW PROCESSLIST; You'll get a list of active connections.
You might need to insert a sleep in your script to keep it alive long enough for you to run the process list command when you've instantiated and are working on all three objects.
You'll see either one connection or three. Then you'll have your answer.
(The answer will vary depending on the underlying driver. Some drivers will reuse the connection if the DSN is identical.)
Instead I would pass the dbwrapper to each objects constructor as they are initialized... letting them use that reference
This is the common practice. Database handles are prime candidates for the Singleton pattern as well.

Mysql Connection Class

I'm writing some php code, and I'm frequently accessing my MySQL database to read and update fields.
My current code includes a class called dbconnnect, and I use it as follows:
class edit_data extends dbconnect {
//<some php code>
parent::connect();
//<get info from database>
parent::disconnect();
//<evaluate data>
My question - this is the most efficient way to connect and disconnect from a MySQL database? (Keep in mind, I almost always connect to the same database, so no need to redefine the connection parameters every time).
I was considering running the connect in the constructor, so then I could just write
$connector = new dbconnect();
but I realized I'm not actually saving much by doing this - right?
Thanks.
Just make sure that the code for db connection/disconnection is included/run automatically at the start and end of each file, without needing to do it separately for every file. Make sure this code is stored in 1 location and included in all other files, so you can change it easily when needed. As long as you do these things, the rest is just personal preferences for how you want to connect/disconnect from the db.
I would also recommend a framework such as CodeIgniter for taking care of common tasks such as this behind the scenes for each file.
By using
$connector = new dbconnect();
and not
parent::connect();
you are essentially decoupling your edit_data class with the dbconnect class. What the means for you is that:
your edit_data class can now have more than one connection by using multiple dbconnect objects (connection pooling)
your edit_data class can (in the future) use something other than dbconnect and won't have to change any other code. With parent::connect(), if you ever change to extending some another class, you'll have to make sure the new class will support the existing semantics
The "right" way would probably be to do it like the MySQLi and PDO extensions - open the connection in the constructor and close it in the destructor.
The "efficient" way is to check the connection in your query() method and (r)open it if necessary.
In both approaches you avoid creating a separate connect() method, and thus remove the risk of forgetting to call it in your script.
Unless you know you are always going to connect to the database every time, I wouldn't put the connect piece in the constructor. If you don't need to connect, you shouldn't, it's expensive. Your constructor should only accept the connection parameters. Although it looks like you may be using static classes, so the constructor would get executed.
As Krzysztof mentioned, you should connect on demand. In my database class, I have all queries eventually go through an "execQuery" function. That function checks if there is a connection to the database or not.
Having a single central query function also allows you to do things like record all queries that were run in a session, add timing, logging or anything else you need to do.
Having the disconnect in the destructor is the proper place.
Our codebase has many paths and makes a lot of use of caching.
We only connect with the database when the first query is executed. (so actually on the ->query() method).
We let PHP disconnect once the script is over, and don't explicitly call ->disconnect
Juts be sure of reusing you connection:
Review new_link parameter:
If a second call is made to mysql_connect() with the same arguments, no new link will be established, but instead, the link identifier of the already opened link will be returned. The new_link parameter modifies this behavior and makes mysql_connect() always open a new link, even if mysql_connect() was called before with the same parameters. In SQL safe mode, this parameter is ignored.
http://php.net/function.mysql-connect
I think deriving your "edit_data" class from your "dbconnect" class demonstrates confusion of logic. Is your data editing object a special type of database connection? Or maybe it would make more sense to say the data editing object needs to use a database connection? (This is the difference between IS A and HAS A.)
Although it seems to be falling out of fashion now, you can use a singleton factory call to get the database handler. Then any function which needs it can simply call it. If you make the handler self-initializing the first time it has to do any work, then nothing needs to even worry about initializing it. (To do this, check if the instance variable containing the handle is a resource handle - if not, call the initializer. Remember to decide what to do if the connection fails.) Then you just need a way for the handler to find it's configuration. I would have the factory call do that, not the initializor.
A variant way of doing that is for the constructor to get the current database handler and put a reference to it in an instance variable. This can be done several ways. Requiring it in the constructor might work, or you can fall back on the singleton factory call again. This technique gives the object constructor a chance to deny instantiation if the database handler won't initialize (the factory call can check that).
Connecting is expencive so, don't connect and disconnect for each query.
If possible use mysqli instead of mysql, it is generally faster
If you are using mysql not mysqli, use mysql_pconnect instead of just mysql_connect
php closes all the open db connections, so there is no need to explicitly do so
share connections between queries whether you connect at the start of the script or on the first query is up to.

Categories