I've placed a hit counter on my page. It reads a text file, increments the number in the file, and later in the page, I output the incremented value.
$hitsFile = "hits/exps/stats.txt";
$hits = file($hitsFile);
$hits[0]++;
$fp = fopen($hitsFile , "w");
flock($fh, LOCK_EX);
fwrite($fp , $hits[0]);
fclose($fp);
My problem is that if I reload the page, the code will increment the hits. I don't want that. I thought of using session to fix that, but with session, in order the increment the hits again, I need to exit the site and visit again. I don't want that either.
I want it to increment not when I reload the page but when I revisit the page.
For example, let's say I have two-page website, Home and Contact, and on contact page I have a hit counter. I don't want the hit counter to increment if I reload(refresh) the contact page, but if I leave the contact page and visit homepage, and later revisit the contact page, I want it to increment.
In short, I don't want it to increment on page reload. Is there a way to do that?
In each of your pages, you need to write the page name in the session.
Do something like this:
$_SESSION['page'] = 'contact';
On the pages where you need to count hits, you need to check this session key.
For example, if you were on page 'contact', then $_SESSION['page'] == 'contact'.
Now when you go to visit the 'homepage':
$page = $_SESSION['page'];
if($page != 'homepage')
{
//increment your hits counter
$_SESSION['page'] = 'homepage';
}
I suggest this method, is my preferred, create in root these folders: cnt and log... then put inside cnt folder the following files cnt.php and showcnt.php...
cnt.php
<?php
##############################################################################
# Php Counter With Advanced Technology For The Prevention Of Reloading Pages #
# Version: 1.4 - Date: 13.11.2014 - Created By Alessandro Marinuzzi [Alecos] #
##############################################################################
function cnt($file) {
session_start();
global $pagecnt;
$reloaded = isset($_SERVER['HTTP_CACHE_CONTROL']) && $_SERVER['HTTP_CACHE_CONTROL'] === 'max-age=0';
$thispage = basename($_SERVER['SCRIPT_FILENAME']);
if (!isset($_SESSION['first_go'])) {
$_SESSION['first_go'] = 1;
$first_go = TRUE;
} else {
$first_go = FALSE;
}
if (!isset($_SESSION['thispage'])) {
$_SESSION['thispage'] = $thispage;
}
if ($_SESSION['thispage'] != $thispage) {
$_SESSION['thispage'] = $thispage;
$new_page = TRUE;
} else {
$new_page = FALSE;
}
$pagecnt = rtrim(file_get_contents($file));
if ((!$reloaded) && ($new_page == TRUE) || ($first_go == TRUE)) {
$fd = fopen($file, 'w+');
flock($fd, LOCK_EX);
fwrite($fd, ++$pagecnt);
flock($fd, LOCK_UN);
fclose($fd);
}
}
?>
showcnt.php
<?php
##############################################################################
# Show Counter Results - v.1.4 - 13.11.2014 By Alessandro Marinuzzi [Alecos] #
##############################################################################
function gfxcnt($file) {
global $number;
$number = rtrim(file_get_contents($file));
$lenght = strlen($number);
$gfxcnt = "";
for ($i = 0; $i < $lenght; $i++) {
$gfxcnt .= $number[$i];
}
$gfxind = "<span class=\"counter\"><span class=\"number\">$gfxcnt</span></span>";
echo $gfxind;
}
?>
Well, then edit your index.php or other php page... and put at the beginning this piece of code:
<?php session_start(); include("cnt/cnt.php"); cnt("log/index.txt"); include("cnt/showcnt.php"); ?>
Well, then edit index.php or other php page... and use this piece of code for reading counter file:
<?php gfxcnt("log/index.txt"); ?>
It's all, I hope you'll find my answer useful :) My counter can write/read multiple php pages...
Source: my blog (https://www.alecos.it/new/101/101.php)
Add session_start(); to the top.
Now change your if to this:
if (!isset($_SESSION['lastpage']) || $_SESSION['lastpage'] != $_SERVER['QUERY_STRING') {
$hits[0]++;
}
$_SESSION['lastpage'] = $_SERVER['QUERY_STRING'];
This will basically force someone to move to another page if they want to increment the counter.
Update the hit count only if the current URL is not stored in $_SESSION['url'].
After updating the hit count, store the current URL in $_SESSION['url'].
Related
What I want to do is to have a variable that increments by 1 after every reload. Now, I can't do cookies because I want it to increment globally, and I've tried sessions but I had no luck with them. If anyone could help me out I'd really appreciate it. I actually can't give any code samples because my tries have turned out very messy.
If you want a variable for each user, then I would definitely go with sessions :
<?php
session_start();
if (!isset($_SESSION['counter'])) {
$_SESSION['counter'] = 0;
} else {
$_SESSION['counter']++;
}
However if you want a unique variable that increases at each load (i.e the same for all users), then you could use a file to store the number of views :
<?php
if(file_exists('counter.txt'))
{
$counter_f = fopen('counter.txt', 'r+');
$count = fgets($counter_f);
}
else
{
$counter_f = fopen('counter.txt', 'a+');
$count = 0;
}
$count++;
fseek($counter_f, 0);
fputs($counter_f, $count);
fclose($counter_f);
?>
I have two landing pages (homepage1 and homepage2). If I land on homepage1, the logo link needs to change to homepage1 and keep it as I go to other pages. The same goes when I land on homepage2. I tried -
if (strstr($_SERVER['HTTP_REFERER'], 'homepage1.php') !== false) {
<a href='homepage1.php'><img src='logo.jpg'></a>
}
elseif (strstr($_SERVER['HTTP_REFERER'], 'homepage2.php') !== false ) {
<a href='homepage2.php'><img src='logo.jpg'></a>
}
It works when I go to one page but anymore than one the url and logo are gone. In other words, it doesn't hold on to the url.
I need it to hold on to the url based on what landing page I land on. And it needs to hold on to the url, no matter how many pages I go to.
Is this possible?
As #DragonYen pointed out , you need to use session variable as it can be used to persist state information between page requests.
session_start();
$ref = $_SERVER['HTTP_REFERER'];
$page = explode("/", $ref);
if($page[3] == "homepage1.php") {
$_SESSION['home'] = 1;
}
else if($page[3] == "homepage2.php") {
$_SESSION['home'] = 2;
}
Now you can check for session variable home
if ($_SESSION['home'] == 1) {
<a href='homepage1.php'><img src='logo.jpg'></a>
}
elseif ($_SESSION['home'] == 2) {
<a href='homepage2.php'><img src='logo.jpg'></a>
}
put this when you no longer need the session
unset($_SESSION['home'];
session_destroy();
I have 3 (.php) files/pages for a website (in a folder), I have Previous/Next Links displayed on the bottom of each. What php code on the previous/next link, would help me navigate to the next page.
For Example:
Lets say the pages are Page1.php, Page2.php, Page3.php, and I am currently on Page2.php.
If I want to click on the 'Previous' Link, I want Page1.php to be displayed.
If I click on 'Next' then I want Page3.php to be displayed.
I believe this is called 'pagination'?
Previous
Next
I dont know if this is possible. And I hope I have been clear with describing the problem.
Thanks,
babsdoc
Here is the original code #Fred
$images = "jars/"; # Location of small versions
$big = "samp2/"; # Location of big versions (assumed to be a subdir of above)
$cols = 2; # Number of columns to display
if ($handle = opendir($images)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && $file != "samp2" && $file != "Thumbs.db") {
$files[] = $file;
}
}
closedir($handle);
}
foreach($files as $file)
{
$pc="Product Code:".substr($file,0,-4);
<a href=\"$images$big$file\" class=\"swap\"><img src=$images$file title=\"title\"
width=\"100\" height=\"100\">
$pc</a></li>";
}
Providing you're going to keep a sane naming convention throughout (ie pageX.php), then the following should suffice.
(might not be the ideal solution for you but gives you an idea. Can be put in a function/changes made, etc)
$strCurrentPage = basename($_SERVER['REQUEST_URI']);
$strPattern = '/\d+/';
preg_match($strPattern, $strCurrentPage, $strGetPageNumber); // extract numerical value
//set two new vars to same as page number, increment one and subtract one
$strNextPageNum = $strGetPageNumber[0];
$strPreviousPageNum = $strGetPageNumber[0];
$strNextPageNum++;
$strPreviousPageNum--;
//set full filename with new numbers
$strNextPage = 'page'.$strNextPageNum.'.php';
$strPreviousPage = 'page'.$strPreviousPageNum.'.php';
//if file is found then show link
//next page
if (file_exists($strNextPage))
{
echo 'Next Page';
}
else
{
echo "No more pages";
}
//previous page
if (file_exists($strPreviousPage))
{
echo 'Previous Page';
}
else
{
echo "No previous pages";
}
i am working on a project which one of our web application would be somehow JavaScript code to gather statistical information about visitors but as far as i know on server side PHP application i should somehow handle the code in a way that multi refresh doesn't count and counting on IP based is not a good idea since many users may have the same IP , cookie or session are also vulnerable to this issue because cookie manager can just wipe out all the cookie related to the site so PHP won't recognize the user and count it new,timeframe jobs and all other way to get-around of this issue are also as far as i know based on cookie or session or ip or a mixture of ip/referrer and all other available data from header, how can i handle it and get more reliable data from users and don't permit them to create fake stats. as i believe there must be a way (i hope so)...!?
I think cookies would be ideal for this kind of problem, but if you do not want to use that then you've got yourself a tough cookie. Unfortunately you don't have many other options since HTTP is stateless.
I would use session vars in this case since the user cannot meddle with the data saved there. There is however the risk of session hijacking, but if your site is open to that vulnerability you need to look at securing the site on a more global level that just the hit counter. The session variable is bound to your site since the data in it is saved on the server rather than in the users browser. And is bound to your user since it saves a cookie with a key in the users browser to request the data from the server.
Here is an example on how you can implement this and not worry about deleting other sessions on the site.
<?php
function hit_counter() {
if(isset($_SESSION['hit_counter'])) { // Check if the user has the hit_counter session
if(isset($_SESSION['hit_counter']['time']) && isset($_SESSION['hit_counter']['page'])) { // Check if the user has the time and the page set from the last visit
$last_time = $_SESSION['hit_counter']['time'];
$last_page = $_SESSION['hit_counter']['page'];
$now = time(); // The current UNIX time stamp in seconds
$current_page = $_SERVER['REQUEST_URI']; // The page name
/*
If the users hasn't requested this page
in the last 10 seconds or if the user
comes from another page increment the
hit counter
*/
if(($now - $last_time) > 10 || $last_page != $current_page) {
/* INCREMENT YOUR HIT COUNTER HERE */
}
}
unset($_SESSION['hit_counter']); // Delete this hit counter session
}
// And create a new hit counter session
$_SESSION['hit_counter'] = array();
$_SESSION['hit_counter']['time'] = time();
$_SESSION['hit_counter']['page'] = $_SERVER['REQUEST_URI'];
}
?>
You will never touch any of the other session variables since you're only unset()ing the hit counter variable. There is no need for you to handle session_destroy(), but you need to make sure that there is a session_start() in the beginning of every page you would like to use function in.
You could edit the script to not factor in time if you'd only want to count hits if the user comes from another page on your site.
This is as far as I can see, a hit counter with a sensible level of security for most sites. Or at the very least a good start.
Some more information about PHP sessions.
I created this
<?php
namespace Codelaby\EventDateGenerator;
class CounterVisitors
{
private $filename = "counter.txt";
private $sessionId;
private $sessionStart;
public function __construct()
{
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
if (!isset($_SESSION['sessionId'])) {
$this->sessionId = md5(uniqid(rand(), true));
$_SESSION['sessionId'] = $this->sessionId;
$this->sessionStart = time();
$this->hitCounter();
} else {
$this->sessionId = $_SESSION['sessionId'];
if (!isset($_SESSION['sessionStart'])) {
$this->sessionStart = time();
} else {
$this->sessionStart = $_SESSION['sessionStart'];
}
if (time() - $this->sessionStart > 60) {
$this->sessionStart = time();
$this->hitCounter();
}
}
$_SESSION['sessionStart'] = $this->sessionStart;
}
private function saveCounter($counter = 0)
{
if (!file_exists($this->filename)) {
touch($this->filename);
}
$fp = fopen($this->filename, "w");
if (!flock($fp, LOCK_EX)) {
return;
}
fwrite($fp, $counter);
flock($fp, LOCK_UN);
fclose($fp);
}
public function readCounter()
{
if (!file_exists($this->filename)) {
touch($this->filename);
}
$fp = fopen($this->filename, "r");
if (!flock($fp, LOCK_EX)) {
return;
}
$file_size = filesize($this->filename);
if ($file_size <= 0) {
$counter = 0;
} else {
$counter = intval(fread($fp, $file_size));
}
flock($fp, LOCK_UN);
fclose($fp);
return $counter;
}
public function hitCounter()
{
$counter = $this->readCounter();
$counter++;
$this->saveCounter($counter);
return $counter;
}
public function resetCounter($counter = 0)
{
$this->saveCounter(0);
}
}
How to use
session_start() //before send headers
$counterVisitors = new CounterVisitors();
$visitors = $counterVisitors->readCounter();
echo 'visitors: ' . $visitors;
The script generate counter.txt if not exist, only increment visit if user start new session or wait 60 seconds for refresh
Among the following include methods which is the best to practice and why?
$page = $_GET['page'];
Method 1
$pages = array('home', 'blog', 'about');
if( in_array($page, $pages) )
{
include($page.'.php');
{
else
{
die('Nice Try.');
}
Method 2
if($page = 'home'){
include('home.php');
}else if($page = 'blog'){
include('blog.php');
}else if($page = 'about'){
include('about.php');
}
Method 3
if(str_replace("http://", "gth://", $page) == $page){
include_once $page;
}else{
die('Nice Try.');
}
or any other solutions? I dont prefer method 1 and 2 as it always needs to be updated everytime i add a new page.
extending/maintaining the first way is easiest, second way is worse. third way is no way to go, as it relies on user input to require pages... it is going to be a security hole
I believe that the first one is the best of the lot. You can try the second one, but it's for the freshers. And the third one is a BIG NO, because any fresher hacker could hack your "if" condition, & more loopholes will start creeping in.
As for your problem, on adding a new page to the array, every time a new page is created, for the first method, I have one solution:-
Let's say you're putting all the new pages in one folder "abc". Now just write one file code as the following, to read all the files / pages existing in that folder:-
<?php
$page = $_GET['page'];
$pages = array();
/**
* If you are using all the pages existing in the current folder you are in,
* then use the below variable as:-
* $path = ".";
*/
$path = 'abc/'; // Change the Path here, related to this Folder name
$handle = opendir($path);
while (($file = readdir($handle)) !== false) {
$pages[] = $file;
}
closedir($handle);
if( in_array($page, $pages) ) {
include($page.'.php');
}
else {
die('Nice Try.');
}
?>
So you see that the array is getting filled up dynamically, without the need to mention all the pages you create every time. And you are using the first method only. And keep the including pages in one separate folder, which you will need to include every time, in other main pages.
Hope it helps.