Newbie: Simple Counter

Tutorials on PHP, databases and other aspects of web development. Before posting a question, check in here to see whether there's a tutorial that covers your problem.

Moderator: General Moderators

User avatar
nigma
DevNet Resident
Posts: 1094
Joined: Sat Jan 25, 2003 1:49 am

Post by nigma »

yay! the last new guy who came 'round here we scared off ;)
d3ad1ysp0rk
Forum Donator
Posts: 1661
Joined: Mon Oct 20, 2003 8:31 pm
Location: Maine, USA

Post by d3ad1ysp0rk »

nigma wrote:Yea, you don't need to add anything. But, say somehow this counter.txt file has the string "blah" in it and not a number, then you increment "blah" and get "blai" and then you output that to the screen saying that is how many hits your site has. Now chances are that this might not ever happen, but still, some people may want to consider adding some ways to check for such an abnormality.
If the text file has "blah" as it's contents, I don't think thats gonna make much of a difference (ie. Our site has blah hits since march 20th, 2004, OR Our site has blai hits since march 20th, 2004).

Point is, if the file has content that shouldnt be there, then you have to change it either way (whether it increments or not), so why add extra code?
User avatar
nigma
DevNet Resident
Posts: 1094
Joined: Sat Jan 25, 2003 1:49 am

Post by nigma »

so things correct themselves.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

LiLpunkSkateR wrote:
Sami wrote:I'd much rather prefer they learned it the best way first, instead of learning an inferior way first and then realizing there is a better method weeks/months later. ;)
For a simple counter, this ISNT the inferior way. mysql would be a bad decision. Creating the db, creating the table/vars, connecting to the db, selecting the table, creating the query, getting the values, updating the value(s), saving the data, disconnecting from the db.. OR.. open file, read file, update data, write to file, close file.
Once you get started on more than one thing (ips, refferer, etc.) dbs become a good idea. tracking JUST hits, files seem better IMHO..
Actually, a file is really inferior. Think about concurrent visitors.
You would need to have file locking, as opposed to mysql where you can simply update foo set count=count+1;
d3ad1ysp0rk
Forum Donator
Posts: 1661
Joined: Mon Oct 20, 2003 8:31 pm
Location: Maine, USA

Post by d3ad1ysp0rk »

Find a site that gets THAT many hits to require file locking AND doesnt already have a database/config table already set up, and I'll change my opinion.

But like I said, for a simple counter (ie. for a small site), files are the best way to go, until you start getting more advanced.
User avatar
nigma
DevNet Resident
Posts: 1094
Joined: Sat Jan 25, 2003 1:49 am

Post by nigma »

Even if the site gets two hits a month, all that has to happen is for those two hits to happen at the same time.
d3ad1ysp0rk
Forum Donator
Posts: 1661
Joined: Mon Oct 20, 2003 8:31 pm
Location: Maine, USA

Post by d3ad1ysp0rk »

and the likelyhood of that happening vs the annoyance of setting up a db/user/table/vars vs just adding a new file is?
anyways, not everyone has mysql.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

LiLpunkSkateR wrote:and the likelyhood of that happening vs the annoyance of setting up a db/user/table/vars vs just adding a new file is?
anyways, not everyone has mysql.
If it can happen, it will happen. And even a newbie wants bugfree software. Even if this means, he'll have to do some "annoying" setup of a database.

Not everybody has access to the filesystem either. I've seen more hosts with safe_mode enabledb than without access to a database.
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Post by phice »

Here you go, both tutorials written by me.


Creating a File-based Counter
Step One - In the same directory as you plan on putting the PHP file for this counter, create a file 'counter.txt' and CHMOD it to 0777.
Step Two - Create a file called 'counter.php' and place the following PHP code into it.

Code: Select all

<?php
	// Change this if you rename your counter.txt file
	$counter_file = "counter.txt";
	
	// Get the contents of the current counter file
	if($f = @fopen($counter_file, "r"))
	{
		@$contents = fread($f, @filesize($counter_file));

		@fclose($f);
	}
	
	
	
	// File is empty
	if($contents == "")
	{
		$contents = 0;
	}
	
	// File contents is not a number
	if(!is_numeric($contents))
	{
		print "Counter contents is not a number.";
		define('ERROR', 1);
	}
	
	
	
	// Bump the count
	if(ERROR <> 1)
	{
		$contents++;
		
		// Add contents back to file
		if($f = @fopen($counter_file, "w"))
		{
			@fwrite($f, $contents);
			@fclose($f);
		}
	
		// Print the contents
		print $contents;
	}

?>
Step Three - Upload PHP file into your server
Step Four - Place the following code (setting the same url as if you were to go to it in the browser) where you want to place your counter. You call the file from the http:// location so it processes, and then you get the contents of the file without worrying about file location or any of that.

Code: Select all

<?php include("http://location.to.your/new/counter.php"); ?>



Creating a MySQL-based Counter
NOTE - This is for the more advanced user. If you don't have phpMyAdmin installed, you can download it at http://www.phpmyadmin.net/.
Step One - Make sure you have MySQL installed on your server and you have the right server address, username, password and database. (If you dont have MySQL installed or dont have these settings, please contact your server administrator/host (I cant help you get these settings myself).
Step Two - Browse to your phpMyAdmin and run this query in your selected database.
CREATE TABLE `counter` (`key` VARCHAR(255) NOT NULL, `value` INT(12) NOT NULL);
INSERT INTO `counter` (`key`, `value`) VALUES ('counter', '0');
Step Three - Create a file called 'counter.php' and place the following PHP code into it.

Code: Select all

<?php	
	// Change these settings to match yours
	define('SERVER', 'localhost');
	define('DATABASE', '');
	define('USER', '');
	define('PASS', '');
	define('TABLE', 'counter');
	
	
	
	// Connect to MySQL
	@mysql_connect(SERVER, USER, PASS)
		or print(mysql_error());
	$db = @mysql_select_db(DATABASE)
			or print(mysql_error() . "<br />\n");
	
	// Update the field
	$result = @mysql_query("UPDATE `" . TABLE . "` SET value = value + 1 WHERE `key` = 'counter'")
			or print(mysql_error() . "<br />\n");
	@mysql_free_result($result);
	
	// Get the value
	$result = @mysql_query("SELECT `value` FROM `" . TABLE . "` WHERE `key` = 'counter'")
			or print(mysql_error() . "<br />\n");
	$row = @mysql_fetch_object($result);
	
	$counter = $row->value;
	
	@mysql_free_result($result);
	
	print $counter;
?>
Step Three - Upload PHP file into your server
Step Four - Place the following code (setting the same url as if you were to go to it in the browser) where you want to place your counter. You call the file from the http:// location so it processes, and then you get the contents of the file without worrying about file location or any of that.

Code: Select all

<?php include("http://location.to.your/new/counter.php"); ?>

If you have any problems, please let me know.
Image Image
User avatar
nigma
DevNet Resident
Posts: 1094
Joined: Sat Jan 25, 2003 1:49 am

Post by nigma »

define() kicks ass
ldomingues
Forum Commoner
Posts: 41
Joined: Fri Aug 06, 2004 1:15 pm
Location: Portugal

Post by ldomingues »

Nice code!

I'd change the order of the sql operations, so that the visitor doesn't have to wait for the update to complete.

Also adding flush() is a good ideia for servers that cache output.

Code: Select all

// Change these settings to match yours 
   define('SERVER', 'localhost'); 
   define('DATABASE', ''); 
   define('USER', ''); 
   define('PASS', ''); 
   define('TABLE', 'counter'); 
    
    
    
   // Connect to MySQL 
   @mysql_connect(SERVER, USER, PASS) 
      or print(mysql_error()); 
   $db = @mysql_select_db(DATABASE) 
         or print(mysql_error() . "<br />\n"); 
    
   // Get the value 
   $result = @mysql_query("SELECT `value` FROM `" . TABLE . "` WHERE `key` = 'counter'") 
         or print(mysql_error() . "<br />\n"); 
   $row = @mysql_fetch_object($result); 
    
   $counter = $row->value; 

   @mysql_free_result($result); 
    
    // add one before showing the counter
   print $counter+1; 

    // added flush to output data before updating counter
   flush();

   // Update the field 
   $result = @mysql_query("UPDATE `" . TABLE . "` SET value = value + 1 WHERE `key` = 'counter'") 
         or print(mysql_error() . "<br />\n"); 
   @mysql_free_result($result); 
    
?>
User avatar
phice
Moderator
Posts: 1416
Joined: Sat Apr 20, 2002 3:14 pm
Location: Dallas, TX
Contact:

Post by phice »

I wouldn't use that code because there could be many people online at the same time and would falsify the output of the counter.

It's best to update the database then selected the updated counter then print out the counter and have a problem updating the number.
Image Image
User avatar
tim
DevNet Resident
Posts: 1165
Joined: Thu Feb 12, 2004 7:19 pm
Location: ohio

Post by tim »

phice wrote:It's best to update the database then selected the updated counter then print out the counter and have a problem updating the number.
best said
User avatar
nigma
DevNet Resident
Posts: 1094
Joined: Sat Jan 25, 2003 1:49 am

Post by nigma »

heh, agreed

I think it's time I moved on though -> tells phpbb not to notify me of new replies to this topic

This could go on indefinitely.

Edit: But there is a plus! We get to show off how many posts we have :)
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

until a mod comes in and cleans the thread of useless junk.
Post Reply