There seems to be two main concerns that lead people to wrap PDO code in classes.
The first is a need to call the database once and reuse the database connection. For instance, you don't want to call the database inside each Model function as it will generate too many database connections, often more connections than your database server will allow.
The next is to prevent having to pass the database connection variable (e.g., $conn) to functions.
This can be illustrated by example as the code ´select($table,$where)´ is preferred over ´select($conn,$table,$where)´.
There are several micro-frameworks / classes / libraries that does this for you.
Some of the better include:
Or - generally - how is this done?
Personally I have come to prefer using procedural code (with a global $dbh variable to hold the database connection) that use "almost" plain PDO calls.
To do this, I first build a db() function to hold the database connection:
function db($dsn=null)
{
global $dbh;
if( isset($dbh) ) {
return $dbh;
} else {
$dbh = new PDO($dsn);
$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbh;
}
}
Usage:
db("sqlite:articles.db");
$stmt = db()->prepare("INSERT INTO `article` (`id`,`title`,`body`) VALUES (:id, :title, :body)");
$stmt->execute([ ':id'=>$id, ':title'=>$title, ':body'=>$body ]);
Or:
$stmt = db()->prepare("SELECT * FROM `article` WHERE `id`=:id");
$stmt->execute([':id'=>542]);
$row = $stmt->fetch(PDO::FETCH_OBJ);
echo $row->id;
...
It even works within functions allowing me to create my own Model functions using a simple syntax:
db("sqlite:articles.db");
print_r( select_article("542") );
function select_article($id) {
// Note that we use db() inside the function, without adding a $conn variable
$stmt = db()->prepare("SELECT * FROM `article` WHERE `id`=:id AND published=1");
$stmt->execute([':id'=>$id]);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
function insert($table,$data) {
...
$stmt = db()->prepare("INSERT INTO `article` (`id`,`title`,`body`) VALUES (:id, :title, :body)");
$stmt->execute([ ':id'=>$id, ':title'=>$title, ':body'=>$body ]);
}