How to properly set up a PDO connection - php

From time to time I see questions regarding connecting to database.
Most answers is not the way I do it, or I might just not get the answers correctly. Anyway; I've never thought about it because the way I do it works for me.
But here's a crazy thought; Maybe I'm doing this all wrong, and if that's the case; I would really like to know how to properly connect to a MySQL database using PHP and PDO and make it easy accessible.
Here's how I'm doing it:
First off, here's my file structure (stripped down):
public_html/
* index.php
* initialize/
-- load.initialize.php
-- configure.php
-- sessions.php
index.php
At the very top, I have require('initialize/load.initialize.php');.
load.initialize.php
# site configurations
require('configure.php');
# connect to database
require('root/somewhere/connect.php'); // this file is placed outside of public_html for better security.
# include classes
foreach (glob('assets/classes/*.class.php') as $class_filename){
include($class_filename);
}
# include functions
foreach (glob('assets/functions/*.func.php') as $func_filename){
include($func_filename);
}
# handle sessions
require('sessions.php');
I know there's a better, or more correct, way to include classes, but can't remember what it was. Haven't gotten the time to look into it yet, but I think it was something with autoload. something like that...
configure.php
Here I basically just override some php.ini-properties and do some other global configuration for the site
connect.php
I've put the connection onto a class so other classes can extends this one...
class connect_pdo
{
protected $dbh;
public function __construct()
{
try {
$db_host = ' '; // hostname
$db_name = ' '; // databasename
$db_user = ' '; // username
$user_pw = ' '; // password
$con = new PDO('mysql:host='.$db_host.'; dbname='.$db_name, $db_user, $user_pw);
$con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$con->exec("SET CHARACTER SET utf8"); // return all sql requests as UTF-8
}
catch (PDOException $err) {
echo "harmless error message if the connection fails";
$err->getMessage() . "<br/>";
file_put_contents('PDOErrors.txt',$err, FILE_APPEND); // write some details to an error-log outside public_html
die(); // terminate connection
}
}
public function dbh()
{
return $this->dbh;
}
}
# put database handler into a var for easier access
$con = new connect_pdo();
$con = $con->dbh();
//
Here I do believe there's room for massive improvement since I recently started learning OOP, and using PDO instead of mysql.
So I've just followed a couple of beginners tutorials and tried out different stuff...
sessions.php
Beside handling regular sessions, I also initialize some classes into a session like this:
if (!isset($_SESSION['sqlQuery'])){
session_start();
$_SESSION['sqlQuery'] = new sqlQuery();
}
This way this class is available all over the place. This might not be good practice(?)...
Anyway, this is what this approach allows me to do from everywhere:
echo $_SESSION['sqlQuery']->getAreaName('county',9); // outputs: Aust-Agder (the county name with that id in the database)
Inside my sqlQuery-class, which extends my connect_pdo-class, I have a public function called getAreaName which handles the request to my database.
Pretty neat I think.
Works like a charm
So that's basically how I'm doing it.
Also, whenever I need to fetch something from my DB from not within a class, I just do something similar to this:
$id = 123;
$sql = 'SELECT whatever FROM MyTable WHERE id = :id';
$qry = $con->prepare($sql);
$qry -> bindParam(':id', $id, PDO::PARAM_INT);
$qry -> execute();
$get = $qry->fetch(PDO::FETCH_ASSOC);
Since I put the connection into a variable inside connect_pdo.php, I just have referring to it and I'm good to go. It works. I get my expected results...
But regardless of that; I would really appreciate if you guys could tell me if I'm way off here. What I should do instead, areas I could or should change for improvement etc...
I'm eager to learn...

The goal
As I see it, your aim in this case is twofold:
create and maintain a single/reusable connection per database
make sure that the connection has been set up properly
Solution
I would recommend to use both anonymous function and factory pattern for dealing with PDO connection. The use of it would looks like this :
$provider = function()
{
$instance = new PDO('mysql:......;charset=utf8', 'username', 'password');
$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
return $instance;
};
$factory = new StructureFactory( $provider );
Then in a different file or lower in the same file:
$something = $factory->create('Something');
$foobar = $factory->create('Foobar');
The factory itself should look something like this:
class StructureFactory
{
protected $provider = null;
protected $connection = null;
public function __construct( callable $provider )
{
$this->provider = $provider;
}
public function create( $name)
{
if ( $this->connection === null )
{
$this->connection = call_user_func( $this->provider );
}
return new $name( $this->connection );
}
}
This way would let you have a centralized structure, which makes sure that connection is created only when required. It also would make the process of unit-testing and maintenance much easier.
The provider in this case would be found somewhere at the bootstrap stage. This approach would also give a clear location where to define the configuration, that you use for connecting to the DB.
Keep in mind that this is an extremely simplified example. You also might benefit from watching two following videos:
Global State and Singletons
Don't Look For Things!
Also, I would strongly recommend reading a proper tutorial about use of PDO (there are a log of bad tutorial online).

I would suggest not using $_SESSION to access your DB connection globally.
You can do one of a few things (in order of worst to best practices):
Access $dbh using global $dbh inside of your functions and classes
Use a singleton registry, and access that globally, like so:
$registry = MyRegistry::getInstance();
$dbh = $registry->getDbh();
Inject the database handler into the classes that need it, like so:
class MyClass {
public function __construct($dbh) { /* ... */ }
}
I would highly recommend the last one. It is known as dependency injection (DI), inversion of control (IoC), or simply the Hollywood principle (Don't call us, we'll call you).
However, it is a little more advanced and requires more "wiring" without a framework. So, if dependency injection is too complicated for you, use a singleton registry instead of a bunch of global variables.

I recently came to a similar answer/question on my own. This is what I did, in case anyone is interested:
<?php
namespace Library;
// Wrapper for \PDO. It only creates the rather expensive instance when needed.
// Use it exactly as you'd use the normal PDO object, except for the creation.
// In that case simply do "new \Library\PDO($args);" with the normal args
class PDO
{
// The actual instance of PDO
private $db;
public function __construct() {
$this->args = func_get_args();
}
public function __call($method, $args)
{
if (empty($this->db))
{
$Ref = new \ReflectionClass('\PDO');
$this->db = $Ref->newInstanceArgs($this->args);
}
return call_user_func_array(array($this->db, $method), $args);
}
}
To call it you only need to modify this line:
$DB = new \Library\PDO(/* normal arguments */);
And the type-hinting if you are using it to (\Library\PDO $DB).
It's really similar to both the accepted answer and yours; however it has a notably advantage. Consider this code:
$DB = new \Library\PDO( /* args */ );
$STH = $DB->prepare("SELECT * FROM users WHERE user = ?");
$STH->execute(array(25));
$User = $STH->fetch();
While it might look like normal PDO (it changes by that \Library\ only), it actually doesn't initialize the object until you call the first method, whichever it is. That makes it more optimized, since the PDO object creation is slightly expensive. It's a transparent class, or what it's called a Ghost, a form of Lazy Loading. You can treat the $DB as a normal PDO instance, passing it around, doing the same operations, etc.

There are a few basic flaws in your setup:
The configure.php file shouldn't be in the web server's document root — if the server is ever missconfigured you might expose credentials to the public. You might think it won't happen to you, but it's a risk you just don't need to be taking. Classes also shouldn't be there... this isn't as important but still anything that doesn't need to be public shouldn't be public.
Unless you're working with an especially large project, you shouldn't have an "initialization" directory. Loading one large file is approximately 10x faster than loading ten small files with the same contents. This tends to really add up as a project grows and can really slow down PHP sites.
Try not to load things unless you actually need to. For example don't connect with PDO unless you actually need to. Don't session_start() you actually read/write to session. Don't include a class definition file unless you create an instance of the class. There are limits to how many connections you can have. And APIs like session establish "locks" that can pause code execution for other people using the same resource.
As far as I can tell, you're not using Composer. You should be using it - it'll make life so much easier both for your own code and for third party dependencies.
Here's my proposed directory structure, which is similar to what I use for medium sized projects:
init.php Replaces public_html/initialize. Your PDO connection details
are held here.
classes/ Replaces public_html/classes
vendor/autoload.php Your class autoload script generated using the
industry standard Composer command line tool
composer.json The file where you describe how autoload.php
operates among other things. For example if you
don't use namespaces (maybe you should) it might be:
{"autoload": {"psr-4": { "": "classes/" }}}
public_html/index.php Your landing page
public_html/other.php Some other page
public_html/css/foobar.css ...and so on for all static resources
The init.php file might look something like:
date_default_timezone_set('Etc/UTC');
require 'vendor/autoload.php';
$pdoConnect = function() {
static $pdo = false;
if (!$pdo) {
$pdo = new PDO('mysql:dbname=db;host=localhost', 'user', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
}
return $pdo;
};
// similar anonymous functions for session_start(), etc.
index.php might look like:
require '../init.php';
$pdo = $pdoConnect();
// go from there
other.php might be similar but maybe it doesn't connect to the database, therefore doesn't execute $pdoConnect.
As much as possible, you should write the bulk of your code into the classes directory. Keep index.php, other.php, etc as short and sweet as possible.

$dsn = 'mysql:host=your_host_name;dbname=your_db_name_here'; // define host name and database name
$username = 'you'; // define the username
$pwd='your_password'; // password
try {
$db = new PDO($dsn, $username, $pwd);
}
catch (PDOException $e) {
$error_message = $e->getMessage();
echo "this is displayed because an error was found";
exit();
}

Related

Static Varible vs PDO::ATTR_PERSISTENT

I have a database class that I developed. But I have doubts about performance in case of load. There are two issues that I was curious about and couldn't find the answer even though I searched.
When the database connection is bound to a static variable in the class,
class DB
{
static $connect;
......
function __construct()
{
try {
self::$connect = new PDO("{$this->db_database}:host={$this->db_host};dbname={$this->db_name};charset=utf8mb4", "{$this->db_username}", "{$this->db_password}");
self::$connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$connect->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES utf8mb4");
} catch ( PDOException $e ){
echo '<b>ERROR: </b>'.$e->getMessage();
exit;
}
}
}
PDO::ATTR_PERSISTENT => true
Does it have an equivalent ability?
Also, I didn't fully understand the pdo permalink logic, it uses the existing connection instead of opening a separate connection for each user. But how does he use the existing link here? For example "ip address" etc.
Thank you for your help.
Let me approach the issues from a different direction.
A program should have only one connection to the database. (There are rare exceptions.) Your code, as it stands, seems to be inconsistent. It has a single ("static") connection, yet the class can be instantiated multiple times, thereby connecting multiple times. (I don't want to depend on anything "persist" to clean up the inconsistency.)
Either make the class a singleton or otherwise avoid being able to call __construct a second time. One approach goes something like this:
class DB {
private static $connect;
......
public function __construct() {
if (! self::$connect) {
self::$connect = ...
}
}
public function Fetch(...) {
self::$connect->...
return ...;
}
$con = new DB();
$data = $con->Fetch(...);
(plus suitable try/catch)
Note that that allows you to sub-class as needed.
Another approach might involve preventing the use of new:
private function __construct() { ... }
plus having some public method invoke that constructor.
Here's another approach. It can be used on an existing class that you don't want to (or can't) modify:
function GetConnection() {
static $db;
if (! $db) {
$db = new ...;
}
return $db;
}
$db = GetConnection();
$db->Fetch(...)'
As for "connection pooling", it is of limited use with MySQL. (Other products need it much more than MySQL does.) In my opinion, don't worry about such.
Do not use "auto-reconnect". If the connection dies in the middle of a transaction and is automatically restarted, then the first part of the transaction will be rolled back while the rest might get committed. That is likely to lead to data inconsistency.
Singletons, statics, globals, void*, critical sections all make me cringe. When I need such, I rush to find a way to "hide" it, even if that means writing cryptic code in some class(es).
For performance, MySQL really needs a single connection throughout the program. I compromise by hiding the connection in a "static" that serves at a "global". Then I hide that inside the class that I use to abstract the object(s).
I agree with Karwin's [now delete] Answer -- that this discussion is "much ado about nothing". MySQL performance is mostly about indexing, query formulation, and even the architecture of the application. Not about connections, common code elimination, redundant function calls, etc.

How to avoid a construct being called twice

Currently trying to learn the "right" way to build a site with OOP and the MVC model, and obviously running into some stumbling blocks since I've been doing mostly procedural for years.
(I'm also using PHP 7 for the first time since I've been stuck with PHP 5 for years and years, so also trying to code the "right" way using mysqli_ instead of the old mysql_. Learning prepared statements for the first time also instead of just escaping all my variables, but that's a whole different discussion)
Right now I have a few different classes:
config.class.php -> Config -> set up the db connection and other site settings
leads.class.php -> Leads extends Config -> get lead info from the db upon request (when someone hits the site)
questions.class.php -> Questions extends Config -> get question info (it's a survey site)
leadsview.class.php -> -> LeadsView extends Leads -> display lead info if needs be
questionsview.class.php -> QuestionsView extends Questions -> display question info on the page after it's pulled from the db
So, let's say on my index.php I need to instantiate both QuestionsView and LeadsView so I can display questions and lead info on the page, respectively. So I do this:
session_start();
include_once 'lib/autoload.php'; // class autoloader
$l = new LeadsView();
$q = new QuestionsView();
Totally works fine so far. BUT - in my Config class I not only have a database connection, but a few site configuration settings inside a constructor that need to be set when someone first hits the page. Something like this so far:
class Config {
// set up db connection
private $db_host;
private $db_user;
private $db_password;
private $db_name;
protected $conn;
protected $flow_id;
protected $domain;
public function __construct() {
$this->flow_id = $_REQUEST['flow'];
$this->domain = $_SERVER['HTTP_HOST'];
$this->connect(); // open the db connection
print "hey<br>";
}
protected function connect($db = "default") {
switch ($db) {
// allow for different db connections in the future
case "default":
$this->db_host = "XXXX";
$this->db_user = "XXXX";
$this->db_password = "XXXX";
$this->db_name = "XXXX";
break;
}
$this->conn = new mysqli($this->db_host, $this->db_user, $this->db_password, $this->db_name);
$this->conn->set_charset("utf8mb4");
if ($this->conn->connect_error) {
die("Error connecting to db: " . $this->conn->connect_error);
}
}
}
I threw in that print "hey<br>"; just to make sure that constructor was being run. But now it's being run twice: once from my $l = new LeadsView(); and once from $q = new QuestionsView(); since they both extend Config. I don't need or want to run that constructor twice, for obvious reasons.
So my question is: what's the proper way to set up a configuration class in a scenario like this? Should I create a Dbh class separate from Config, and just have all my questions, leads, etc. classes extend Dbh instead so they don't all run the Config methods as well? Is there some other obvious way to do this that I'm completely missing?
Your classes should never extend from Config or Database class or anything like that. This is not how polymorphism works.
In fact, your Config class isn't very useful. To make use of such class you need methods that actually help you perform prepared statements. The connect() method is not needed and you definitely do not need all the properties.
If we were going to fix this class then we could do something like this:
class Database {
protected $conn;
protected $flow_id;
protected $domain;
public function __construct(string $db) {
$this->flow_id = $_REQUEST['flow'];
$this->domain = $_SERVER['HTTP_HOST'];
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
// Load the variable from the config file
$this->conn = new mysqli($db_host, $db_user, $db_password, $db_name);
$this->conn->set_charset("utf8mb4");
}
//
// The rest of your database abstraction methods. Some methods that help you write parameterized queries more easily
// Without other methods this class would be useless!
}
The name of the class doesn't make sense. It is not a config class. It is an abstraction around mysqli. The config details should be stored in a separate file.
When you need to use this class in another class, simply require it as a parameter.
$db = new Database();
$l = new LeadsView($db);
This is called dependency injection. You should use this pattern in your code when working with OOP as it will make a lot of interactions between your classes much simpler. You can also implement IoC container. Nette has a good tutorial, but you can also use their implementation.
I would strongly recommend to don't reinvent the wheel. There are already good libraries that provide abstraction around PDO. Yes, PDO not mysqli. Do not waste your time with mysqli unless you have an extremely good reason to use mysqli. Use PDO with an abstraction library such as EasyDB
You are using inheritance. You probably want to use composition instead. Concretely this means providing the Config to LeadsView or Questionsview.
$config = new Config();
$leadsview = new LeadsView( $config );
class Config {
__construct() {
// do whatever
}
}
class LeadsView {
private $config;
__construct( $config ) {
$this->config = $config;
}
// use this->config somewhere in Leadsview to get whatever you need
}
To prevent the usage of multiple instances of Config you can use a single reference (this requires your discipline to enforce).
Otherwise you can create config as a singleton, which guarantees only one version of Config exists. If you want to know more about Singletons you can look it up, it's a very well know pattern.

Initialize php class with same name

If we have two or more classes with the same name, but in different folders, how would one differentiate between them during initialization?
require_once('database.php');
require_once('t/database.php');
$db = new Database(); // I want this to initialize the one in t/database.php
$globalDb = new Database(); // I want this to initialize database.php
This is what Namespaces are for.
But honestly, this sounds like an architectural problem. There are two ways you can approach this. If we were to answer your question as posed, you could solve your problem like so:
database.php
class Database{
// ...
}
t/database.php
namespace T;
class Database{
// ...
}
index.php
require_once('database.php');
require_once('t/database.php');
$db = new T\Database();
$globalDb = new Database();
But judging by your naming conventions, it appears as if you have two separate classes that are intended to interact with either the same - or similar - database instances.
I'm making some assumptions here, but the other way you can set up your logic is to condense your code down to a single Database class and operate on multiple connections over multiple instances.
Consider using dependency injection to manage your connections in a single unified class structure, especially if you're using the same type of RDBMS flavor across all connections.
Consider something like the following naive example:
class Database{
private $conn;
public function __construct(PDO $conn){
$this->conn = $conn;
}
public function select(...$args) { // Select Logic goes here }
public function insert(...$args) { // Insert Logic goes here }
public function update(...$args) { // Update Logic goes here }
public function delete(...$args) { // Delete Logic goes here }
}
It would be possible to operate over multiple connections at once by simply injecting different PDO instances into the same class:
require_once('database.php');
$conn1 = new PDO('mysql:host=localhost;dbname=test1', $user, $pass);
$conn2 = new PDO('mysql:host=localhost;dbname=test2', $user, $pass);
$db1 = new Database($conn1);
$db2 = new Database($conn2);
So while the first example may address your question directly, you may want to rethink your architecture if I'm on the right track with my second example.
And to echo everyone else, you should seriously consider using a proper Autoloader. Look into Composer and Autoloading - specifically PSR-4.
If we have two or more classes with the same name, but in different folders, how would one differentiate between them during initialization?
Don't do that. Loading the PHP file which contains the second definition will throw an error:
Fatal error: Cannot declare class Database, because the name is already in use
You will need to rename one of the classes.
As an aside, you may want to consider using an autoloader in your application instead of calling require() manually.

database parameters on function __construct

I am wondering if my understanding is right.
I placed my database connection parameter on my __construct(), so this means every time the class is instantiated, I also reconnect to my database, right?
private $handle;
public function __construct()
{
$username = "test";
$password = "9712nc*<?12";
$host = "localhost";
$db = "miner";
$dsn = 'mysql:dbname='.$db.';host='.$host;
try {
$this->handle = new PDO($dsn,$username,$password);
}
catch(PDOException $e) {
print $e->getMessage();
die();
}
}
Is this a good practice if I have many request from a certain user? Does this mean every time a user make a request (even if the request is just done minutes ago) the script should first connect to the database? Is there any appropriate way I can preserve my $handle?
BTW: The database connection is working fine.
If the class is instantiated once, then you're going to be just fine. In this case, you open one connection only.
If you instantiate the class several times, or use it as a static class, then you're potentially going to create a connection each time, which is not ideal.
If you keep the classes all active (i.e. you never delete reference to a class once you create it, from memory (I've never tested it) the internals of PHP should actually sort this out for you, and you'll still only have the one connection to the database. But if you lost a handle to the class you created, then the PDO will be destroyed and you start again. If you are using as a static class (i.e. you call it with class:function()), then you're on the wrong path.
There are two common solutions, and you'll find arguements for and against both of them.
1) Use a global for storing your DB connection. You create the $handle = PDO and store $handle as a global variable. Easy to pass around. Easy to overwrite - I'm not going to debate here.
2) Create a "static" class (commonly called a Singleton) that you recall. The basic structure would be
private static $ThisObj;
private static $handle;
public static function getInstance() {
if( !(self::$ThisObj instanceof SoapDB) ) {
self::$ThisObj = new SoapDB();
try {
$this->handle = new PDO_Handler('mysql:dbname=' . DB_NAME . ';host=' . DB_HOST, DB_USER, DB_PASS);
$this->handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
// Error Here
}
}
return self::$ThisObj;
}
Using this, you would normally create a separate DB class as a singleton. Using Singleton vs Global: your call (after research).
3) The third answer is if you are only ever calling your class above as a static (i.e. you call class::function()) then you can just make the $handle as a static and actually your problems should be wonderously solved. Essentially you're creating a Singleton, with the database as one of the properties.
Sorry that there's no wrong or right answer.
Edit based on comment "What's a static class":
Strictly speaking, I should say "class with static properties". To explain, normally you create a class with the syntax:
$myClass = new class();
$methodResult = $myClass->method();
and then do lots of nifty little things with $myClass by calling functions. You can then drop reference to the class, lose the properties (variables) and will reinitilaise later on.
A static class (for the purposes of this answer) is one where you have static properties. Normally (not absolutely) they are called by going.
$methodResult = class::method();
You don't hold on to the class - it gets initiated, used and dropped. However, if you store properties (vars) as static then each time you use that class, those properties will still exist in the state they last were. So method can set $this->MyVar = 'something' and next time, $this->MyVar will still be something.
Very useful for compartmentalising your code, stops functions overwriting others and can make unit testing easier.
(Note - I'm generalising to make it simpler. But it should give you an idea of the processes.)
You should use singleton.
try google 'mysql php singleton'
eg.
http://www.swhistlesoft.com/blog/2011/08/05/1435-mysql-singleton-class-to-allow-easy-and-clean-access-to-common-mysql-commands

Switching from PHP's mysql extension to PDO. Extend class to reduce lines of code

So this is something I've been meaning to get to grips with for ages. Converting a few small (single-file) applications to PDO. I can use PDO, connect to a database and run queries, all working.
But each time I initialise a new PDO, I'm also having to run
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Yeah it's only one line but one day I might need to add further stuff in there. To me it would seem better to somehow extend the PDO class in a way that can include that line so I can just start my DB connection with a single line. Creating my own class, even if only adding a single line of code at this stage, keeps me future-proofed if I ever decide to add anything else in the future.
I've found something like this...
class myPDO extends PDO {
public function __construct($dsn, $user=null, $pass=null, $options=null) {
parent::__construct($dsn, $user, $pass, $options);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
}
// THEN A SIMPLE 1 LINER TO CONNECT - USING TRY/CATCH AS WELL OF COURSE
$pdo_conn = new myPDO($cfg['pdo_dsn'], $cfg['pdo_user'], $cfg['pdo_pass'], $cfg['pdo_options']);
When extending the class I assume I don't actually need to re-create the constructor.
Is there a way I can integrate my $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); into my class without re-creating the constructor function?
I'm just getting started with PHP's class syntax so this will be a really basic question for someone but it will answer a few other questions for me at the same time.
You do not need to extend from PDO here. What you want is a central place in your application that is creating the PDO object. You can then do the changes you like over time (e.g. integrating some configuration file/system) and extend then centrally.
One thing is that you create a class for that, let's call it PdoFactory:
class PdoFactory
{
/**
* #return PDO
*/
public function buildPdo() {
$pdo = new PDO($dsn = 'xyz', $user = 'abc', $pass = '', $options = '');
if ($pdoException = true) {
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return $pdo;
}
}
Usage:
$factory = new PdoFactory();
$pdo = $factory->buildPdo();
As you can see, this is very easy to use. You can even put the place where you create the PdoFactory apart from the place where you invoke the buildPdo() function.
Also this makes it more clear that you are dealing with two different things here: First creating the Pdo object (encapsulated into a class of it's own) and the Pdo object itself which is just for accessing the database.
I hope this helps.
The problem, as I see it, is that you are hard-coding a particular error level into your application. What if you're in development and you want everything? What if you decide you want to change the level for a particular application? It would be much better to keep it as a parameter you set after the fact, or, if you're bent on subclassing it, pass an error level in as a constructor argument.

Categories