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

Generic method for database calls

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

Problem

Background

Breaking from MVC, I've implemented the following architecture:

POST/GET ➤ PHP ➤ Database Calls ➤ XML ➤ XSLT ➤ HTML


All database interactions are relegated to the call method in the Database class, without exception. This adheres to the DRY principle. This design allows the following, which is a critical application feature:

... ➤ XML ➤ XSLT ➤ LaTeX ➤ PDF


The same code that retrieves data to render as an interactive web page is exactly the same code and XML used to render a PDF. Eventually additional output formats will be required:

... ➤ XML ➤ XSLT ➤ XML
... ➤ XML ➤ XSLT ➤ ASCII Text


Using this architecture, the same database functions can be used to generate completely different output formats.

Common Code

The code that makes database calls can do so in one of three ways:

$this->call( "database_function", "c1, c2, c3", $v1, $v2, $v3 );
$this->call( "database_function", "c1, c2, c3" ) );
$this->call( "database_procedure" ) );


The parameters are variable arguments.

Database Class

My questions pertain to the database class itself:

```

* $db = Database::get();
* $db->call( ... );
*
*/
class Database extends Obj {
private static $instance;
private $dataStore;

/**
* Sets the connection that this class uses for database transactions.
*/
public function __construct() {
global $dbhost;
global $dbname;
global $dbuser;
global $dbpass;

try {
$this->setDataStore(
new PDO( "pgsql:dbname=$dbname;host=$dbhost", $dbuser, $dbpass ) );
}
catch( PDOException $ex ) {
$this->log( $ex->getMessage() );
}
}

/**
* Returns the singleton database instance.
*/
public function get() {
if( self::$instance === null ) {
self::$instance = new Database();
}

return self::$instance;
}

/**
* Call a database function and return the results. If there are
* multiple columns to return, then the value for $params must contain
*

Solution

Here's my sniff at the first things I saw for the code (not the implementation).

public function __construct() {
    ...
    try {
      $this->setDataStore(
        new PDO( "pgsql:dbname=$dbname;host=$dbhost", $dbuser, $dbpass ) );
    }
    ...


Above, a class is instantiating a class, and not injecting dependencies.

Pass arguments to the constructor with the dependencies that a class requires:

public function __construct(PDO $pdo) {
    $this->dataStore = $pdo;
}


In addition, use the magic __get() and __set() methods instead of explicitly declared accessors to vastly improve readability and maintenance ease. Here's the documentation, remember it, and learn to love it.

public function __get(string $name) {
    // Logic/cases to check name for correct stores here.
}

Code Snippets

public function __construct() {
    ...
    try {
      $this->setDataStore(
        new PDO( "pgsql:dbname=$dbname;host=$dbhost", $dbuser, $dbpass ) );
    }
    ...
public function __construct(PDO $pdo) {
    $this->dataStore = $pdo;
}
public function __get(string $name) {
    // Logic/cases to check name for correct stores here.
}

Context

StackExchange Code Review Q#26507, answer score: 2

Revisions (0)

No revisions yet.