Should a base PHP database class create multiple connections? - php

I have written a data class for handling MySQL queries and then all other classes such as login, products extend this class to make use of the database. As a result, each page load creates 2 or more DB connections due to something similar to the following:
$login, parent::__construct(); // check login via db
$products, parent::__construct(); // fetch products from db
Is there a way around this such as adding some code in the constructor to verify whether an existing DB connection has already been established?
A fellow developer I work with writes in procedural style and simply uses a single global $_db object for all queries and, this seems a lot more efficient as it only creates 1 DB connection.

For many smaller applications, I make my database instance global to the whole application, along with configuration and other application-wide classes, such as logging. This is not necessarily the preferred method, as it couples code to expect things named certain ways, and could possibly cause conflicts down the road. However, for small utility applications it is convenient.
For anything larger, I usually utilize my DB from an ORM anyway, so it becomes a non issue.

Michael's example of creating a static class and how to use it helped resolve the problem.
https://stackoverflow.com/a/26981461/541091

Related

Gridfield containing data from external database in Silverstripe

I am using a ModelAdmin to display data through gridfield. i want to manage a model in the same way, but from an external database.
In my model admin i have the code to call the model(DataObject) i want to manage:
private static $managed_models = array(
'exampleModel'
);
To insert the data into this second database i have the follwing code inside a function:
global $databaseConfig, $databaseConfig2;
DB::connect($databaseConfig2); //connect to second database
//do somee stuff
DB::connect($databaseConfig); //return to default database
Just for test, i've used a dataObject exampleModel and defined some fields.
In this way, the gridfield is showing results from this model in my modelAdmin, so it's working, but how can i show results from my second database in this gridfield. is it possible ?
This is an interesting scenario, one that isn't possible out of the box in a default setup of SilverStripe. Notice that at any one time, there is only one DB connection open, as is the case with most CMS systems, and it is this connection that the ORM is using in your models.
However, I don't see in principle why this couldn't be done in SilverStripe, but there would be some additional classes needed to be written "behind" your models before it would work satisfactorily for you. Any solution would also be predicated on your wanting to edit, delete in your models (all the standard GridField actions) on each respective database.
The only solution that comes to mind is to use SilverStripe's built-in Aspects system - but I have to admit to never having used it myself. Aspect Oriented Programming is different to standard business logic-as-class OO programming, but can still be used within an OO paradigm. It allows developers to "point cut" (to cut "horizontally" across class-logic and utilise different logic, in a different class under pre-defined scenarios).
Think of it a little like a hook.
Looking at the SilverStripe's aspect system and the example it uses (See: https://docs.silverstripe.org/en/3.2/developer_guides/extending/aspects/), I believe one could modify the example to your use. The example explains how, based on DB reads or writes, the ORM should use one DB connection over another, this sounds similar to your scenario, expect that instead of "read" and "write" being the arbiter of which connection is used, it would be which model - perhaps by virtue of implementing a specific interface.
Good luck :-)

What is the correct location for db object initialization?

I am building a plugin for WordPress 3.3.1. In the code I define several shortcodes, class to support them, and a couple of admin pages. I am at a beginners level with php although I have 20+ years experience with programming, OOA&D, etc..
In the class methods, I make calls to a custom database not housed in the wp database. That is, the custom database is a separate schema, independent of the wp database.
Right now, I make the declaration in the methods that need the object. Works fine for dev but won't cut it in production. I am tempted to raise it to the class instance level. Here is where my question becomes clear. There are several classes that will need the connection. The plugin needs only one connection.
Where is the best place to put the database connection object declaration and initialization?
Given the answer to that, where is the proper place to destroy the db connection object instance?
I would make the database connection a static field. Which class to put it in depends on how you've structured your classes/code. Making it static will ensure that the same connection is shared throughout your script.
I recommend using PDO (connecting PDO to MySQL, etc) to connect to your database. PHP will automatically close the connection when the script ends.

PHP conventions for encapsulation and database calls

This is going to take a bit to explain. I'm creating my first real-world web application, and I'd to do it properly. I have very little PHP experience, but vast experience in other languages so technical skill isn't a problem, it's more conventions of the language. I'm following the MVC pattern, and I am at the stage where I'm implementing user registration for the application.
To standardise connections to the database, I've created a Config class with a static getConnection method, which creates a mysqli connection object. This isn't a problem, it's the next bit that is.
To make my classes a bit more readable, I have various functions built into them that make database calls. For example, my User class has a getFriends method like so:
class User
{
public $id;
public getFriends()
{
return UserController::getFriends($id);
}
}
But as it stands now, if I implement it that way, it means creating a connection for every query on a page, probably many times in a single script, which is just horrific.
I was thinking about doing the same as above, but pass getFriends a mysqli object, which in turn passes one to UserController::getFriends as well, but that feels messy, and frankly poor form, even though it would guarantee only one connection per script, a much better improvement.
I also thought about scrapping the idea of keeping the methods inside User altogether, and instead making calls like UserController::getFriends($connection, $id) directly in the script, with a single $connection declared at the beginning, in place of user->getFriends(). That seems like the absolute cleanest, nicest solution, but I'm unsure.
So, essentially, how do PHP folks normally do this sort of thing?
What I do in my MVC framework is create a db connection and assign it to the Model base class (in the config):
$db = new database\adapters\MySQL(...);
if ( !$db->connected() ) {
exit('Ewps!');
}
database\Model::dbObject($db);
Then later on, anywhere, I can use:
User::getFriends(13);
because User extends Model and Model has access to $db: self::dbObject()
If I need my raw db connection, I either use Model::dbObject() or $GLOBALS['db'], but I rarely do need the raw connection, because all db logic should be in your Models.
https://github.com/rudiedirkx/Rudie-on-wheels/blob/master/example_app/config/database.php
https://github.com/rudiedirkx/Rudie-on-wheels/blob/master/example_app/models/User.php#L30
Have a look into the Singleton Pattern . It allows you to create a class (a DB object), but where only one of them is ever allowed (so more than one can't be instantiated).
This means that you only have to create one connection to the DB and it's shared.
Check here for a code example

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.

What are the disadvantages of using a PHP database class as a singleton?

What are the disadvantages of using a PHP database class as a singleton?
The disadvantages are the same as for any class that uses the Singleton pattern:
It is hard to test code that uses singletons.
If your DB class is built to only connect to a single database, you will have problems when you have a script that needs to connect to 2 two separate databases. However, you could build the singleton class to accept multiple server configurations, and then manage them within the singleton.
Otherwise, designing a database class as a singleton is a practice that makes a lot of sense, as you can maintain tight control over how many connections a script is making at any given time.
You can not use two database connections. You would want this because:
you have two databases.
you want to do something within a transaction when another transaction is already running on the 'current' database connection.
you want to use several mock database instances in your unit tests
It makes it hard to run unit tests against it and also makes it impossible to have multiple database connections. As we all know, global variables has lots of drawbacks and Singletons are no exception, only that they are a more "friendly" global variable.
I found a pretty good article about it and an old SO question as well.

Categories