I have created a DB connector class with PDO.
Do I need to add, delete or edit anything in this code?
<?php
class Config extends model{
// The state of the config
public $configState = array();
// THE only instance of the class
private static $instance;
public function __construct(){}
/**
* Returns THE instance of 'Config'.
* The config is automatically initialized if it wasn't.
*
* @return object
**/
public static function getInstance(){
if ( !isset(self::$instance)){
self::$instance = new self;
}
self::$instance->startConf();
return self::$instance;
}
public function startConf(){
if (empty($this->configState)){
$this->resetState();
}
return $this;
}
/**
* Stores datas in the Config.
* Example: $instance->foo = 'bar';
* @param $key
* @param $val
*/
public function __set( $key , $val ){
$this->configState[$key] = $val;
}
/**
* Gets datas from the Config.
* Example: echo $instance->foo;
*
* @param $key
* @return bool
*/
public function __get( $key ){
return (isset($this->configState[$key]))? $this->configState[$key]: false;
}
public function __isset( $key ){
return isset($this->configState[$key]);
}
public function __unset( $key ){
unset( $this->configState[$key] );
}
public function destroy(){
$this->configState = array();
}
public function resetState(){
$this->configState = array();
$this->configState['show_php_errors'] = true;
$this->configState['SSL_security'] = true;
$this->configState['XFO_security'] = true;
$this->configState['XSS_security'] = true;
$this->configState['CSRF_security'] = true;
$this->configState['db_type'] = "mysql";
$this->configState['db_host'] = "localhost";
$this->configState['db_port'] = 3306;
$this->configState['db_name'] = "demo";
$this->configState['db_user'] = "root";
$this->configState['db_pass'] = "";
$this->configState['db_path'] = "";
}
}
class PDOConnection{
private $instance;
private $dsn;
private $username;
private $password;
private $options = [];
/**
* constructor
*
* @param $dsn
* @param $username
* @param $password
* @param array $options
*/
public function __construct($dsn, $username, $password, array $options = []) {
$this->dsn = $dsn;
$this->username = $username;
$this->password = $password;
$this->options = $options;
}
/**
* Setting attributes on instance
*
* @param $name
* @param $value
* @return mixed|void
*/
public function setAttribute($name, $value) {
if(!$this->instance instanceof PDO) {
throw new LogicException('Cannot set PDO attribute. Please make sure you are connected using the connect() method.');
}
if($this->instance->setAttribute($name, $value) === false) {
throw new LogicException('Could not set PDO attribute: ' . $name);
}
}
/**
* Setting options
*
* @param $name
* @param $value
*/
public function setOption($name, $value) {
$this->options[$name] = $value;
}
/**
* getting connection
* @return PDO
*/
public function getConnection() {
if(!$this->instance instanceof PDO) {
throw new LogicException('No database connection established.');
}
return $this->instance;
}
/**
* connecting to database
*
* @throws ErrorException
*/
public function connect() {
try {
$this->instance = new PDO($this->dsn, $this->username, $this->password, $this->options);
}catch(PDOException $exception) {
throw new ErrorException('Could not connect to the database!', null, $exception);
}
}
/**
* disconnecting from database
*/
public function disconnect() {
$this->instance = null;
}
}
class database{
private $dbh;
private $executed = false;
private $stmt;
/**
* constructor
**/
public function __construct(){
$conf = Config::getInstance();
switch($conf->db_type){
case "mysql":
$dsn = "mysql:host=$conf->db_host;port=$conf->db_port;dbname=$conf->db_name";
break;
case "sqlite":
$dsn = "sqlite:$conf->db_path;";
break;
case "postgresql":
$dsn = "pgsql:host=$conf->db_host;port=$conf->db_port;dbname=$conf->db_name";
break;
default:
$dsn = "mysql:host=$conf->db_host;port=$conf->db_port;dbname=$conf->db_name";
}
$dsn .= ';charset=utf8';
$connection = new PDOConnection($dsn, $conf->db_user, $conf->db_pass, array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_TIMEOUT => 60*60*60*60,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
));
$connection->connect();
$this->dbh = $connection->getConnection();
}
/**
* Provides access to the application PDO instance.
*
* @return \PDO
*/
public function pdo() {
return $this->dbh;
}
/**
* set query statement
*
* @param $query
*
* @return $this
*/
public function query($query){
/** @noinspection PhpUndefinedMethodInspection */
$this->stmt = $this->dbh->prepare($query);
return $this;
}
/**
* binding database
*
* @param $param
* @param $value
* @param null $type
*
* @return $this
*/
public function bind($param, $value, $type = null){
if (is_null($type)) {
switch (true) {
case is_string($value):
$type = PDO::PARAM_STR;
break;
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
break;
default:
$type = PDO::PARAM_STR;
}
}
/** @noinspection PhpUndefinedMethodInspection */
$this->stmt->bindValue($param, $value, $type);
return $this;
}
/**
* executing query statement
*
* @return $this
*/
public function execute(){
/** @noinspection PhpUndefinedMethodInspection */
$this->stmt->execute();
$this->executed = true;
return $this;
}
/**
* fetching all result
*
* @param int $fetch
*
* @param null $class
* @param array $args
* @return mixed
*/
public function FetchAll($fetch = PDO::FETCH_ASSOC, $class = null, array $args = []){
$this->execute();
if(!is_null($class) && in_array($fetch, [PDO::FETCH_CLASS, PDO::FETCH_OBJ])) {
/** @noinspection PhpUndefinedMethodInspection */
return $this->stmt->fetchAll(PDO::FETCH_CLASS, $class, $args);
}
/** @noinspection PhpUndefinedMethodInspection */
return $this->stmt->fetchAll($fetch);
}
/**
* fetching first result only
*
* @param int $fetch
*
* @param null $class
* @param array $args
* @return mixed
*/
public function FetchOne($fetch = PDO::FETCH_ASSOC, $class = null, array $args = []){
$this->execute();
if(!is_null($class) && in_array($fetch, [PDO::FETCH_CLASS, PDO::FETCH_OBJ])) {
/** @noinspection PhpUndefinedMethodInspection */
return $this->stmt->fetchObject($class, $args);
}
/** @noinspection PhpUndefinedMethodInspection */
return $this->stmt->fetch($fetch);
}
/**
* fetching column
*
* @param int $columnNumber
*
* @return mixed
*/
public function FetchColumn($columnNumber=0){
$this->execute();
/** @noinspection PhpUndefinedMethodInspection */
return $this->stmt->fetchColumn($columnNumber);
}
/**
* counting rows
*
* @return mixed
*/
public function rowCount(){
/** @noinspection PhpUndefinedMethodInspection */
return $this->stmt->rowCount();
}
/**
* counting columns
* @return mixed
*/
public function columnCount(){
/** @noinspection PhpUndefinedMethodInspection */
return $this->stmt->columnCount();
}
/**
* getting last inserted ID
* @return string
*/
public function lastInsertId(){
return $this->dbh->lastInsertId();
}
/**
* starting transaction
*
* @return bool
*/
public function beginTransaction(){
return $this->dbh->beginTransaction();
}
/**
* ending transaction
* @return bool
*/
public function endTransaction(){
/** @noinspection PhpUndefinedMethodInspection */
return $this->dbh->commit();
}
/**
* transaction savepoint
*
* @param $savepoint_name
*
* @return $this
*/
public function TransactionSavepoint($savepoint_name){
$this->query("SAVEPOINT :savepointname");
$this->bind(':savepointname',$savepoint_name);
$this->execute();
return $this;
}
/**
* canceling transaction
*
* @return bool
*/
public function cancelTransaction(){
/** @noinspection PhpUndefinedMethodInspection */
return $this->dbh->rollBack();
}
/**
* debuging dump parameters
*
* @return mixed
*/
public function debugDumpParams(){
/** @noinspection PhpUndefinedMethodInspection */
return $this->stmt->debugDumpParams();
}
/**
* Reset the execution flag.
*/
public function closeCursor() {
/** @noinspection PhpUndefinedMethodInspection */
$this->stmt->closeCursor();
$this->executed = false;
}
}
and Usage:
$db = new database();
$info = $db->query("SEKECT * FROM `table`")->FetchAll();
I need to be sure that this classes are secure for injections and they are optimized for memory usage; any & all other feedback is also welcome.
"SELECT * FROM
table"
rather thanSEKECT
\$\endgroup\$