or if it does so itself when the scripts ends?
Yes, sure, PHP automatically close and clean up all the resources that has been opened during script execution, so, don't worry to close it manually.
Anyway, to nullify conn, just nullify it: $this->conn = NULL
;
But all that stuff is utterly negligible compared to the other problems of your class, which is insecure, inefficient and unusable.
- First of all, I have no idea why would you want to make this class abstract. Abstract classes are prototype classes, used to be source of other classes. But a database wrapper is rather a ready to use final class. I see no point in making it abstract.
- Error reporting is also superfluous and inconsistent. Adding "Error In SELECT STATMENT" to the error message is quite useless. While connection error handling is plainly wrong. Instead, let PDO to throw an exception and just let it go. It will be handled the same way as any other error in your site.
- Next problem is security. For some reason neither
select()
not insert()
function supports prepared statements, which renders them quite useless: you can use PDO::query() instead, with exactly the same outcome. But what you really have to is to use prepare/execute properly, by using placeholders in the query while sending actual variables to execute()
;
- Another problem is duplicated code: both functions are pretty much the same.
- And at the same time both function are quite unreliable:
select()
function is limited to only one type of result set, while insert()
doesn't return anything at all. Instead, you can use just single function to run all your queries, and make it return the statement, which will be extremely useful. It will let you to get the returned data in dozens different formats supported by PDO, and even let you to get the number of affected rows from DML queries.
Let me suggest you another approach, a simple PDO wrapper that can let you to use PDO most simple and secure way:
<?php
define('DB_HOST', 'localhost');
define('DB_NAME', 'test');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_CHAR', 'utf8');
class DB
{
protected static $instance = null;
public function __construct() {}
public function __clone() {}
public static function instance()
{
if (self::$instance === null)
{
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => TRUE,
);
$dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHAR;
self::$instance = new PDO($dsn, DB_USER, DB_PASS, $opt);
}
return self::$instance;
}
public static function __callStatic($method, $args)
{
return call_user_func_array(array(self::instance(), $method), $args);
}
public static function run($sql, $args = [])
{
$stmt = self::instance()->prepare($sql);
$stmt->execute($args);
return $stmt;
}
}
It's extremely powerful, secure, and easy to use.
You can use any PDO function by simply adding it's call after DB::
prefix:
$stmt = DB::query("SELECT * FROM table WHERE foo='bar'");
So, in the first place, it's a PDO wrapper, which is able to run any PDO method by means of using magic __call()
method. The only function I added is run()
.
Instead of your own insecure and unreliable select()
and insert()
methods let me suggest you to use one universal run()
method, which is nothing more than a shorthand to these three lines:
$stmt = DB::prepare($query);
$stmt->execute($params);
$data = $stmt->fetch();
So, instead you can write it as a neat one-liner:
$data = DB::run($query, $params)->fetch();
Note that it can run a query of any kind and return the result in any format that PDO supports.
I wrote an article about this simple wrapper, where you can find some usage examples. All the example code can be run as is, just copy and paste it in your script and set up credentials: http://phpdelusions.net/pdo/pdo_wrapper#samples