How do I wait for mysqli_multi_query to resolve? - php

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().

Related

MySQL query won't execute - Class->Function->Form

I have built a query ($query_q = "SELECT * FROM `table`;") and am trying to execute it within a function.
public function read_from_table() {
$query_q = "SELECT * FROM `table`";
$query_a = mysql_query($query_q);
while (mysql_fetch_array($query_a)) {
echo "Did it!";
//OR AS TRIED ANOTHER WAY
return "Did it!";
}
}
And called as such:
echo $classInstance->read_from_table();
//OR AS TRIED ANOTHER WAY
$classInstance->read_from_table();
Both the ways that the function and the class have been made have been tried in every conceivable way, and yet I still get no result.
I was getting the error that says the xecution time has exceeded the limit of 30 seconds, so I added the ini_set('max_execution_time', 0); (knowing this removes time limit altogether) to see if the query would execute at all, it has been running now for 30 minutes without a sign of life. Why is the query not executing?
Additional comments:
I am aware that I am using the depreciated mysql_* functions, this is at client request and will be updated after the site has been made live and is complete to a point where I am ready to change it all to mysqli->* functions.
The table that I am calling (it's name has been stripped and replaced with `table`) has only 9 rows in it, so this should not affect the execution time greatly (or will it?).
I have had to strip all sensitive information from the function to satisfy the client and my employer. Please keep in mind that I cannot disclose and information that the client and my employer do not wish to disclose.
The issue was that the internet and server had gone down.
This has since been sorted and is operational.
Thank you for help and support in this.
DigitalMediaMan
try
error_reporting(E_ALL);
if all ok, try run this query from console, look, how many times query will be performed
before this, kill old process in database(show processlist and kill pid)

How to backtrace a mysql query?

I have a large and complicated system consisting of php and javascript code, which make many mysql queries. Is there a way to 'backtrace' each mysql query to the exact line of code, which makes the query?
In mysql it is possible to trace all queries (adding a log statement to the mysql config), but it does not show which php or javascript code/module/line did the query. Is it possible to find the offending lines for each mysql query?
No, there is no way of MySQL knowing what line of code, class, function or file you're making a call from. It just receives a socket connection from the application running the code, and accepts input, processes it and returns a result.
All it knows about is the data it receives, and who is sending it.
You can view active connections and a brief description of what they're doing using
SHOW PROCESSLIST;
You'll get output similar to this:
Id User Host db Command Time State Info
48 test 10.0.2.2:65109 test Sleep 4621
51 test 10.0.2.2:49717 test Sleep 5
52 test 10.0.2.2:49718 test Query 0 SHOW PROCESSLIST
Generally when people want to log queries it happens somewhat similar to this
Before the query is run, log the query and any parameters
Run the query
Log the success/failure of the query, and any errors
To execute this process for systems with hundreds or thousands of queries, you'll generally find a wrapper function/class is created which accepts the appropriate parameters, processes the query as listed above, and returns the result. You could pass your wrapper method the PHP Constants __FILE__ and __LINE__ when you call it, to then log where the database call is being initiated from.
pseudo code only
// Wrapper method
function query_wrapper($stm, $file, $line)
{
log_prequery($stm, $file, $line); // Log the query, file and line
$result = $stm->execute(); // Execute the query
log_postquery($result); // Log the result (and any errors)
return $result; // Return the result
}
// In your code where you're making a database query
$db = new Database();
$stm = $db->prepare("SELECT foo FROM bar");
query_wrapper($stm, __FILE__, __LINE__);

Inconsistent behavior in a php code

I coded a function to help me handle transaction with files in CodeIgniter.
today I was trying this code:
function($db_trans_func, $context){
if(is_callable($db_trans_func)){
$context = $db_trans_func($context);
FirePHP_::info_(time(), "After Db trans");
}
}
that is just a snippet from my helper. But the problem is, when this code runs and in the case where the execution of the function $db_trans_func takes place it takes more time to run, php passes to next code FirePHP_::info_($context, "From db transaction"); before the ending of the line before.
That is abnormal for me. because in the normal case the lines should run one after the other.
Can anyone help me solve this problem ? How can I tell php to not run
FirePHP_::info_(time(), "After Db trans");
after that:
$context = $db_trans_func($context);
finishes its execution?
I'm not entirely clear, but my assumption is:
db_trans_func is running some function against the DB (such as setting a transaction begin)
you are comparing the php function FirePHP_::info_(time(), "After Db trans"); against the time recorded in the db, or similar
In other words, you have a function that DOES fire first in php, then a second one. They ARE running consecutively; BUT, the DB result takes longer, of course, and so the db effect is seen afterwards. In other words, these are different threads running asynchronously
Does that make sense to you, and is it possible?

PHP connection_aborted() and/or register_shutdown_function work intermittently

I've a PHP script that outputs a file to the user (as a download) which is also used to record what the user is downloading.
Basic structure is this:
set_time_limit(0);
ignore_user_abort(true);
register_shutdown_function('shutdown_fn'); //as a fail safe (i think)
//some other code here
//do some mysql queries
while(!feof($fh) && !connection_aborted()) {
echo fread(....);
ob_flush;
ob_end_flush;
sleep(1);
}
fclose($fh);
//do some more mysql queries here and set a boolean to track if it was done successfully
function shutdown_fn () {
//check boolean to see if queries failed, if so, do them here
}
The above code seems to work 99% of the time just fine. However, there are some instances when the second set of queries don't execute at all (the other 1%). I have no idea why. The files being sent to the user range from very small to very large (and in both cases they work just fine so i cant see how a large file (or small file) would be breaking the code).
Any thoughts? I hope i have explained myself well enough
I need to see some more code like the opening/reading of the file to further help you, but if you really want to be sure and not depend on the one shutdown_fn() function then why not call it yourself as well on the end of the script? Reset the boolean in the shutdown_fn() so whenever the actual shutdown is triggered than your sql queries are not ran twice.

When to call mysqli::close

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.

Categories