Why are we closing the $result
$mysqli = new mysqli("localhost", "root", "root", "test");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: " . $mysqli->connect_error;
}
if ($result = $mysqli->query("Select * from user")) {
while ($row = $result->fetch_object())
{
//var_dump($row);
}
$result->close();
}
Your check if the connection failed falls through to the code that uses the connection. Obviously that won't work because it's not a live connection. Make sure that if the connection fails, code that depends on it is not reached. (Note that I'm not necessary advocating use of exit or die. They can make for a rather bad user experience. They can be useful, but ideally you should output a better message and leave the ugly error stuff for logs [unless you're only testing or it's a command line script]).
As for close() (which is actually an alias for free()):
free() basically deallocates all of the stuff attached to result. You need to understand that there are two (simplification, but go with it) ways of retrieving rows:
Buffered - Everything is snatched in one go. In other words, by the time you start looping through the records, they're all actually already in memory. They are buffered. They are not being pulled from the server every time you call fetch() but rather are being pulled from memory.
Non buffered - there may be a small buffer, but essentially every time you call fetch(), PHP must pull a new row from the database. At the beginning of the loop, they are not all sitting in memory.
Interesting note: num_rows() can be called on a buffered query very efficiently since all of the rows are already pulled (though you should never pull all of the rows just to count them -- that's what COUNT is for). Non buffered queries cannot do num_rows() until they pull all of the rows. Meaning it will either be an error, or will essentially turn it into a buffered query.
Anyway, back to your actual question:
free() frees anything associated with the result object. In the case of a buffered query, this is any rows sitting in memory. In the case of a non buffered query, free() will release whatever rows may be sitting in memory and then cancel the rest of the request. Basically its PHP telling MySQL, "Hey you know all those rows I request? Changed my mind. You can just drop that request."
As for if you should free results... Well, whenever the variable goes out of scope*, it will happen anyway. There is, however, no harm in explicitly doing it, and in situations where a query may use a lot of memory and then another query after it may use a lot of memory, you may wish to free the sets just to keep memory usage low.
* Or maybe when the request ends. I don't remember off the top of my head.