HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

PHP database class - Managing two connections with different privileges

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
managingwithphpprivilegesdatabasedifferenttwoclassconnections

Problem

I'm just trying to master the art of using classes in PHP and have come across a concern.

For security reasons, I sometimes use two database connections in my application; one with read-only privileges and one with full read/write. Unfortunately, I wasn't really thinking about this when I started to build a few classes.

So, I have a database class, which is essentially a pointless PDO wrapper (pointless because PDO is a wrapper), but thought it'd be good practice to write one anyway and I may extend PDO later too. This is what I did:

 false,
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
            );
            if ($accessLevel == "public") {
                $this->dbh = new PDO($dsn, $credentials['publicUser'], $credentials['publicPassword'], $options);
            } else if ($accessLevel == "private") {
                $this->dbh = new PDO($dsn, $credentials['privateUser'], $credentials['privatePassword'], $options);
            }
        }
    }

    // other database functions

}
?>


For a public connection (read/write), I simply used this:

$db = new Database('public', config['dbConfig']);


... or for a private connection (read-only), I used this:

$db = new Database('private', config['dbConfig']);


... and when I wanted to use the connection in another class, I simply injected the connection, like so:

$user = new User($db);


Works fine, but then I realised that I may need two connections inside that class, one for reading only and one for all. So I got a little confused, but had a go regardless. This is what I did:

Instead of calling the class with either of the connections, I called the class twice with both, like so:

$publicDB = new Database('public', $config['db']);
$privateDB = new Database('private', $config['db']);


and then injected both of those to my other class:

$user = new User($publicDB, $privateDB);


Inside this User class, this how I used the two connections:

```
dbh = $publi

Solution

You want two classes. They extends Database. PublicDatabase and PrivateDatabase, you instantiate whichever you need, and inject whichever you need. That way you can even have the same signature in the constructor in both types.

If you don't have a preference, you just need a database connection in a function, just ask for Database, and either will fit.

Also

-
You don't need to use gettype, you can hint in the function's signature for the type, it works for all Objects and array. So for example:

public function __construct(array $accessLevel, array $credentials) {


-
Don't give defaults if you can't handle defaults. Your object won't work if $credentials is empty, don't let it be.

-
What do your Database object solve? What kind of abstraction it provides? Usually such 'utility' classes are pointless.

Better approach

Your User shouldn't be responsible to save/fetch itself. In fact, if you have a User which doesn't care where it came from, you have a perfectly reusable object, a User that can come from a database, a file, a session, a form, whatever, and work the same.

You should have two objects: the User and the UserMapper, the UserMapper is responsible for fetching information about users and fill them into User objects, as well as saving information from the User object back into the database.

The idea of OOP is separation of responsibilities.

Code Snippets

public function __construct(array $accessLevel, array $credentials) {

Context

StackExchange Code Review Q#52712, answer score: 2

Revisions (0)

No revisions yet.