PDO class ¿wrapper?
up vote
0
down vote
favorite
I'm writing one custom class for PDO connection.
I want these advantages:
- Protect credentials: user, password ...
- Facilitate maintenance: facing future password changes for example
- Facilitate connection:
$pdo=new MyPDO();
- Provide my class with all the PDO functionalities
I write my class as you can see here:
For protect credentials i saved them into a ini file:
<?php return; ?>
; credentials
host=localhost
user=myUser
pass="my/very/secure/password.../UqMsN[)VPn&gunmv3KzE?3Q&Qw/..."
dbname=myDataBase
The class
class MyPDO extends PDO
{
public function __construct()
{
$iniData = parse_ini_file("//home/.credentials/db.php.ini");
$host=$iniData["host"];
$dbname=$iniData["dbname"];
$user=$iniData["user"];
$pass=$iniData["pass"];
$dsn = "mysql:host=$host;dbname=$dbname";
$options = array(
PDO::ATTR_PERSISTENT => FALSE,
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"
);
try {
parent::__construct($dsn, $user, $pass, $options);
} catch (PDOException $e) {
error_log($this->error = $e->getMessage(),0);
}
}
}
?>
Usage example
include_once('MyPDO.php');
$pdo=new MyPDO();
/*Use any PDO method*/
$pdo->query(...);
$pdo->prepare(...);
$pdo->execute(...);
php pdo
New contributor
A. Cedano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
up vote
0
down vote
favorite
I'm writing one custom class for PDO connection.
I want these advantages:
- Protect credentials: user, password ...
- Facilitate maintenance: facing future password changes for example
- Facilitate connection:
$pdo=new MyPDO();
- Provide my class with all the PDO functionalities
I write my class as you can see here:
For protect credentials i saved them into a ini file:
<?php return; ?>
; credentials
host=localhost
user=myUser
pass="my/very/secure/password.../UqMsN[)VPn&gunmv3KzE?3Q&Qw/..."
dbname=myDataBase
The class
class MyPDO extends PDO
{
public function __construct()
{
$iniData = parse_ini_file("//home/.credentials/db.php.ini");
$host=$iniData["host"];
$dbname=$iniData["dbname"];
$user=$iniData["user"];
$pass=$iniData["pass"];
$dsn = "mysql:host=$host;dbname=$dbname";
$options = array(
PDO::ATTR_PERSISTENT => FALSE,
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"
);
try {
parent::__construct($dsn, $user, $pass, $options);
} catch (PDOException $e) {
error_log($this->error = $e->getMessage(),0);
}
}
}
?>
Usage example
include_once('MyPDO.php');
$pdo=new MyPDO();
/*Use any PDO method*/
$pdo->query(...);
$pdo->prepare(...);
$pdo->execute(...);
php pdo
New contributor
A. Cedano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
So you actually exposed your credentials to anyone who wold have a whim of navigating to .credentials/db.php.ini
– Your Common Sense
12 hours ago
1
@YourCommonSense thaks for your comment. The credentials are not exposed. 1º. The folder is out ofpublic_html, then, non navigation possible (i'm using shared hosting). 2º. The first line:<?php return; ?>prevents to show the file content in case of access to fila via browser. I think the info is protected so.
– A. Cedano
12 hours ago
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I'm writing one custom class for PDO connection.
I want these advantages:
- Protect credentials: user, password ...
- Facilitate maintenance: facing future password changes for example
- Facilitate connection:
$pdo=new MyPDO();
- Provide my class with all the PDO functionalities
I write my class as you can see here:
For protect credentials i saved them into a ini file:
<?php return; ?>
; credentials
host=localhost
user=myUser
pass="my/very/secure/password.../UqMsN[)VPn&gunmv3KzE?3Q&Qw/..."
dbname=myDataBase
The class
class MyPDO extends PDO
{
public function __construct()
{
$iniData = parse_ini_file("//home/.credentials/db.php.ini");
$host=$iniData["host"];
$dbname=$iniData["dbname"];
$user=$iniData["user"];
$pass=$iniData["pass"];
$dsn = "mysql:host=$host;dbname=$dbname";
$options = array(
PDO::ATTR_PERSISTENT => FALSE,
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"
);
try {
parent::__construct($dsn, $user, $pass, $options);
} catch (PDOException $e) {
error_log($this->error = $e->getMessage(),0);
}
}
}
?>
Usage example
include_once('MyPDO.php');
$pdo=new MyPDO();
/*Use any PDO method*/
$pdo->query(...);
$pdo->prepare(...);
$pdo->execute(...);
php pdo
New contributor
A. Cedano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
I'm writing one custom class for PDO connection.
I want these advantages:
- Protect credentials: user, password ...
- Facilitate maintenance: facing future password changes for example
- Facilitate connection:
$pdo=new MyPDO();
- Provide my class with all the PDO functionalities
I write my class as you can see here:
For protect credentials i saved them into a ini file:
<?php return; ?>
; credentials
host=localhost
user=myUser
pass="my/very/secure/password.../UqMsN[)VPn&gunmv3KzE?3Q&Qw/..."
dbname=myDataBase
The class
class MyPDO extends PDO
{
public function __construct()
{
$iniData = parse_ini_file("//home/.credentials/db.php.ini");
$host=$iniData["host"];
$dbname=$iniData["dbname"];
$user=$iniData["user"];
$pass=$iniData["pass"];
$dsn = "mysql:host=$host;dbname=$dbname";
$options = array(
PDO::ATTR_PERSISTENT => FALSE,
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"
);
try {
parent::__construct($dsn, $user, $pass, $options);
} catch (PDOException $e) {
error_log($this->error = $e->getMessage(),0);
}
}
}
?>
Usage example
include_once('MyPDO.php');
$pdo=new MyPDO();
/*Use any PDO method*/
$pdo->query(...);
$pdo->prepare(...);
$pdo->execute(...);
php pdo
php pdo
New contributor
A. Cedano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
A. Cedano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
A. Cedano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked 13 hours ago
A. Cedano
1011
1011
New contributor
A. Cedano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
A. Cedano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
A. Cedano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
So you actually exposed your credentials to anyone who wold have a whim of navigating to .credentials/db.php.ini
– Your Common Sense
12 hours ago
1
@YourCommonSense thaks for your comment. The credentials are not exposed. 1º. The folder is out ofpublic_html, then, non navigation possible (i'm using shared hosting). 2º. The first line:<?php return; ?>prevents to show the file content in case of access to fila via browser. I think the info is protected so.
– A. Cedano
12 hours ago
add a comment |
So you actually exposed your credentials to anyone who wold have a whim of navigating to .credentials/db.php.ini
– Your Common Sense
12 hours ago
1
@YourCommonSense thaks for your comment. The credentials are not exposed. 1º. The folder is out ofpublic_html, then, non navigation possible (i'm using shared hosting). 2º. The first line:<?php return; ?>prevents to show the file content in case of access to fila via browser. I think the info is protected so.
– A. Cedano
12 hours ago
So you actually exposed your credentials to anyone who wold have a whim of navigating to .credentials/db.php.ini
– Your Common Sense
12 hours ago
So you actually exposed your credentials to anyone who wold have a whim of navigating to .credentials/db.php.ini
– Your Common Sense
12 hours ago
1
1
@YourCommonSense thaks for your comment. The credentials are not exposed. 1º. The folder is out of
public_html, then, non navigation possible (i'm using shared hosting). 2º. The first line: <?php return; ?> prevents to show the file content in case of access to fila via browser. I think the info is protected so.– A. Cedano
12 hours ago
@YourCommonSense thaks for your comment. The credentials are not exposed. 1º. The folder is out of
public_html, then, non navigation possible (i'm using shared hosting). 2º. The first line: <?php return; ?> prevents to show the file content in case of access to fila via browser. I think the info is protected so.– A. Cedano
12 hours ago
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
There are several areas for improvement.
- First of all, it violates the Liskov substitution principle. I am guilty for doing it too, so I cannot blame you too much but if you want your code to follow the best practices, it's better to make your class not extend PDO but either make a PDO instance a property of your class publicly accessible through a property or a method, or you can re-create in your class all the functionality supported by PDO.
Next, error reporting for the connection is rather inflexible. An exception is a precious thing that can be handled in many different ways, logging included. So I would rather re-throw a new exception, like
try {
parent::__construct($dsn, $user, $pass, $options);
} catch (PDOException $e) {
throw new PDOException($e->getMessage(), (int)$e->getCode());
}
so it can be caught elsewhere or simply logged if a corresponding PHP configuration directive says so.
- Connection encoding is better to be set in the DSN, as it's going to be more generic and supported by all drivers.
- reading the configuration right in the class violates the Single responsibility principle. I would make this class to accept an array of parameters, as to where these parameters are taken from - from .ini, .yml or .env file - is a distinct matter.
- And all the hassle related to protecting the configuration should be delegated elsewhere. After all, database credentials are not only settings that have to be protected - there are admin email, salt, API keys, etc.
- protecting an ini file adding .php as one of its extensions is too risky. it would work merely by accident. Why not to name it straight
settings.phpand thus make sure it will be always interpreted as PHP as long as it is called through a web-server with PHP support. - I would also add a possibility to add/override the PDO options
So I would make your class
class DB
{
protected $connection;
public function __construct($config)
{
$dsn = "mysql:host=$config[host];dbname=$config[dbname];charset=$config[charset]";
$options = array(
PDO::ATTR_PERSISTENT => FALSE,
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
if (isset($config['options'])) {
$options = array_merge($options, $config['options']);
}
try {
$this->connection = new PDO ($dsn, $config['user'], $config['pass'], $options);
} catch (PDOException $e) {
throw new PDOException($e->getMessage(), (int)$e->getCode());
}
}
public function conn() {
return $this->connection;
}
}
used as
$db = new DB($config);
$stmt = $db->conn()->query('SELECT * FROM users');
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
There are several areas for improvement.
- First of all, it violates the Liskov substitution principle. I am guilty for doing it too, so I cannot blame you too much but if you want your code to follow the best practices, it's better to make your class not extend PDO but either make a PDO instance a property of your class publicly accessible through a property or a method, or you can re-create in your class all the functionality supported by PDO.
Next, error reporting for the connection is rather inflexible. An exception is a precious thing that can be handled in many different ways, logging included. So I would rather re-throw a new exception, like
try {
parent::__construct($dsn, $user, $pass, $options);
} catch (PDOException $e) {
throw new PDOException($e->getMessage(), (int)$e->getCode());
}
so it can be caught elsewhere or simply logged if a corresponding PHP configuration directive says so.
- Connection encoding is better to be set in the DSN, as it's going to be more generic and supported by all drivers.
- reading the configuration right in the class violates the Single responsibility principle. I would make this class to accept an array of parameters, as to where these parameters are taken from - from .ini, .yml or .env file - is a distinct matter.
- And all the hassle related to protecting the configuration should be delegated elsewhere. After all, database credentials are not only settings that have to be protected - there are admin email, salt, API keys, etc.
- protecting an ini file adding .php as one of its extensions is too risky. it would work merely by accident. Why not to name it straight
settings.phpand thus make sure it will be always interpreted as PHP as long as it is called through a web-server with PHP support. - I would also add a possibility to add/override the PDO options
So I would make your class
class DB
{
protected $connection;
public function __construct($config)
{
$dsn = "mysql:host=$config[host];dbname=$config[dbname];charset=$config[charset]";
$options = array(
PDO::ATTR_PERSISTENT => FALSE,
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
if (isset($config['options'])) {
$options = array_merge($options, $config['options']);
}
try {
$this->connection = new PDO ($dsn, $config['user'], $config['pass'], $options);
} catch (PDOException $e) {
throw new PDOException($e->getMessage(), (int)$e->getCode());
}
}
public function conn() {
return $this->connection;
}
}
used as
$db = new DB($config);
$stmt = $db->conn()->query('SELECT * FROM users');
add a comment |
up vote
0
down vote
There are several areas for improvement.
- First of all, it violates the Liskov substitution principle. I am guilty for doing it too, so I cannot blame you too much but if you want your code to follow the best practices, it's better to make your class not extend PDO but either make a PDO instance a property of your class publicly accessible through a property or a method, or you can re-create in your class all the functionality supported by PDO.
Next, error reporting for the connection is rather inflexible. An exception is a precious thing that can be handled in many different ways, logging included. So I would rather re-throw a new exception, like
try {
parent::__construct($dsn, $user, $pass, $options);
} catch (PDOException $e) {
throw new PDOException($e->getMessage(), (int)$e->getCode());
}
so it can be caught elsewhere or simply logged if a corresponding PHP configuration directive says so.
- Connection encoding is better to be set in the DSN, as it's going to be more generic and supported by all drivers.
- reading the configuration right in the class violates the Single responsibility principle. I would make this class to accept an array of parameters, as to where these parameters are taken from - from .ini, .yml or .env file - is a distinct matter.
- And all the hassle related to protecting the configuration should be delegated elsewhere. After all, database credentials are not only settings that have to be protected - there are admin email, salt, API keys, etc.
- protecting an ini file adding .php as one of its extensions is too risky. it would work merely by accident. Why not to name it straight
settings.phpand thus make sure it will be always interpreted as PHP as long as it is called through a web-server with PHP support. - I would also add a possibility to add/override the PDO options
So I would make your class
class DB
{
protected $connection;
public function __construct($config)
{
$dsn = "mysql:host=$config[host];dbname=$config[dbname];charset=$config[charset]";
$options = array(
PDO::ATTR_PERSISTENT => FALSE,
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
if (isset($config['options'])) {
$options = array_merge($options, $config['options']);
}
try {
$this->connection = new PDO ($dsn, $config['user'], $config['pass'], $options);
} catch (PDOException $e) {
throw new PDOException($e->getMessage(), (int)$e->getCode());
}
}
public function conn() {
return $this->connection;
}
}
used as
$db = new DB($config);
$stmt = $db->conn()->query('SELECT * FROM users');
add a comment |
up vote
0
down vote
up vote
0
down vote
There are several areas for improvement.
- First of all, it violates the Liskov substitution principle. I am guilty for doing it too, so I cannot blame you too much but if you want your code to follow the best practices, it's better to make your class not extend PDO but either make a PDO instance a property of your class publicly accessible through a property or a method, or you can re-create in your class all the functionality supported by PDO.
Next, error reporting for the connection is rather inflexible. An exception is a precious thing that can be handled in many different ways, logging included. So I would rather re-throw a new exception, like
try {
parent::__construct($dsn, $user, $pass, $options);
} catch (PDOException $e) {
throw new PDOException($e->getMessage(), (int)$e->getCode());
}
so it can be caught elsewhere or simply logged if a corresponding PHP configuration directive says so.
- Connection encoding is better to be set in the DSN, as it's going to be more generic and supported by all drivers.
- reading the configuration right in the class violates the Single responsibility principle. I would make this class to accept an array of parameters, as to where these parameters are taken from - from .ini, .yml or .env file - is a distinct matter.
- And all the hassle related to protecting the configuration should be delegated elsewhere. After all, database credentials are not only settings that have to be protected - there are admin email, salt, API keys, etc.
- protecting an ini file adding .php as one of its extensions is too risky. it would work merely by accident. Why not to name it straight
settings.phpand thus make sure it will be always interpreted as PHP as long as it is called through a web-server with PHP support. - I would also add a possibility to add/override the PDO options
So I would make your class
class DB
{
protected $connection;
public function __construct($config)
{
$dsn = "mysql:host=$config[host];dbname=$config[dbname];charset=$config[charset]";
$options = array(
PDO::ATTR_PERSISTENT => FALSE,
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
if (isset($config['options'])) {
$options = array_merge($options, $config['options']);
}
try {
$this->connection = new PDO ($dsn, $config['user'], $config['pass'], $options);
} catch (PDOException $e) {
throw new PDOException($e->getMessage(), (int)$e->getCode());
}
}
public function conn() {
return $this->connection;
}
}
used as
$db = new DB($config);
$stmt = $db->conn()->query('SELECT * FROM users');
There are several areas for improvement.
- First of all, it violates the Liskov substitution principle. I am guilty for doing it too, so I cannot blame you too much but if you want your code to follow the best practices, it's better to make your class not extend PDO but either make a PDO instance a property of your class publicly accessible through a property or a method, or you can re-create in your class all the functionality supported by PDO.
Next, error reporting for the connection is rather inflexible. An exception is a precious thing that can be handled in many different ways, logging included. So I would rather re-throw a new exception, like
try {
parent::__construct($dsn, $user, $pass, $options);
} catch (PDOException $e) {
throw new PDOException($e->getMessage(), (int)$e->getCode());
}
so it can be caught elsewhere or simply logged if a corresponding PHP configuration directive says so.
- Connection encoding is better to be set in the DSN, as it's going to be more generic and supported by all drivers.
- reading the configuration right in the class violates the Single responsibility principle. I would make this class to accept an array of parameters, as to where these parameters are taken from - from .ini, .yml or .env file - is a distinct matter.
- And all the hassle related to protecting the configuration should be delegated elsewhere. After all, database credentials are not only settings that have to be protected - there are admin email, salt, API keys, etc.
- protecting an ini file adding .php as one of its extensions is too risky. it would work merely by accident. Why not to name it straight
settings.phpand thus make sure it will be always interpreted as PHP as long as it is called through a web-server with PHP support. - I would also add a possibility to add/override the PDO options
So I would make your class
class DB
{
protected $connection;
public function __construct($config)
{
$dsn = "mysql:host=$config[host];dbname=$config[dbname];charset=$config[charset]";
$options = array(
PDO::ATTR_PERSISTENT => FALSE,
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
if (isset($config['options'])) {
$options = array_merge($options, $config['options']);
}
try {
$this->connection = new PDO ($dsn, $config['user'], $config['pass'], $options);
} catch (PDOException $e) {
throw new PDOException($e->getMessage(), (int)$e->getCode());
}
}
public function conn() {
return $this->connection;
}
}
used as
$db = new DB($config);
$stmt = $db->conn()->query('SELECT * FROM users');
edited 7 hours ago
answered 10 hours ago
Your Common Sense
3,291526
3,291526
add a comment |
add a comment |
A. Cedano is a new contributor. Be nice, and check out our Code of Conduct.
A. Cedano is a new contributor. Be nice, and check out our Code of Conduct.
A. Cedano is a new contributor. Be nice, and check out our Code of Conduct.
A. Cedano is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209517%2fpdo-class-wrapper%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
So you actually exposed your credentials to anyone who wold have a whim of navigating to .credentials/db.php.ini
– Your Common Sense
12 hours ago
1
@YourCommonSense thaks for your comment. The credentials are not exposed. 1º. The folder is out of
public_html, then, non navigation possible (i'm using shared hosting). 2º. The first line:<?php return; ?>prevents to show the file content in case of access to fila via browser. I think the info is protected so.– A. Cedano
12 hours ago