Jump to content

[SOLVED] PHP MySQL Statement not being executed with no feedback


ialsoagree

Recommended Posts

I've run into a really odd problem which, for the first time in my life, I can't even figure out how to trouble shoot it anymore. I've been at it for about 4 hours and still can't find a solution (or even what is wrong).

 

I have a piece of code executed in an object method:

 

if ($remove_from_database) {
		$table = NULL;
		$where = NULL;
		$table = 's';
		$where = 'WHERE session_id = \''.$this->basic['session_id'].'\'';
		$delete = $db->do_query($db->build_delete($table, $where), __FILE__, __LINE__);
		unset($table, $where, $query);
	}

 

I've confirmed that this code does execute by adding in "echo" statements like so:

 

if ($remove_from_database) {
$table = NULL;
$where = NULL;
$table = 's';
$where = 'WHERE session_id = \''.$this->basic['session_id'].'\'';
$delete = $db->do_query($db->build_delete($table, $where), __FILE__, __LINE__);
echo $db->build_delete($table, $where);
unset($table, $where, $query);
	}

 

And get the following output:

 

DELETE FROM [actual table name] WHERE session_id = '[actual session id]' LIMIT 1

 

I then take this code into phpMyAdmin and run the statement there. It works, says 1 row affected.

 

However, when it is run in the live PHP environment it does not execute.

 

Involved in this process is the deletion of a session as thoroughly as I can manage. But if the session ID were deleted before that code could execute, why am I able to echo it? Additionally, if the delete statement wasn't executing, why does the echo statement still execute?

 

It's not an issue with the $db->do_query action either. I have literally hundreds of other statements (including 1 other delete statement) that all use it successfully. The action is set up to report (and log) SQL errors and it is not logging an error for this statement.

 

Additionally, $delete is NOT a mysql resource after executing this script (confirmed with other tests).

 

Note that during this session delete process, I DO get a new session ID and create a new session cookie, but the old session remains in the database (along with the new one).

 

I have no idea what else to do, but I will provide a good deal of the code (as much as I think is needed to trouble shoot) in case there's something going on elsewhere:

 

Defined in included files:

function delete_je_login_cookie() {
setcookie('je_login', '', time()-1);
}

public function erase_session($remove_from_database = TRUE) {
	global $db;

	if ($remove_from_database) {
		$table = NULL;
		$where = NULL;
		$table = 's';
		$where = 'WHERE session_id = \''.$this->basic['session_id'].'\'';
		$delete = $db->do_query($db->build_delete($table, $where), __FILE__, __LINE__);
		unset($table, $where, $query);
	}
	unset($this->basic);
	if (isset($_COOKIE[session_name()])) {
		setcookie(session_name(), '', time()-42000, '/');
	}

	session_unset();
	session_destroy();

	if ($remove_from_database) {
		$this->clean_sessions();
	}

	$this->session();

	return TRUE;
}

// This function below works, I've confirmed it by watching it delete old sessions in the database

private function clean_sessions() {
	global $db;
	$time_check = NULL;
	$where = NULL;
	$table = NULL;

	$time_check = time();
	$time_check -= MAX_IDLE_TIME;
	$where = 'WHERE last_active < '.$time_check;
	$table = 's';
	if (!$db->do_query($db->build_delete($table, $where), __FILE__, __LINE__, TRUE)) {
		$description = 'Could not delete old sessions. '.mysql_error();
		$db->debug_log($description, __FILE__, __LINE__, TRUE);
		return FALSE;
	}
	unset($time_check, $where, $table);
	return TRUE;
}

public function clear_get() {
	unset($_SESSION['get']);
	return TRUE;
}

 

Actual code being executed:

 

delete_je_login_cookie();
$session->erase_session();

// The below if statement evaluates to true
// Confirmed by the fact that this is the only place this response is generated
// and this is the received response after executing.

if ($_SESSION['get']['ajax'] == '1' || $_GET['ajax'] == '1' || $_SESSION['post']['ajax'] == '1' || $_POST['ajax'] == '1') {
$response = '		<form method="post" action="login.php" name="login">
	<table border="0px" cellpadding="0px" cellspacing="2px" width="210px" align="center">
		<tr>
			<td style="color:#eeeeee">Username:</td>
			<td style="text-align:right"><input type="text" name="username" length="20" maxlength="40" id="username" /></td>
		</tr>

		<tr>
			<td style="color:#eeeeee">Password:</td>
			<td style="text-align:right"><input type="password" name="password" length="20" maxlength="100" id="password" /></td>
		</tr>
		<tr>
			<td colspan="2" style="height:5px;"></td>
		</tr>
		<tr>
			<td style="color:#eeeeee"><input type="hidden" name="redirect" value="'.$redirect.'" id="redirect" /><input type="checkbox" name="save" id="save"/> Save</td>
			<td style="text-align:right;"><img src="images/login.jpg" onClick="forumSend()" style="cursor:pointer" /></td>
		</tr>
	</table>
	</form>';
echo $response;
$session->clear_get();
exit;
}

 

This code is an AJAX response and thus is not a complete HTML file.

 

I'll restate the final result of the code:

User is logged out and the proper AJAX responses are made.

User's session information and session ID are deleted.

User starts a new session with a new session ID.

The new session is stored in the database and marked as logged out.

The old session is STILL in the database and marked as logged in. (This should not happen based on the $db->do_query($db->build_delete line).

 

The only explanation that I can seem to come up with is that PHP inserts the NEW session ID into the delete statement and on subsequent AJAX requests the $session instructor simply recreates it.

 

The only problem with that analysis is that the echo statement echoes the OLD session ID (confirmed multiple times).

 

Which made me think perhaps this is a timing issue. Maybe the new session ID is created before the delete statement can execute but when I echo before hand the script can't send new headers thus defeating my attempt to trouble shoot it.

 

It's my understanding, however, that headers are typically sent out more slowly and that saving something to a variable would happen more quickly (especially considering that save is executed before headers are even told to send).

Link to comment
Share on other sites

That would imply one off two things, one of which has been ruled out:

 

1.) Mal-formed statement (Ruled out)

2.) Uncaught exception.

 

make use of mysql_error(). That's where your error is going to hide.

 

If there are no errors, go back to #1.

Link to comment
Share on other sites

That would imply one off two things, one of which has been ruled out:

 

1.) Mal-formed statement (Ruled out)

2.) Uncaught exception.

 

make use of mysql_error(). That's where your error is going to hide.

 

If there are no errors, go back to #1.

 

Thought I had figured it out but I hadn't.

 

That's quite my point, as far as I can tell it's neither.

 

As for number 1, you're right, it's been ruled out.

 

As for number 2 (perhaps I should have posted this - I've updated it how it was most recently run):

 

public function do_query($query, $page, $line, $return_on_error = FALSE) {
	global $debug_mode;
	global $webpage;
	if (!($result = mysql_query($query))) {
		if (TRUE) {
			$description = 'SQL Error occurred: '."\n".mysql_error();
			$this->debug_log($description, $page, $line);
			unset($description);
		}

		if (!$return_on_error) {
			$description = 'There was a problem with your request. If this error presists the database may be unavailable.';
			if ($debug_mode) {
				$description .= "\n".' <!-- '.mysql_error().' -->';
				$description .= "\n".' <!--'.$query.'-->';
				$description .= "\n".' <!--'.$page.' '.$line.'-->';
			}
			$webpage->report_error($description, NULL, $database_title);
		}
		else {
			return FALSE;
		}
	}
	$this->last_query = $query;
	return $result;
}

public function debug_log($description, $page, $line, $return_on_error = FALSE) {
	$tables = array();
	$tables[] = 'de';
	$data = array();
	$page = substr($page, (strrpos($page, '/') +1));
	$description = mysql_real_escape_string($description, $this->db);

	$data['user_id'] = ($session instanceof session) ? $session->basic['user_id'] : 0;
	$data['ip'] = '\''.(($session instanceof session) ? $this->basic['ip'] : $_SERVER['REMOTE_ADDR']).'\'';
	$data['rank'] = ($session instanceof session) ? $this->basic['rank'] : 0;
	$data['permission'] = ($session instanceof session) ? $this->basic['permission'] : 0;
	$data['date_created'] = time();
	$data['message'] = '\'Page: '.$page.' | Line: '.$line."\n";
	$data['message'] .= $description.'\'';

	$query = $this->build_insert($tables, $data);
	$query_result = $this->do_query($query, $page, $line, $return_on_error);

	if (!$query_result) {
		return FALSE;
	}

	return TRUE;
}

 

But no error log is made (the error logging feature is confirmed to work a number of times).

 

I updated my original post with my first thought, but not sure how it could be.

Link to comment
Share on other sites

awpti, thanks for the advice. The SQL statement wasn't throwing an error, but I went ahead and forced it to make a debug log and state it's affected rows. I was surprised to find that it stated the affected rows was 1.

 

The only possibility was that the same old session was recreated after being deleted. Then I realized that with an AJAX request (or any single request, for that matter) the http headers wouldn't be updated until a new request was made (even merely to delete a setting in the headers).

 

The fatal blow was the call to $this->session(); - even though the session had been totally deleted, the server still had access to all the old headers and recreated the session using the old ID and login information.

 

I've since changed the function so that the call can be avoided and it works like a charm.

 

I have the impending feeling it will crash and burn when it comes to non-AJAX requests, but that's a problem for another time.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.