Reputation: 27
My Database Class in PHP is shown below. Is it considered a best practice to have a destruct function?
<?php
class Database{
private $host;
private $username;
private $password;
private $database;
private $conn;
public function __construct($host, $username, $password, $database){
$this->host = $host;
$this->username = $username;
$this->password = $password;
$this->database = $database;
$this->connect();
}
public function connect(){
try{
$this->conn = new PDO('mysql:host=' . $this->host . ';dbname=' . $this->database, $this->username, $this->password);
} catch(PDOException $e){
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
}
public function runSQL($query, $params=null){
try {
$statement = $this->conn->prepare($query);
$statement->execute($params);
return true;
} catch (PDOException $e) {
print "Error" . $e->getMessage();
}
}
public function close(){
$this->conn = null;
}
/*
// is this needed??
function __destruct() {
$this->conn->close();
}
*/
}
?>
My concerns for not needing- and therefore I have excluded it from my scripts- are:
Wouldn't the database connection be closed anyways after the script is run?
If I have several calls to the database in a single script, would closing the connection on one interfere with subsequent calls? Example below:
$db = new Database( [configuration here]);
function one($db) {
$sql = " ...";
return $db->runSQL($sql;
}
function two($db) {
$sql = " ...";
return $db->runSQL($sql);
}
// this should be fine
$x = one($db);
// if the destruct is in place,
// wouldn't I get an error here?
$y = two($db);
Everything works fine without the destruct being included, but I'm concerned if this is susceptible to memory leaks.
Thank you in advance :)
Upvotes: 0
Views: 637
Reputation: 32232
Generally, unless you have a specific reason you don't need to define a destructor or explicitly close connections in PHP.
Within the most common use case of PHP, CGI web services, processes only live for the span of a single HTTP request. At the end of of the request all resources are garbage-collected and as a result all connections are implicitly closed as though you had called their respective close()
.
If, for the sake of example, you are writing a persistent, long-running daemon you may then have a reason to worry about open connections. However, resources that are unset or otherwise go out of scope are eventually garbage collected and any connection resources will be implicitly closed.
If I had to make a strawman argument for destructors, let's say the app needs to talk to a service over a raw TCP socket, and to gracefully close the connection a final command needed to be issued, then I would write a destructor like:
public function __destruct() {
$this->conn->send("QUIT");
$this->conn->close();
}
and even in that case it would likely not be a problem for the majority of well-designed services as the connection being closed from the other side is a pretty clear indicator that the session is over.
And none of this is to say that you can't or shouldn't explicitly close connections or write destructors, it's just that in the vast majority of cases it's not making much of a difference one way or the other.
Upvotes: 1