Page 1 of 1

Click counting?

Posted: Tue Apr 15, 2008 3:57 am
by Strawbee
Sorry if this has been asked before. This is really basic and I'm pretty much a PHP newbie. I would like to know how to count the number of times a link has been accessed or clicked and display that count on my web page.

For example, if someone goes to mydomain.com/link.php?id=1 I would like to add 1 to the count. How would I do this and display it on a web page?

I searched for this on Google but it keeps giving me click tracking programs to download. Isn't there a way I can do this with simply code? I don't want an admin control panel or anything.

Re: Click counting?

Posted: Tue Apr 15, 2008 4:09 am
by s.dot
This would involve storing, retrieving, and incrementing the number of times accessed. Which means you will need a permanent medium of storage (flat file or database).

In MySQL it would look like:

Code: Select all

$id = !empty($_GET['id']) ? mysql_real_escape_string((int) $_GET['id']) : false;
if ($id)
{
    //update
    mysql_query("UPDATE `table` SET `counting_field`=`counting_field`+1 WHERE `id` = '$id' LIMIT 1") or die(mysql_error());
 
    //retrieve
    $count = mysql_query("SELECT `counting_field` FROM `table` WHERE `id` = '$id' LIMIT 1") or die(mysql_error());
 
    //display
    echo mysql_result($count, 0);
}

Re: Click counting?

Posted: Tue Apr 15, 2008 4:15 am
by Chris Corbyn
You probably want a database, but a text-file will do just as well. Effectively you want to look at the value of $_SERVER['REQUEST_URI'] and grab the last count for that specific URI from either a DB or a text file, then increment it and save it again.

Here's a text-file example; actually I'm just going to write PHP code to the file here cos it's quicker to demonstrate.

We're aiming to store the data in an array in a PHP file looking something like this:

Code: Select all

<?php
 
$records = array(
  '?foo=bar' => 23,
  '/foo/bar/test.php' => 19,
  '?x=y&a=b' => 1
);
 

Code: Select all

function recordPageHit($recordFile) {
 
  //Define $records, or load an existing copy
  if (!file_exists($recordFile)) {
    $records = array();
  } else {
    include $recordFile; //This would put $records in the local scope of the function
  }
  
  //Get the current Page URI
  $currentURI = $_SERVER['REQUEST_URI'];
  
  //Check if a count exists for this URI and create a zero one if not
  if (!array_key_exists($currentURI, $records)) {
    $records[$currentURI] = 0;
  }
  
  //Increment the count
  $records[$currentURI]++;
  
  //Create a PHP code string we can write back to a file
  $code = "<?php" . PHP_EOL .
    '$records = array(' . PHP_EOL;
  //Loop over all the records and put the values in our code
  foreach ($records as $uri => $n) {
    $code .= '  "' . $uri . '" => ' . $n . ',' . PHP_EOL;
  }
  $code .= ');' . PHP_EOL;
  
  //Open the file for writing
  $fp = fopen($recordFile, 'w');
  //Gain exclusive access to it (in case 2 page requests happen at the same time
  flock($fp, LOCK_EX);
  //Write the code to it
  fwrite($fp, $code);
  //Close it (releasing the lock)
  fclose($fp);
  
}
 
function getPageHitCount($recordFile) {
  //Define $records, or load an existing copy
  if (!file_exists($recordFile)) {
    $records = array();
  } else {
    include $recordFile; //This would put $records in the local scope of the function
  }
  
  //Get the current Page URI
  $currentURI = $_SERVER['REQUEST_URI'];
  
  //Check if a count exists for this URI and create a zero one if not
  if (!array_key_exists($currentURI, $records)) {
    $records[$currentURI] = 0;
  }
  
  //Return the count
  return $records[$currentURI];
}
 
So you'd use that something like:

Code: Select all

<?php
 
recordPageHit('hits.php');
 
echo getPageHitCount('hits.php');
 
hits.php would need to be a writable file on the server, or the directory it's in would need to be writable.

There are loads of ways to do this, and most of them are better than what I posted. I just figured my code was clear(ish) doe a newcomer :) Using a database is probably most preferable.

EDIT | What was I thinking??! There are so many potential exploits in my code, don't use it!