patternphpMinor
Generic method for database calls
Viewed 0 times
callsgenericmethoddatabasefor
Problem
Background
Breaking from MVC, I've implemented the following architecture:
All database interactions are relegated to the
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:
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:
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
*
Breaking from MVC, I've implemented the following architecture:
POST/GET ➤ PHP ➤ Database Calls ➤ XML ➤ XSLT ➤ HTMLAll 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 ➤ PDFThe 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 TextUsing 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).
Above, a class is instantiating a class, and not injecting dependencies.
Pass arguments to the constructor with the dependencies that a class requires:
In addition, use the magic
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.