PHP session for tracking unique page views

2019-01-15 21:56发布

问题:

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!

回答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.



回答2:

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

}