When should i call mysqli::close? I never used to use if statements to check whether bind_param(), prep() and execute() were successful. Should I call $stmt->close() at the end of the method(below) . Or should I call it after every condition ensuring that I close the database connection even if the process fails at some stage e.g bind param.
public function function_name($id,$new_id ){
$query = "UPDATE TABLE SET name = ? WHERE field = ? ";
if($stmt=$this->prepare($query)){
if($stmt->bind_param("is", $id, $new_id)){
if($stmt->execute()){
}else{//Could not execute the prepared statement
$message = "Could not execute the prepared statement";
}
}else{//Could not bind the parameters
$message = "Could not bind the parameters";
}
}else{
$message = "Could not prepare the statement";
}
return $message
}
When PHP exits it closes the database connections gracefully.
The only reason to use the close method is when you want to terminate a database connection that you´ll not use anymore, and you have lots of thing to do: Like processing and streaming the data, but if this is quick, you can forget about the close statement.
Putting it in the end of a script means redundancy, no performance or memory gain.
Whats is important: unset unused data, and if you will want to avoid memory leaks (which in my humble opnion are problem of PHP core in this case) use:
mysqli_kill();
mysqli_close();
This way the socket is killed too.
You should always gracefully close the connection when you are done with it, to avoid performance and memory/handle leak problems. On the other hand, you should also make sure that you really are done with it - your script will crash if you try to use a closed connection.
The same goes for statements. If a statement is no longer going to be used, dispose of it appropriately.
Just a little thought you could create another method called function_close and call it after you have called the function_name method.
This way if you change to pdo or mongo you will just have to refactor the methords rather than every instance of close.
you should close it especially after a multi query (http://php.net/manual/en/mysqli.multi-query.php) because you could get memory problems. Otherwise closing is not needed.
Related
Suppose I have code like this:
mysqli_multi_query('<first query>');
include_once 'secondQuery.php';
This is an enormous simplification, and hopefully I haven't simplified the error out, but secondQuery.php relies on <first query> to be completed in order to execute properly. When I run the two manually, in the correct order, everything works perfectly. But when I run this, the error I get is consistent with them either executed in the wrong order, or simultaneously.
How would I write the middle line of:
mysqli_multi_query('<first query>');
wait for mysqli_multi_query to conclude;
include_once 'secondQuery.php';
in correct PHP syntax?
Every time you use mysqli_multi_query() you need to execute a blocking loop after it, because this function sends SQL queries to be executed by MySQL asynchronously. An example of a blocking loop which waits for MySQL to process all queries asynchronously is this:
$mysqli->multi_query(/* ... */);
do {
$result = $mysqli->use_result();
if ($result) {
// process the results here
$result->free();
}
} while ($mysqli->next_result()); // Next result will block and wait for next query to finish
$mysqli->store_result(); // Needed to fetch the error as exception
It is always a terrible idea to use mysqli_multi_query() in your PHP code. 99.99% of the time there are better ways to achieve what you want. This function has so many downsides that using it should be avoided at all cost.
What you need are database transactions. If your queries depend on each other then you need to switch off implicit commit and commit when all of them execute successfully. You can't achieve this with mysqli_multi_query().
I have to include database connection in some PHP scripts. So I require() first and then put my queries after. If viewed as a single script, it amounts to something like this:
Try {
$connect = new PDO("mysql:host={$DB_host};dbname={$DB_name}; charset=utf8mb4",$DB_user,$DB_pass);
$connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
Catch(PDOException $e) {
echo $e->getMessage();
}
// Then I put the queries here
It works, but my question is: is this safe? I've seen in most tutorials that they put all the queries within Try { } curly brackets. And what is the difference between putting the queries within Try { } and putting it after ?
If for whatever reason your query fails the program will crash at the line of code that was executing the query. There may be justification to do this if this a behavior that you desire in your code, for whatever reason.
Without the error handling your program will just break whenever an error is thrown. So unless you specifically need to have the query outside of the try catch (I couldn't guess what for), then you will just be creating trouble for yourself in the future.
If an exception occurs during your query (For instance, if it can't execute the query properly because of a missing quote), the error will not be caught and the execution of your script will halt.
Error handling is usually always preferred when possible. If there is a problem fetching data, inserting data, or simply a typo in your query, you should always have a way to notify a user that an error has occurred (And also, log it for further investigation for yourself.)
I'm trying to figure out exactly how I should work around this. When I have one MySQLi query fail, it automatically kills the rest of the script. For instance
//Pure example code
$data = $mysqli->prepare("somequery");
$data->execute(); // Execute the prepared query.
//If the query above fails, the rest of the script doesn't get executed.
Basically, I'm trying to figure out how I can stop PHP from killing the script when the query fails. Any ideas? I moved to prepared statements because of the supposed performance and security gains. It'd be a pain to rewrite everything to plan old queries.
Thanks,
You need to actually check for success, rather than blindly executing $data->execute() when data may be false, which will raise an error and abort your script.
From the docs, prepare...
returns a statement object or FALSE if an error occurred.
PHP kills scripts on fatal errors. If this line fails:
$data = $mysqli->prepare("somequery");
PHP will not kill your script but $data is set to false. The script will be killed upon the next line:
$data->execute();
With the following error:
Fatal error: Call to a member function execute() on a non-object in...
First of all, you need to enable error_reporting so that you could be able to diagnose the problem (and perhaps figure out the solution) yourself. Secondly, as #meagar mentioned, check for return values of mysqli functions:
$data = $mysqli->prepare("somequery");
if($data === false) {
echo $mysqli->error;
// dying isn't the most graceful approach by the way
die();
}
if($data->execute() === false) {
echo $mysqli->error;
die();
}
Changing from mysql_* to mysqli has nothing to do with your issue. If you were using mysql_* you still need to check the return values from functions. A generic rule: never assume that your queries will always succeed.
if($data = $mysqli->prepare("somequery")) {
// binding
$data->execute(); // Execute the prepared query.
}
From the documentation
I have a problem with reaching my connection limit too quickly... Am I right in thinking the following will help resolve this?
On older files using mysql_query
<?php
mysql_close($link);
if (isset($link2)) {
mysql_close($link2);
}
?>
On newer files using mysqli class
class DB extends MySQLi {
function __destruct() {
$this->close();
}
}
You may also be keeping connections open via persistent connections (pconnect), causing your database server to pool and stack up the connections. I've had troubles with this up until about PHP5.2?
Connection is closed automatically when script finishes it's work even if you forget to mysql_close(). Consider raising max_clients setting my.cnf
Also, if you are using only one database, you wont need, you don't need two connections - use one instead.
<?php
mysql_close($link);
if (isset($link2)) {
mysql_close($link2);
}
?>
This doesn't make any sense - if know that both variables may contain mysql connection resources then close the both!
Better yet - if your code is a mess and you can't make sense of it, then...
<?php
#mysql_close();
#mysql_close();
#mysql_close();
?>
But the only place you can sensibly put this (without analysing the code behaviour in some details - in which case you would know what resources you have open) is at the end of the script - which is where the connections get closed anyway.
Similarly, the destruct method is only called when all references to an object are deleted - this is marginally better but depending on the code structure you may get no benefit at all.
It makes far more sense to identify which URLs are taking a long time to process and trying to re-factor the code (both PHP and SQL) in these.
Do I need to explicitly kill and/or close a mysqli connection at the end of a script. At the moment, I do neither, and it works, but I don't have much load.
I've heard that there is connection pooling, and mysqli connections are re-used... do I need to close the connection then at all?
You should always close your connections at the end of the main script. If you uses some php5 and object to handle your DB just think about using __destruct() to automatically close it
http://php.net/manual/en/language.oop5.decon.php
No it is not necessary to close a mysql connection at the end of a script. PHP does it automatically.
it is not necessary but generally that's good practice. I personally, when wish to boost error-checking mechanism, you $con->close() for almost each function. e.g:
if($stmt = $db->prepare($statment))
{
if($db->bind_param($str, $param1, $param2))
{
// the rest of the code and error checking
}
else
}
$db->close();
}
}
else
{
$db->close();
}
This makes OOP necessary. Since you can simply write function doing this automatically with many other security checks added. codeIgniter as a framework has nice DB connectors whith superb security at a basic general level.