I have some questions about using MySQLi, queries, and related memory management. The code here is just to clarify my questions, so don\'t dump on it for error checking, etc. I
As rare as they are, in my opinion memory leaks are a nightmare to find and correct. I go out of my way to avoid them. Below is the pattern I use, based on the code you supplied:
$db = NULL;
try {
$dbPool = "p:$dbhost"; // question 3: use pooling
$db = new mysqli($dbPool, $un, $ps, $dbname);
if ($db->connect_errno) {
throw new Exception('' . $db->connect_error . ' ' . $db->connect_errno
. "\n" . $un . '@' . $dbhost . ' ' . $dbname);
// NOTE: It's commonly considered a security
// risk to output connection information e.g.
// host, user and database names.
}
$query = "SELECT field1, field2 ".
"FROM table1 ".
"WHERE field1={$some_value}";
$results = NULL;
try {
if (!$results = $db->query($query)) {
throw new Exception($db->error . " " . $db->errno
. "\n" . $query);
// NOTE: It's commonly considered a security
// risk to output SQL ($query).
}
while ($result = $results->fetch_object()) {
// Do something with the results
}
} catch (Exception $ex) {
// log, report, or otherwise handle the error
}
if ($results) {
$results->free(); // question 1: why risk it?
}
$query = "SELECT field1, field2 ".
"FROM table2 ".
"WHERE field1={$some_value2}";
$results = NULL;
try {
if (!$results = $db->query($query)) {
throw new Exception($db->error . " " . $db->errno
. "\n" . $query);
// NOTE: It's commonly considered a security
// risk to output SQL ($query).
}
while ($result = $results->fetch_object()) {
// Do something with the second set of results
}
} catch (Exception $ex) {
// log, report, or otherwise handle the error
}
if ($results) {
$results->free(); // question 2: again, why risk it?
}
} catch (Exception $ex) {
// log, report, or otherwise handle the error
}
if ($db) {
$db->close();
}
In my opinion, connection pooling increases the chances for a memory leak, but according to the manual, the connection pooling libraries do a lot of cleanup for you automatically:
The persistent connection of the mysqli extension however provides built-in cleanup handling code. The cleanup carried out by mysqli includes:
Rollback active transactions
Close and drop temporary tables
Unlock tables
Reset session variables
Close prepared statements (always happens with PHP)
Close handler
Release locks acquired with GET_LOCK()
This ensures that persistent connections are in a clean state on return from the connection pool, before the client process uses them.
source: http://php.net/manual/en/mysqli.persistconns.php
I also agree with Pascal MARTIN that it's a good idea to open your connection at the beginning of your script and close it at the end. I think connection pooling makes that less important, but still a good idea.