PHP Page View Counter for Anywhere
- PHP page view counter for website
- PHP page visit counter with sessions for website
- PHP page view counter for anywhere
This page will help you create a PHP Page View Counter for Anywhere. It uses the PHP GD Library. Find out if you have GD enabled by saving the tiny code block below as gd.php in your website public_html folder and running it: http://yoursite.com/gd.php. If there is a gd section and you see the word "enabled" everywhere, you're in business. GD stands for Graphics Draw. In truth, the library works with lots of languages, be we care only about PHP support. GD is extensively used with PHP, where a modified version supporting additional features is included by default as of PHP 4.3 and was an option before that. So get your website host to enable it if it isn't. It's free, you know!
<?php
phpinfo();
?>
To set up some web page with a counter, put this in the head section, adjusting the positioning as needed:
<style type="text/css">
.counter {position:absolute;top:1749px;left:320px;padding:3px;text-align:center;}
.z {padding:3px;text-align:center;}
</style>
And put this after the body tag, leaving in the links to our site (at least one of them, please) since no one clicks on these anyway (it's a counter, for Pete's sake!):
<div class='counter'><a HREF="http://www.css-resources.com/"><img src="http://www.yoursite.com/whatever/counter3.php?code='crabbyman3243699QED'" border='4'></a><div class='z'><small><a HREF="http://www.css-resources.com/"><font color="#999">PHP and JavaScript Expertise</font></a></small></div></div>
Why did we use the GD Library? We know of no other way to do it on someone's plain old HTML web page. We don't need the library if you want a counter on a PHP page or on an HTML page that's on a site where you've set up the htaccess file so the PHP parser runs on all HTML and HTM pages as well as PHP pages. Usually the following will suffice:
RemoveHandler .html .htm
AddType application/x-httpd-php .php .htm .html
But if neither of these are true (PHP page or HTML page that's on a site where you've made HTML and HTM parse PHP), we need to use the Library, like the code below. You can use this script from any site, regardless of PHP, as long as the server the script is on supports MySQL and PHP (the server the counter page is on does not need PHP or MySQL). It runs the PHP script on site A from an HTML or PHP or HTM page on site B. Check out the DIV, above. The weird query string in the URL is just a code that you can change to be whatever you want (letters and numbers only—up to 20 characters long). Let us call this the unique code that belongs on one particular page only. Make up a different code for each and every page you put the DIV on—it helps if you put a hint in the code about which page it's for. (E.g., 24804index143qwerty for your index/home page.) It's fine to have a different counter for each of 500 web pages. Just keep the codes unique. The only exception is if you want the counters to mean site visits, where all page visits on your site are counted. Then use the same code site-wide. Another thing about the DIV. The image source that is the counter is a PHP file, not a PNG, JPG, GIF, or BMP image. More on that craziness later!
This script uses PHP, MySQL, and the GD Library. If you don't know about MySQL, now is a good time to learn. You'll be able to go to phpAdmin in your cPanel X control panel and see the page visit totals, but will need a printout of codes plus web page names to decipher what page got what views, unless you put strong hints in the codes telling you what page the code is for. The codes take letters and numbers only, so you cannot put the path or extension.
Let's look at the script code: We start with a header that says this PHP file is really a gif because header("Content-type: image/gif") tells the PHP file to output a gif image to a browser or a file. Then, after getting ready to access the MySQL database by using the include with config.php in it, we GET the code from the URL query string and do a bit of input filtering. We use the PHP strip_tags() function. The code is supposed to be letters and numbers only—certainly there should be no tags. But we like extra security precautions. Next we use the PHP preg_replace() function and do a regular expression search and replace in which anything not a letter or a number gets the ax.
Now we create a MySQL table named counter3 if it doesn't already exist. It contains the fields id (since we need a primary field or MySQL will scream), visitors (to tally up the page views), and code. The latter can be up to 20 characters long. With this unique code, we will recognize incoming visitors data as specifically related to this code, and add to the total. Or start a new record because no such code exists. And that's our next step. We use the MySQL SELECT statement to look for the visitors tally for the code that we got above with the GET function. Then we use the mysql_num_rows() function to determine if the code was found in the counter3 table. If not, we INSERT the code in the table with a 1 for how many visitors, although technically we are talking about views. PHP page visit counter with sessions for website uses sessions to deal with visits instead of views.
But if we DO find the code, we add to its visitors tally using visitors=visitors+'1' in an UPDATE. MySQL doesn't seem to mind if we increment a field this way, without first getting the old value into a PHP variable, incrementing it, and sticking this new value back in the database table.
Note that—in this script—as long as the code is 1 or more letters or numbers, it is accepted and if its code isn't in the table, it is added. Obviously, if you want to have a bunch of users with passwords and usernames using your counter system, you will want to have a database of acceptable SITE codes and the websites that can use them and you'll want to give each of these sites a special code as a SECOND value in the URL query string, so the page code comes first and your site code comes second in these query strings. Then you accept all page codes from any counter-using website owner who has an acceptable site code as his second query string value, and you accept no codes from sites that have not signed up and received from you their special website code. This means that as codes come into your script, you have their second (site) code checked and if it exists in your site code table AND is from the correct site, you accept their data (which will either increment a page counter or start a new one at 1). If their second (site) code is checked and it is not in your site code table, you reject their data and display a message about why.
Since the PHP page thinks it is a gif creator, the message must use only PHP echo and NOT JavaScript which cannot be part of an image. One ramification of this system is that if cheaters view someone's counter code and try to use it, it won't work on their site. This code should get you where people are from so you can compare the domain with what it should be:
if(isset($_SERVER['HTTP_REFERER'])){$referer=$_SERVER['HTTP_REFERER'];}
The bad news is that people who are hackers can fake where they are from. As a matter of fact, there are no PHP codes in existence that can give you the correct URL the counter script user came from and there never will be—the best you can get is to use the referrer code above to get where they are PROBABLY from. The good news is that most won't do this, for all kinds of reasons, such as they don't know how, and why should they bother, since it's just a counter, for Pete's sake!?
More good news: if you really want to be sure all code users are legitimate, do this: Forget the iffy referrer stuff. Use three values in your URL query string. The values are: the site code, the page code, and the page's file name with any folders in its path (e.g., /myfolder/mysubfolder/mypagefile.html will be automatically URL encoded by the browser as %2Fmyfolder%2Fmysubfolder%2Fmypagefile.html in a query string since / is a reserved character). Then when this info hits your script, look up the site domain (sent as a site code in the query string) in the site code table, and use this together with the page's file name (sent as a path composed of folders with file name in the query string) in the script as the url of a page to search: "http://www.yoursite.com/myfolder/mysubfolder/mypagefile.html".
How to search? Use the PHP function file_get_contents() such as is used on the count-and-alphabetize-words-on-a-web-page.html page. You're simply trying to get the $content variable to hold the text on the page as a single string, at which point you can use stripos() to search $content for the page code, which should be found in the image source link in the div where the counter lives. Domains and paths can be determined from URLs by the parse_url() function if needed, but it shouldn't be. Your site code table (you get the site code from the URL query string) should have the needed domain and the page's file name with any folders in its path will be found in the URL query string file name value. You have only to put the 2 together (making sure there is exactly one / character in between) before searching the page using file_get_contents() and stripos(). Make sure the site code and page code values from the query string get filtered through the filters already discussed, but have the filter for the value containing the page's file name (with any folders in its path) allow . and / in addition to numbers and letters.
Back to the code: Next we read the table again, get the visitors tally using the PHP mysql_fetch_assoc() function and the use of the associative key "visitors", and find the length of this string of digits, subtracting that from 9. This is the correct number of zeros to concatenate with the number in order to always get a 9-digit number (e.g., 000001234). This makes the counter look better on the web page. So we do the concatenating, putting the word "Counter: " first (optional, but it clarifies that the number is indeed a counter. Now we close the db.
We select the GD Library's biggest font size, 5, and start using the GD functions, starting with imagefontwidth() which gets the font width, obviously, and imagefontheight() which is self-explanatory. We use these to get the size of the counter. Next, imagecreatetruecolor() is used to create a new true color image. It takes width and height parameters. Now we use the imagecolorallocate() function to return a color identifier representing the color composed of the given RGB components, red, green, blue. This function imagecolorallocate() must be called to create each color that is to be used in the image. We go on to define $gray and $blue, then fill the image with $gray using the imagefill() function. Then we define the color $black and use the imageline() function 4 times to draw lines to form a rectangle. This function draws a line of a specified color between two given points. Now the imagestring() function draws a string of characters horizontally in the counter image we're creating. Finally, we create a gif on the screen using the function imagegif(), then get it out of memory using the function imagedestroy(). The imagegif() function can be used to create an actual image you can save as a gif file, or just display the image in the browser.
The default font for GD is uncool. Feel free to use $font = 'arial.ttf';, or any other true type font you have, in the GD section below to get a decent font in the counter. Replace path by your own font path. If you want a fancy counter to draw the .ttf text on, use the info here: http://www.lateralcode.com/manipulating-images-using-the-php-gd-library/, one of the best GD sites we know of.
On to the code for the script. Name the following: counter3.php
<?php
header("Content-type: image/gif");
include_once"../config.php";
$code=strip_tags($_GET['code']);
$pattern2 = '/[^a-zA-Z0-9]/i';
$replacement = '';
$code=preg_replace($pattern2, $replacement, $code);
if(strlen($code)>0){
$sql = "CREATE TABLE IF NOT EXISTS counter3 (
id int(4) NOT NULL auto_increment,
code varchar(20) NOT NULL,
visitors int(11) NOT NULL default '1',
PRIMARY KEY (id)
) ENGINE=MyISAM AUTO_INCREMENT=1";
mysql_query($sql);
$result=mysql_query("SELECT * FROM counter3 WHERE code='$code'");
$num_rows = mysql_num_rows($result);
if ($num_rows == 0){
mysql_query("INSERT INTO counter3 (id, code, visitors)
VALUES ('','$code','1')");
}else{
mysql_query("UPDATE counter3 SET visitors=visitors+'1' WHERE code='$code'");}
$result=mysql_query("SELECT * FROM counter3 WHERE code='$code'");
$row=mysql_fetch_assoc($result);
$n=$row['visitors'];
$l=9-strlen($n);
$z=substr('000000000',0,$l);
$c="Counter: ".$z.$n;
mysql_close();
$fontsize = 5;
$wide = imagefontwidth($fontsize) * strlen($c) + 20;
$high = imagefontheight($fontsize) + 20;
$picture = imagecreatetruecolor($wide,$high);
$gray = imagecolorallocate($picture,223,223,223);
$blue = imagecolorallocate($picture,0,0,255);
imagefill($picture,0,0,$gray);
$black=imagecolorallocate($picture, 0, 0, 0);
imageline($picture, 0, 0, 0, $high, $black);
imageline($picture, 0, 0, $wide, 0, $black);
imageline($picture, $wide-1, 0, $wide-1, $high-1, $black);
imageline($picture, 0, $high-1, $wide-1, $high-1, $black);
imagestring($picture,$fontsize,10,10,$c,$blue);
imagegif($picture);
imagedestroy($picture);
}else{
echo 'Use a code in URL query string.';}
?>