Why does mysqli::multi_query stop after a certain amount of rows? - php

I'm attempting to run a fairly large amount of updates/inserts on a table using multi_query. There are ~14,000 queries total, but the function only executes ~480, then it stops without errors and PHP continues the script beyond the snip below:
if($this->db->conn_id->multi_query($sql)){
do{
// echo $line.' '.mysqli_sqlstate($this->db->conn_id).'<br>';
}while($this->db->conn_id->more_results() && $this->db->conn_id->next_result());
$this->message->set('Import complete.','success',TRUE);
}else{
$this->message->set('Import could not be completed. '.mysqli_error($this->db->conn_id),'error',TRUE);
}

mysqli::multi_query only returns false if the first statement fails. To get the errors from the other queries in your set, you need to call mysqli::next_result() first, which is what your do while() is doing.
However, since mysqli::next_result() returns false on failure, it will cause the loop to end and the 'Import complete' message to be displayed. You probably need to check for an error before setting the success message, and only if the error is blank, return success.
The following should at least show you the error if there was one later in the statement.
if($this->db->conn_id->multi_query($sql)){
do{
// echo $line.' '.mysqli_sqlstate($this->db->conn_id).'<br>';
} while($this->db->conn_id->more_results() && $this->db->conn_id->next_result());
if ($error = mysqli_error($this->db->conn_id)) {
$this->message->set('Import could not be completed. ' . $error,'error',TRUE);
} else $this->message->set('Import complete.','success',TRUE);
} else {
$this->message->set('Import could not be completed. '.mysqli_error($this->db->conn_id),'error',TRUE);
}

Related

My ELSE condition refuses to run in IF/ELSE Laravel

I have a basic if/else statement is Laravel.
$model = MyModel::where('row', 'abc123')->first();
// Returns 3 statuses - connected, inactive, disconnected
$status = getStatus();
if ($status === 'connected') {
if (!$model->is_active) {
$model->timed_at = now();
}
$model->is_active = true;
}
else {
if ($model->is_active) {
$model->last_timed_at = $model->updated_at;
}
$model->is_active = false;
}
$model->save();
NOTE: This function is called repeatedly at an interval of 10 seconds.
The ELSE functionality works flawlessly outside the ELSE statement.
But the moment it's in the ELSE, it doesn't run at all.
I have proven that it does reach the ELSE by adding an echo which works fine.
Another odd thing, when I place the ELSE in the IF side, it works perfectly fine.
Thanks everyone for the input.
Turns out the data I was tweaking during my testing gave me unexpected (they were actually expected) results.
Not sure how to fully close a question, but leaving this here to say it was a non-issue.

PHP: mysqli clearing stored results

I was using this function to clear stored results after calling a procedure etc.
function clearStoredResults($mysqli_link){
#------------------------------------------
while($mysqli_link->next_result()){
if($l_result = $mysqli_link->store_result()){
$l_result->free();
}
}
}
But I keep getting the following message/error
mysqli::next_result(): There is no next result set. Please, call
mysqli_more_results()/mysqli::more_results() to check whether to call
this function/method in
If I change next_result() to more_results() the page keeps loading for a while and I get a time out error:
Maximum execution time of 30 seconds exceeded
any ideas on how to fix this?
You need to use both methods:
function clearStoredResults($mysqli_link) {
#------------------------------------------
while($mysqli_link->more_results()) {
$mysqli_link->next_result();
if($l_result = $mysqli_link->store_result()) {
$l_result->free();
}
}
}
Use more_results to control the loop, and next_result to actually move the cursor.

Doctrine2 insert fails silently, only on certain records

I have the following code which results sometimes in a silent failure:
public function updateCoreGameTableIfNecessary($coreEm)
{
$game = $this->getCoreGameRecord($coreEm);
if (!$game) {
$game = new Game();
$game->setHomeSchool($this->getHomeSchool()->getCoreSchool($coreEm));
$game->setDatetime($this->getDatetime()->format('Y-m-d H:i:s'));
$game->setDate($this->getDatetime()->getTimestamp());
$game->setTime($this->getDatetime()->format('H:i:s'));
$game->setSport($coreEm->getRepository('VNNCoreBundle:Sport')->findOneByName($this->getSport()->getName()));
$game->setSeason($coreEm->getRepository('VNNCoreBundle:Season')->findCurrent());
$game->setEventType(strtolower($this->getEventType()->getName()));
$game->setMeetName($this->getMeetName());
$game->setRemoteUnique(md5(rand(0, 100000)));
$game->setNotes($this->getRecap());
$game->setHomeConfId(0); // This field is no longer used, so value doesn't matter.
$game->setAwayConfId(0); // This field is no longer used, so value doesn't matter.
$game->setConfStatus(''); // This field is going away as well.
}
if ($this->getEventType()->getName() == 'Game') {
$game->setHomeScore($this->getHomeScore());
$game->setAwayScore($this->getAwayScore());
$game->setAwaySchool($this->getAwaySchool()->getCoreSchool($coreEm));
} else {
$game->setPlace($this->getPlace());
$game->setPoints($this->getHomeScore());
}
$game->setOwnerId($this->getUser()->getSchool()->getCoreSchool($coreEm)->getId());
$coreEm->persist($game);
$coreEm->flush();
return $game->getId();
}
It always starts with a $this that's already saved. For certain instances of $this (i.e. certain records in the database), $game won't get saved. I won't get an error or anything like that. It will just fail silently.
Any suggestions for debugging? I guess I'll try to figure out what's different about those certain records, but it seems like an insert should never silently fail, for any reason.

PHP long poll fails

I have this loop to long poll:
$time = time(); //send a blank response after 15sec
while((time() - $time) < 15) {
$last_modif = filemtime("./logs.txt");
if($_SESSION['lasttime'] != $last_modif) {
$_SESSION['lasttime'] = $last_modif;
$logs = file_get_contents("./logs.txt");
print nl2br($logs);
ob_flush();
flush();
die();
}
usleep(10000);
}
problem is: the "if" condition is never entered in the middle of the while loop, even if logs.txt is modified. I have to wait 15sec till the next call to this file to obtain the updated content (so it becomes a regular, "setTimeout style" AJAX polling, not a long-poll). Any idea why ?
This is because of the filemtime() function : its results are cached. Thus each time your loop is executed the timestamp's the same for 15 seconds.
I have not tried it myself, but according to w3cschools :
The result of this function are cached. Use clearstatcache() to clear the cache.
Hope that helps !

in php i need one line if condition for time compare

i have to value
$mo=strtotime($input_array['MondayOpen']);
$mc=strtotime($input_array['MondayClose']);
now i need a if condition to display an error on below conditions
if one of them($mo or $mc) are empty, null or blank.
if close time($mc) is less than open time($mo)
means if both are empty(null) or $mc>$mo then go further
please suggest optimized one line if condition for this
i know it seems very basic question, but i m facing problem when both are null
either i was using simple
if(($mo==NULL && $mc!=NULL) || ( $mo>=$mc && ($mo!=NULL && $mc!=NULL)) )
Keep in mind that 0, null, and blank all mean completely different things here. As indicated previously, strtotime will never return NULL. However, 0 is a valid unix timestamp, whereas false means that the strtotime function was unable to process the value provided.
Also, you've requested that a single-line solution; however, in my opinion, it is much better in this case to write out each condition and display a different error message for each condition. That way, the user knows what actually went wrong. Perhaps this is a better way:
// Only check for errors if we have at least one value set
if (!empty($input['MondayOpen']) || !empty($input['MondayClosed']) {
$mo = strtotime($input['MondayOpen']);
$mc = strtotime($input['MondayClosed']);
$invalid = false;
if (false === $mo) {
echo "Invalid Opening Time\n";
$invalid = true;
}
if (false === $mc) {
echo "Invalid Closing Time\n";
$invalid = true;
}
if (!$invalid && $mc <= $mo) {
echo "Closing time must be After Opening Time\n";
$invalid = true;
}
if ($invalid) {
exit(); // Or handle errors more gracefully
}
}
// Do something useful
All right. How about this.
It checks whether $mo and $mc are valid dates using is_numeric. Any NULL or false values will be caught by that.
I haven't tested it but it should work.
I spread it into a huge block of code. In the beginning, when learning the language, this is the best way to make sense out of the code. It is not the most elegant, nor by far the shortest solution. Later, you can shorten it by removing whitespace, or by introducing or and stuff.
I'm not 100% sure about the number comparison part, and I don't have the time to check it right now. You'll have to try out whether it works.
You need to decide how you want to handle errors and insert the code to where my comments are. A simple echo might already do.
// If $mo or $mc are false, show error.
// Else, proceed to checking whether $mo is larger
// than $mc.
if ((!is_numeric($mo)) and (is_numeric($mc)))
{
// Error: $mo is either NULL, or false, or something else, but not a number.
// While $mc IS a number.
}
elseif ((!is_numeric($mc)) and (is_numeric($mo)))
{
// Error: $mc is either NULL, or false, or something else, but not a number.
// While $mo IS a number.
}
else
{
if (($mc <= $mo) and ((is_numeric($mc) or (is_numeric($mo)))))
{
// Error: closing time is before opening time.
}
else
{
// Success!!
}
}
in php, strotime will return a integer or false. Checking for null in this case will never bear fruit, but otherwise...
if((!$mo xor !$mc) || ($mc && $mc<=$mo)){
print('error');
}else{
print('no_error');
}
oops, edited for correctness. I transposed $mc and $mo. XOR should be correct though.
You can try:
print ((empty($mo) && empty($mc)) || ($mc > $mo)) ? 'case_true_message' : 'case_false_message';
But you should also check the manual :) - for basic control structures

Categories