Include acting strange

I have a script which when loaded grabs the “MemberID” from the $_SESSION, and then uses that to run an UPDATE query which puts a timestamp in that Member’s “Last_activity” field.

This is my my non-JavaScript way of tracking a Member’s “Online Status”. :slight_smile:

This script is Included in most of my other web pages, so as a person navigates through my website, I give them credit for being active, and update their Member record.

On to my problem…

I have been dinking around with my code and Sessions this week, and have everything working, but all of a sudden noticed that when I Log Out, and then Log In again, instead of being taken to the Home Page, I get a user-defined error about “Member Status could not be updated”.

The only way this could happen - I have this traced down to a specific Error Code - is if my UPDATE query failed due to no MemberID.

Hello! I just logged in when I get this error?! :rolleyes:

And I checked my Session Cookie in MAMP, and it shows a MemberID and LoggedIn = TRUE.

It seems like my Included file is firing before my base script (e.g. “index.php”) can load the MemberID from the $_SESSION variable?!

Again, I know that I have a valid MemberID and am Logged In on my Home Page, because I can see things like “Welcome Debbie!”

If I move my Include line from the top of the script to the very last line, then the issue goes away?! (This seems to further verify this is a timing issue.)

I guess I would like to get a more scientific answer for why this started happening all of a sudden.

It seems really half-*ssed to have to put my Include at the end of my script for it to work, and I fear that maybe there is some larger issue I am not seeing.

Any idea what is going on??

Sincerely,

Debbie

If you load your script that uses the session variable before the session variable is set then you will run into this issue. Can you post some code?

Let me try and explain the sequence of events.

1.) A User logs out.

2.) A User logs in and gets redirected to the Home Page.

3.) The Home Page loads and Includes “last-activity.php” (because I want to update a Member’s record when they hop to the Home Page or any other such page).

index.php


<?php
	// Initialize Session.
	session_start();

	// Access Constants.
	require_once(whatever);

	// Connect to Database.
	require_once(whatever);

	// Update Last Activity.
	require_once('account/last-activity.php');

	// Set Redirect Path.
	$_SESSION['returnToPage'] = $_SERVER['SCRIPT_NAME'];
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

4.) last-activity.php gets Included by index.php next…

last-activity.php


<?php
	// Initialize Variables.
	$sessMemberID = (isset($_SESSION['sessMemberID']) ? $_SESSION['sessMemberID'] : '');
//echo '<p>$sessMemberID = ' . $sessMemberID . '</p>';
//When uncommented, this yields a valid MemberID...
//exit();

	// Update Last Activity.
	if ((isset($_SESSION['loggedIn'])) && ($_SESSION['loggedIn'] == TRUE)){
		// Member Logged In.

// We are getting here, so I know the MemberID above is getting logged in...

		// Build query.
		$q1 = "UPDATE member
				SET last_activity = now()
				WHERE id = ?
				LIMIT 1";

		// Prepare statement.
		$stmt1 = mysqli_prepare($dbc, $q1);

		// Bind variables to query.
		mysqli_stmt_bind_param($stmt1, 'i', $sessMemberID);

		// Execute query.
		mysqli_stmt_execute($stmt1);

		// Verify Update.
		if (mysqli_stmt_affected_rows($stmt1)==1){
			// Update Succeeded.
			// Do Nothing.

		}else{
// I am landing here, so realistically the only way my query would fail is no MemberID,
// but I just showed that I *do* have a MemberID by the time I get to my Query?!

			// Update Failed.
			$_SESSION['resultsCode'] = 'LAST_ACTIVITY_MEMBER_STATUS_NOT_UPDATED_2050';

			// Set Result Type. (New)
			$_SESSION['resultsType'] = 'error';

			// Set Source Page. (New)
			$_SESSION['sourcePage'] = $_SERVER['SCRIPT_NAME'];

			// Redirect to Display Outcome.
			header("Location: " . BASE_URL . "/account/results.php");

			// End script.
			exit();
		}

	}else{
		// Member Not Logged In.
		// Do Nothing.

	}//End of UPDATE LAST ACTIVITY

?>

5.) My “/account/results.php” fires next, because there was the following error…


LAST_ACTIVITY_MEMBER_STATUS_NOT_UPDATED_2050

So I get a corresponding Error Message, HOWEVER, in the Page Header I see “Welcome Debbie!” meaning I was successfully logged in.

And if I go to the Session-Cookie in MAMP, I see sessMemberID=19 and loggedOn=TRUE

So it is like two conflicting things are happening?! :-/


If I move my Included file to the bottom of “index.php” the problem goes away…

VERY STRANGE!!!

Sincerely,

Debbie

what file do you set the session information in? and where does that appear in conjunction to when you include your last_activity_date file?

In Step 2 (i.e. “log-in.php”) of my Original Post, I set variables after the User successfully logs in…


	// Log In Member.

	// Set Session variables.
	$_SESSION['loggedIn'] = TRUE;
	$_SESSION['sessMemberID'] = $sessMemberID;
	$_SESSION['sessFirstName'] = $sessFirstName;
	$_SESSION['sessUsername'] = $sessUsername;

So in “log-in.php” I set the $_SESSION variables to denote being logged in and the Member ID…


	// Set Session variables.
	$_SESSION['loggedIn'] = TRUE;
	$_SESSION['sessMemberID'] = $sessMemberID;

And then a few lines after that in “log-in.php”, I redirect…


	// Determine Redirect-Type after Log In.	*
	if (isset($_SESSION['returnToPage']) && ($_SESSION['returnToPage'] !== '/account/create-password.php')){
		// Return to Last Page.
		header("Location: " . BASE_URL . $_SESSION['returnToPage']);

	}else{
		// Go to Home Page.
		header("Location: " . BASE_URL . "/index.php");
	}

	// End script.
	exit();

Sincerely,

Debbie

I suggest always to put session_write_close() before any header() redirect. Try that in the spot after login before it redirects to the home page. Sounds like the redirect is too fast. :slight_smile:

That’s a good idea and be sure to verify that the processing of log-in.php doesn’t ever include “account/last-activity.php” prior to the session being set.

Good thing I didn’t embarrass myself and celebrate too soon.

I tried your advice, and the first time it seems to work, but every time thereafter I have the same issue… :headbang:

Here is where I am pretty sure the issue is happening…

All is well until I am redirected to “index.php”

Here is the code in that file again…


<?php
	// Initialize Session.
	session_start();

	// Access Constants.
	require_once('../outside_root/config.php');   

	// Connect to Database.
	require_once(DB_SETTINGS_PATH);   //<==== MAYBE THIS GUY IS TOO POKEY????

	// Update Last Activity.
	require_once('account/last-activity.php');  //<======= IS THIS FIRING BEFORE I HAVE AN INCLUDED DB CONNECTION?????

	// Set Redirect Path.
	$_SESSION['returnToPage'] = $_SERVER['SCRIPT_NAME'];
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

And immediately after landing on “index.php” I am re-rerouted to “outcome.php” because my UPDATE query which was Included in “index.php” fails.

Here is the suspect code in “last-activity.php” which is the Included script…


<?php
	// Initialize Variables.
	$sessMemberID = (isset($_SESSION['sessMemberID']) ? $_SESSION['sessMemberID'] : '');

//echo '<p>$sessMemberID = ' . $sessMemberID . '</p>';
// This echo shows a value of '57' when uncommented.
//exit();

	// ************************
	// Update Last Activity.	*
	// ************************
	if ((isset($_SESSION['loggedIn'])) && ($_SESSION['loggedIn'] == TRUE)){
		// Member Logged In.

		// Build query.
		$q1 = "UPDATE member
						SET last_activity = now()
						WHERE id = ?
						LIMIT 1";

		// Prepare statement.
		$stmt1 = mysqli_prepare($dbc, $q1);

		// Bind variables to query.
		mysqli_stmt_bind_param($stmt1, 'i', $sessMemberID);

		// Execute query.
		mysqli_stmt_execute($stmt1);

		// Verify Update.
		if (mysqli_stmt_affected_rows($stmt1)==1){
			// Update Succeeded.
			// Do Nothing.

		}else{
			// Update Failed.
			$_SESSION['resultsCode'] = 'LAST_ACTIVITY_MEMBER_STATUS_NOT_UPDATED_2050';

			// Set Result Type. (New)
			$_SESSION['resultsType'] = 'error';

			// Set Source Page. (New)
			$_SESSION['sourcePage'] = $_SERVER['SCRIPT_NAME'];

			// Redirect to Display Outcome.
			header("Location: " . BASE_URL . "/account/results.php");

			// End script.
			exit();
		}

As far as I can see, there are only two reasons the UPDATE query above would fail…

a.) No $sessMemberID (which I seem to prove is there)

b.) The database connection isn’t ready or is down

If you go back to “index.php” above…

Is it possible that “last-activity.php” is too quick and that my Database Connection is not up yet? (See comments above)

Sincerely,

Debbie

What does throwing it in a try/catch block produce?

try {
        // Member Logged In. 

        // Build query. 
        $q1 = "UPDATE member 
                        SET last_activity = now() 
                        WHERE id = ? 
                        LIMIT 1"; 

        // Prepare statement. 
        $stmt1 = mysqli_prepare($dbc, $q1); 

        // Bind variables to query. 
        mysqli_stmt_bind_param($stmt1, 'i', $sessMemberID); 

        // Execute query. 
        mysqli_stmt_execute($stmt1); 

        // Verify Update. 
        if (mysqli_stmt_affected_rows($stmt1)==1){ 
            // Update Succeeded. 
            // Do Nothing. 

        }else{ 
            // Update Failed. 
            $_SESSION['resultsCode'] = 'LAST_ACTIVITY_MEMBER_STATUS_NOT_UPDATED_2050'; 

            // Set Result Type. (New) 
            $_SESSION['resultsType'] = 'error'; 

            // Set Source Page. (New) 
            $_SESSION['sourcePage'] = $_SERVER['SCRIPT_NAME']; 

            // Redirect to Display Outcome. 
            header("Location: " . BASE_URL . "/account/results.php"); 

            // End script. 
            exit(); 
        }
} catch (Exception $e) {
  var_dump($e);
  exit();
}

why don’t you echo out $stmt1->error - might be mysqli_stmt_error($stmt1)?

I tried adding those lines of code and am getting syntax errors in NetBeans.

Sure that is the right format, and what is $e ???

Debbie

Try using } catch (Exception $e) {

I did try adding this code…


	if ((isset($_SESSION['loggedIn'])) && ($_SESSION['loggedIn'] == TRUE)){
		// Member Logged In.

		// Build query.
		$q1 = "UPDATE member
				SET last_activity = now()
				WHERE id = ?
				LIMIT 1";

		// Prepare statement.
		$stmt1 = mysqli_prepare($dbc, $q1);

		// Bind variables to query.
		mysqli_stmt_bind_param($stmt1, 'i', $sessMemberID);

		// Execute query.
		mysqli_stmt_execute($stmt1);

echo '<p>mysqli_stmt_affected_rows($stmt1) = ' . mysqli_stmt_affected_rows($stmt1) . '</p>';
exit();

		// Verify Update.
		if (mysqli_stmt_affected_rows($stmt1)==1){
			// Update Succeeded.
			// Do Nothing.

		}else{
			// Update Failed.
			$_SESSION['resultsCode'] = 'LAST_ACTIVITY_MEMBER_STATUS_NOT_UPDATED_2050';

When I re-ran my code I got this…

mysqli_stmt_affected_rows($stmt1) = 0

Again, if I have this code at the top of “last-activity.php”…


<?php
	// Initialize Variables.
	$sessMemberID = (isset($_SESSION['sessMemberID']) ? $_SESSION['sessMemberID'] : '');
echo '<p>$sessMemberID = ' . $sessMemberID . '</p>';
exit();

Then I get…

$sessMemberID = 57

So to me that is strongly pointing towards there being an issue with my Database Connection…

What about this…

In “index.php”, I have this…


<?php
	// Initialize Session.
	session_start();

	// Access Constants.
	require_once('../outside_root/config.php');

	// Connect to Database.
	require_once(DB_SETTINGS_PATH);

	// Update Last Activity.
	require_once('account/last-activity.php');

Now, “last-activity.php” needs a $_SESSION to run, and it needs a Database Connection to run.

I stripped out the following code from “last-activity.php” because I felt it was redundant…

last-activity.php (former)


<?php
	// Initialize Session.
	session_start();

	// Access Constants.
	require_once('../outside_root/config.php');

	// Connect to Database.
	require_once(DB_SETTINGS_PATH);

[b]I guess I just assumed that since “index.php”…

  • Starts the Session
  • Includes the Constants
  • Connects to the Database

…that when it INCLUDES “last-activity.php”, that “last-activity.php” would inherit all of that stuff, right???[/b] :-/

Sincerely,

Debbie

Yeah, that isn’t a good thing to do. Chances are that is part (if not all of your problem). You really should continue the path of catching the exception or echoing the result of mysqli_stmt_error too

The syntax worked this time, but when I ran things, I just got my same User-Defined Error…

System Error

A Fatal Error has occurred. Please contact the System Administrator. (2050)

Your code didn’t spit out any output like I would have expected?!

Debbie

That just means it isn’t throwing an exception and you may get a better idea using mysqli_stmt_error. So I’d try that next.

Okay, so I added that code to mine, below…


	// Update Last Activity.
	if ((isset($_SESSION['loggedIn'])) && ($_SESSION['loggedIn'] == TRUE)){
		// Member Logged In.

		// Build query.
		$q1 = "UPDATE member
				SET last_activity = now()
				WHERE id = ?
				LIMIT 1";

		// Prepare statement.
		$stmt1 = mysqli_prepare($dbc, $q1);

		// Bind variables to query.
		mysqli_stmt_bind_param($stmt1, 'i', $sessMemberID);

		// Execute query.
		mysqli_stmt_execute($stmt1);

echo '<p>mysqli_stmt_error($stmt1) = ' . mysqli_stmt_error($stmt1) . '</p>';
//echo '<p>mysqli_stmt_affected_rows($stmt1) = ' . mysqli_stmt_affected_rows($stmt1) . '</p>';
exit();

Here is what I got…

mysqli_stmt_error($stmt1) =

Not much help… :frowning:

Debbie

OK, maybe a stupid question, but do you actually have id of 57 on the member table?

Sure do! :slight_smile:

Debbie

Here is what I have been able to figure out today…

It appears my code is throwing my user-defined error when I try and update “last_activity” too quickly and it hasn’t changed.

Not sure why this suddenly started after working for a year, but apparently the time from “log-in.php” to “index.php” to including “last-activity.php” happens under 1 second, and so this statement is not true…


		// Verify Update.
		if (mysqli_stmt_affected_rows($stmt1)==1){

As a workaround, I wrote a new SELECT query to check if there is a difference between “last_activity” and now(), and if there is, THEN I run the UPDATE query, otherwise I just pass…

But it seems like there must be a better way. (I mean who wants to bog down their server with TWO queries just to update the “last_activity” field in a Member’s record?!) :rolleyes:

Any suggestions?

Sincerely,

Debbie