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
Related
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
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.
I'm creating a new PHP application and want to make sure I get the ground work right to save any future problems. I know my application will have more than one class that will need a database connection (PDO) and after a long time scouring the internet i can't find a definitive solution.
I like the singleton design pattern personally, but there are a lot of people out there that say singletons in general should be avoided at all costs. These people, however, don't give a specific solution to this problem.
I understand that an application may need more than one database connection but could i not create a singleton that contained each required DB connection (i.e. DB::getInst('conn1')->query(); )?
Is it a case of having to pass round the PDO (or PDO wrapper) object to every class that may need it? I've done this before found it annoying keeping track of it.
I personally thing a singleton (or a multiton, if you need several DB connections) is fine for such an usage.
But if you do not want to use it, you should then take a look at the Registry pattern.
This way, you can have your database class instance(s) available for all your application's classes, without having to pass an additional parameter each time (which is very ugly, IMHO).
but could i not create a singleton that contained each required DB connection (i.e. DB::getInst('conn1')->query(); )?
you can, it's called multiton pattern
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.
We have a need to access a DB that only allows one connection at a time. This screams "singleton" to me. The catch of course is that the singleton connection will be exposed (either directly or indirectly) via a web-service (most probable a SOAP based web-service - located on a separate server from the calling app(s) ) - which means that there may be more than one app / instance attempting to connect to the singleton class.
In PHP, what is the best way to create a global singleton or a web-service singleton?
TIA
This screams "use a DB SERVER" to me. ;-), but...
You could create an SoapServer and use a semaphore to allow only 1 connection at a time
$s1 = sem_get(123, 1);
sem_acquire($s1);
// soapserver code here
sem_release($s1);
In PHP, there is no such thing as a "global" object that resides across all requests . In a java webserver, this would be called "application level data store". In php, the extent of the "global" scope (using the global keyword) is a single request. Now, there is also a cross session data store accessible via $_SESSION, but I'm trying to highlight that no variable in php is truly "global". Individual values emulate being global by being stored to a local file, or to a database, but for something like a resource, you are stuck creating it on each request.
Now, at the request level, you can create a Singleton that will return an initialized resource no matter which scope within the request you call it from, but again, that resource will not persist across or between requests. I know, it is a shortcoming of php, but on the other hand, the speed and stability of the individual requests help make up for this shortcoming.
Edit:
After reading over your question again, I realized you may not be asking for a singleton database access class, but rather something that can resource lock your database? Based on what you said, it sounds like the database may do the locking for you anyway. In other words, it won't allow you to connect if there is already another connection. If that is the case, it seems kind of like you have 2 options:
1) just let all your pages contend for the resource, and fail if they don't get it.
2) Create a queue service that can accept queries, run them, then cache the results for you for later retrieval.