Location: PHPKode > scripts > x64 Simple Counter > x64-simple-counter/x64_simple_counter.php
<?php

/**
 * x64 Simple Counter
 * 
 * A simple visits counter, it uses a flat
 * file as database, and it logs the IP
 * in order to know if the visitor already
 * was counted.
 * It can even be used to know if a visitor already
 * voted, or whatever you want to do.
 * 
 * @author Atomo64 - www.atomo64.tk
 * @version 0.1
 * @copyright Atomo64 2006
 * @license GNU GPL
 * @example $counter=new x64_simple_counter(); $counter->auto();
 * 
 */
class x64_simple_counter
{
	/**
	 * The name of the file used as DB
	 *
	 * @var string
	 */
	var $db;
	/**
	 * The number of seconds when the IP expires
	 *
	 * @var int
	 */
	var $expire;
	/**
	 * If the visitor already was counted(filled when calling count(), get_count() or the function of the name of the var)
	 *
	 * @var bool
	 */
	var $already_counted;
	/**
	 * This is the number of visits counted
	 * This value is used for caching pourposes, preventing from re-opening
	 * the file if we already opened it once.
	 * Only two functions sets the value of this var, count() (after counting) and get_count()
	 * It is going to be null if none of both functions were called yet
	 * 
	 * @var int,null null if count() or get_count() were not called yet
	 */
	var $count;
	/**
	 * This is the time of since when we are counting
	 * For more information about this var see $count
	 * The only exception is that the value of this var is set
	 * by these functions: count(), get_count(), install(), reset_ips() and clean_expired_ips()
	 *
	 * @var int,null null if the value has not been set yet.
	 */
	var $since_time;

	/**
	 * Class initiator
	 * Checks if the file used ad DB already exists,
	 * if not, then it creates it.
	 *
	 * @param string $file The file name of the file used as DB
	 * @param int $expire The expiration time of an IP (in seconds, default is a day)
	 * @return x64_simple_counter
	 */
	function x64_simple_counter($file='counter_data.php',$expire=86400)
	{
		$this->db=$file;
		$this->expire=$expire;
		if(!file_exists($file))
		$this->install();
	}

	/**
	 * Counts the visitor
	 *
	 * @return bool if the file could be found/open or not
	 */
	function count()
	{
		if(!file_exists($this->db))
		return false;

		$data=file($this->db);
		$ips=unserialize($data[1]);
		$count=unserialize($data[2]);
		$date=unserialize($data[3]);
		$this->since_time=$date;

		if(isset($ips[$_SERVER['REMOTE_ADDR']]))
		{
			$ips[$_SERVER['REMOTE_ADDR']]=time();
			$this->already_counted=true;
		}
		else
		{
			$count++;
			$ips[$_SERVER['REMOTE_ADDR']]=time();
			$this->already_counted=false;
		}

		$this->count=$count;

		$flat_file="<?php /* \n".serialize($ips)."\n".serialize($count)."\n".serialize($date)."\n */ ?>";

		$fp=fopen($this->db,"w");

		if(!$fp)
		return false;

		fwrite($fp,$flat_file,strlen($flat_file));
		fclose($fp);

		return true;
	}

	/**
	 * Get the number of visits
	 *
	 * @return false,int false when the file could not be found/open or an int with the visits
	 */
	function get_count()
	{
		if(!file_exists($this->db))
		return false;

		if($this->count!==null)
		return $this->count;

		$data=file($this->db);
		$ips=unserialize($data[1]);
		$count=unserialize($data[2]);
		$date=unserialize($data[3]);

		$this->already_counted=isset($ips[$_SERVER['REMOTE_ADDR']]);
		$this->count=$count;
		$this->since_time=$date;

		return $count;
	}

	/**
	 * Creates the file used as DB
	 *
	 * @return bool if the file could be found/open or not
	 */
	function install()
	{
		$time=time();
		$flat_file="<?php /* \n".serialize(array())."\n".serialize(0)."\n".serialize($time)."\n */ ?>";
		$this->since_time=$time;

		$fp=fopen($this->db,"w");

		if(!$fp)
		return false;

		fwrite($fp,$flat_file,strlen($flat_file));
		fclose($fp);

		return true;
	}

	/**
	 * Alias of install(); resets all the data
	 *
	 * @return bool if the file could be found/open or not
	 */
	function reset_all(){ return $this->install(); }

	/**
	 * This removes all the IPs from the database
	 *
	 * @return bool if the file could be found/open or not
	 */
	function reset_ips()
	{
		if(!file_exists($this->db))
		return false;

		$data=file($this->db);

		$count=unserialize($data[2]);
		$date=unserialize($data[3]);
		$this->since_time=$date;
		$flat_file="<?php /* \n".serialize(array())."\n".serialize($count)."\n".serialize($date)."\n */ ?>";

		$fp=fopen($this->db,"w");

		if(!$fp)
		return false;

		fwrite($fp,$flat_file,strlen($flat_file));
		fclose($fp);

		return true;
	}

	/**
	 * Cleans the DB from expired IPs
	 *
	 * @param bool $reduce_count if the counter should decrease for each expired IP
	 * @return bool if the file could be found/open or not
	 */
	function clean_expired_ips($reduce_count=false)
	{
		if(!file_exists($this->db))
		return false;

		if($this->expire==0)
		return true;

		$data=file($this->db);
		$ips=unserialize($data[1]);
		$count=unserialize($data[2]);
		$date=unserialize($data[2]);

		$this->since_time=$date;

		$new_array=array();
		$modified=false;

		foreach ($ips as $key=>$date)
		{
			if((time()-$date)<$this->expire)
			$new_array[$key]=$date;
			else
			{
				if($reduce_count)
				$count--;
				$modified=true;
			}
		}

		if($modified)
		{
			$flat_file="<?php /* \n".serialize($new_array)."\n".serialize($count)."\n".serialize($date)."\n */ ?>";

			$fp=fopen($this->db,"w");

			if(!$fp)
			return false;

			fwrite($fp,$flat_file,strlen($flat_file));
			fclose($fp);
		}
		return true;
	}

	/**
	 * Use this and forget about calling any other function
	 * It is necessary that you initiate a class before calling
	 *
	 * @param bool $reduce_count if the counter should decrease for each expired IP
	 * @return false,int False when DB couldn't be created/open or an int saying the number of visits on the DB.
	 */
	function auto($reduce_count=false)
	{
		if(!file_exists($this->db)&&!$this->install())
		{
			return false;
		}

		$this->clean_expired_ips($reduce_count);
		$this->count();

		return $this->get_count();
	}

	/**
	 * Returns if the visitor was already counted
	 * This function fills the value of $already_counted
	 *
	 * @return bool,null null when the DB doesn't exists
	 */
	function already_counted()
	{
		if($this->already_counted!=null)
		return $this->already_counted;

		if(!file_exists($this->db))
		return null;

		$data=file($this->db);
		$ips=unserialize($data[1]);
		$count=unserialize($data[2]);
		$date=unserialize($data[3]);

		$this->already_counted=isset($ips[$_SERVER['REMOTE_ADDR']]);
		$this->count=$count;
		$this->since_time=$date;
		
		return $this->already_counted;
	}
}
?>
Return current item: x64 Simple Counter