1

I want to use sessions to track unique page views. Not a very robust method, I know, but sufficient for what I want to do.

On the first page load the session variable is set and a field in the database increments. On subsequent page views it does not increment, because the increment is conditional on the session variable not being set.

This is my code:

$pagenumber = 1;

//other stuff here...

session_start();

if (!isset($_SESSION[$pagenumber])) {
    $storeview = mysqli_query($dbconnect, "UPDATE tblcount SET views=views+1 WHERE id='$pagenumber'");
    $_SESSION[$pagenumber] = $pagenumber;
}
echo $_SESSION[$pagenumber];

$Recordset1 = mysqli_query($dbconnect, "SELECT views FROM tblcount WHERE id = '$pagenumber'");
$row_Recordset1 = mysqli_fetch_assoc($Recordset1);

echo "Viewed ".$row_Recordset1['views']." times";

The first echo is only there for testing. It echoes the value just fine on page refresh and the increment works the first time, but the view count continues to increment on every page refresh, which it shouldn't. I can't see why.

I found a similar question: PHP: Unique visits/hits to specific items using cookies/ip but I ran into a similar issue with the solution offered there.

Help appreciated!

Community
  • 1
  • 1
blogo
  • 319
  • 1
  • 12
  • 1
    `$pagenumber` ?? Where do you get this variable from? – RiggsFolly May 15 '17 at 19:12
  • Sorry, I should have mentioned that. $pagenumber is defined earlier. E.g. index.php has $pagenumber = 1; defined at the start. – blogo May 15 '17 at 19:16
  • 1
    So show all the code. Or show an example that actually demonstrates the real code properly – RiggsFolly May 15 '17 at 19:17
  • @RiggsFolly thanks for taking a look. I edited the post to show more of what happens around the code in question. Does that help? – blogo May 15 '17 at 19:30

2 Answers2

1

Problems:

  1. You are updating in tblCount EACH time, because your session is closed each time your script finishes. SO: Put the session_start()call as the FIRST LINE in code.
  2. It's not permitted to set an integer as $_SESSION variable. So if you set $_SESSION[$pagenumber] = 'something', then you gain the following notice:

( ! ) Notice: Unknown: Skipping numeric key 1 in Unknown on line 0

Quite... not understandable. For details see this answer.

Solution:

Add your $pagenumber as index in an array (here pagenumbers) and that array inside the $_SESSION variable. No notice anymore.

session_start();

$pagenumber = 1;

if (!isset($_SESSION['pagenumbers'])) {
    $_SESSION['pagenumbers'] = array();
}

if (!isset($_SESSION['pagenumbers'][$pagenumber])) {
    updateViews($pagenumber);
    $_SESSION['pagenumbers'][$pagenumber] = $pagenumber;
}

echo 'Page number: ' . $_SESSION['pagenumbers'][$pagenumber] . '<br/>';
$views = getViews($pagenumber);
echo '<pre>Viewed ' . print_r($views, true) . ' times</pre>';

Note: I used my functions to test. They just replace your db-processing code.

Community
  • 1
  • 1
  • Excellent. Thanks @aendeerei – blogo May 15 '17 at 22:18
  • You're welcome! Apropos: today, your little piece of code showed me to never ever (anymore) underestimate the power of displaying the notices. So we both learned something. Good luck! –  May 15 '17 at 22:34
0

Just tested. This also works.

session_start();

// Get page name
$page_url = $_SERVER['REQUEST_URI'];

// Create the session ID. Will act as visitor username
if(!isset($_SESSION['id'])){

$_SESSION['id'] = session_id();

// For the visit to the first page
$visit_id = $_SESSION['id'];

}else{

// For subsequent visits to any page
$visit_id = $_SESSION['id'];

}

/******************
Query DB. Insert only one visit per page per session. It means we need a count for each page to get its total visits. Or a count for all records to get site total visits.
************************************/
$query_visits_table = mysqli_query($db_connect, "SELECT * FROM tblcount WHERE (visit_id='$visit_id') AND (page_name='$page_url')");

if(mysqli_num_rows($query_visits_table) > 0){

// Do nothing if this page has been visited during this session

}else{

mysqli_query($db_connect, "INSERT INTO tblcount (visit_id, page_name, visit) VALUES('$visit_id', '$page_url', '1')");

}

// Get site total visits
$query_site_visits = mysqli_query($db_connect, "SELECT * FROM tblcount");

// For a specific page
$query_specific_page_visit = mysqli_query($db_connect, "SELECT * FROM tblcount WHERE page_name='$page_url'");

if(isset($query_site_visits) && isset($query_specific_page_visit)){

$site_total_visits = mysqli_num_rows($query_site_visits);
$specific_page_visit = mysqli_num_rows($query_specific_page_visit);

echo 'Site total visits is '. $site_total_visits . '<br />';

echo 'Total visits for ' . $page_url . ' is ' . $specific_page_visit;

exit();

}

hans-könig
  • 553
  • 8
  • 10
  • Thanks @Hans. I want to record one visit per page, per visitor, per session. So basically I only want to exclude page reloads. Regarding your suggestion, I'm not seeing how it is different from my code. – blogo May 15 '17 at 20:43
  • OK. I've got an idea. I just need some time, say 15 minutes to put it together. – hans-könig May 15 '17 at 21:01
  • I've came up with something different. Hope you try it. It is a bit tricky since we are dealing with a case were there is no registered username being used as filter. That's why I brought in that session-id idea and page_name. It means you have to adjust your database table to try this one. – hans-könig May 15 '17 at 22:13
  • Many thanks for the effort Hans, but I got it to work with aendeerei's suggestion. It looks like the integer as $_SESSION variable was the main problem. – blogo May 15 '17 at 22:21