Category: CGI
Author/Contact Info /msg sulfericacid
Description: I finished a banner rotating script a few days ago with VERY little help from PM (which is a good thing.. it means I'm either learning to figure things out on my own or learning not to bug anyone :) ). That script gave me the idea to track link counts as well.

I think this is the most useful script I've written so far, all you do is redirect the links on your site to something that looks like <a href="linktracker.pl?url=http://www.yoursite.com/yourfile.html"> and it'll count how many times it was clicked then redirect to the file. It's kind of nice knowing which sections of your pages are getting the most clicks.

Things I've learned:

  • $var++ is postincrement
  • ++$var is pre-increment

    Other:
  • this will accept any domain that's passed through url_params, I set it up this way so you don't need an admin panel to setup which links/ids you want to link to
  • This is a very basic program with little features or error checking, if any of you have reasons to throw some other things in I'd be glad to listen. Only thing I'm aware that should be fixed is somehow have the script realize www.yoursite.com/yourpage.html is the same as a link <a href="linktracker.pl?url=yourpage.html"></a>
  • --------------------------------------------
    linktracker.pl (file you redirect to)
    
    
    #!/usr/bin/perl
    
    #
    # link tracker
    #
    
    use warnings;
    use strict;
    use CGI::Carp qw(fatalsToBrowser);
    use CGI qw/:standard/;
    
    use POSIX;
    
    use DB_File;
    
    my %db;
    my $db = "linktracker.db";
    
    
    tie %db, "DB_File", "$db", O_CREAT | O_RDWR, 0644, $DB_BTREE
      or die "Cannot open file 'db': $!\n";
    
    my $url = url_param('url');
    
    if (exists $db{$url}) {
    my $value = $db{$url};
    
    $value++;
    $db{$url} = $value;
    
    print "Location: $url\n\n";
    }
    else {
    $db{$url} = 1;
    print "Location: $url\n\n";
    }
    
    -------------------------------------------
    linkcount.pl    (stats page)
    
    #!/usr/bin/perl
    
    #
    # link counter
    #
    
    use warnings;
    use strict;
    use CGI::Carp qw(fatalsToBrowser);
    use CGI qw/:standard/;
    
    use POSIX;
    
    use DB_File;
    
    my %db;
    my $db = "linktracker.db";
    
    
    tie %db, "DB_File", "$db", O_CREAT | O_RDWR, 0644, $DB_BTREE
      or die "Cannot open file 'db': $!\n";
    
    print header, start_html;
    print "<center>";
    print "<table><tr>";
    print qq(<td bgcolor="000080"><b><font color=white>URL</font></b></td>
    +);
    print qq(<td bgcolor="000080"><b><font color=white>Click Count</font><
    +/b></td></tr>);
    
    foreach (keys %db) {
    print "<td>$_ </td> <td><center>$db{$_}</center></td></tr>\n";
    }
    
    
    print "</table>";
    print "</center>";
    
    Replies are listed 'Best First'.
    Re: Link Tracker
    by Anonymous Monk on Sep 13, 2003 at 17:00 UTC
      if (exists $db{$url}) { my $value = $db{$url}; $value++; $db{$url} = $value; print "Location: $url\n\n"; } else { $db{$url} = 1; print "Location: $url\n\n"; }
      Should be replaced by:
      $db{ $url } ++; print "Location: $url\n\n";
      in order to improve readability. The $hash{ 'key' } ++; idiom is quite common for incrementing the value of a hash key.

      -- am
    Re: Link Tracker
    by jeffa (Bishop) on Sep 13, 2003 at 18:03 UTC

      Yes. You are improving. Now if we could just convince you to indent your code! ;) As for this item:

      $db{$url} = $value++; # post increment!
      This indeed does increment $value, but after it's original value has been fetched and stored into $db{$url}. You could have used this instead:
      $db{$url} = ++$value; # pre increment!
      But Anonymous Monk's suggestion is much better.

      Also, consider switching to HTML::Template (although i will commend you for at least using qq). It's really not that hard, and with the help of my tutorial you should be able to pick it up fairly quickly. (If you can work with DB files, you can handle HTML::Template! ;))

      jeffa

      L-LL-L--L-LL-L--L-LL-L--
      -R--R-RR-R--R-RR-R--R-RR
      B--B--B--B--B--B--B--B--
      H---H---H---H---H---H---
      (the triplet paradiddle with high-hat)
      
        I really appreciate everyone's comments on this and really really happy that I'm finally getting to the point where I can do a lot of things on my own.

        The ++$var will come in handy real quick, I ran into the same "not incrementing" problem with my banner rotator. Thanks for that bit of info..

        As for $db{ $var } ++; that's amazing. They sure did make it easier for the lazy people to do pretty mcuh everything :) I wish Anonymous Monk signed in so I could ++ him/her, that's a really quick and short way of incrementing a hash key. I didn't test this out but I was wondering if you could increment both the key and value at the same time? $db{$var1}++ = ++$value;

        Sorry about the indenting Jeffa, I do intent now! It's just my computer isn't working so I'm on a system without ActivePerl (without perltidy). I will read/print/read/read/read your tutorial Jeffa :) If this helps with creating forms and tables I'll rake your leaves and shovel your snow all winter!! :)

        Thanks again for all your comments/suggestions everyone, it really helps knowing other people can tell the difference in your codes.

        "Age is nothing more than an inaccurate number bestowed upon us at birth as just another means for others to judge and classify us"

        sulfericacid

          I didn't test this out but I was wondering if you could increment both the key and value at the same time? $db{$var1}++ = ++$value;

          (1) If you are using incremental values as hash keys, then you should probably be using a plain array instead.

          (2) Yes, you can increment the array index (or key) and the value in one statement. The correct way would be: $db[$index++] = ++$value (or similarly with a hash key, if you insist), whereas your initial guess (with "++" outside the brackets) is not allowed; it generates a compile-time error.

          Go ahead, try it yourself and see. Your guess is "logically" equivalent to:  $j++ = ++$i (I'm glad perl treats this as an uncompilable coding error).

    Re: Link Tracker
    by Limbic~Region (Chancellor) on Sep 13, 2003 at 15:54 UTC
      sulfericacid,
      I do not know anything about WWW programming, so I did not review this. I can tell you it looks much cleaner than your older code. I am not sure why you are using CGI if you are constructing most of the HTML yourself though?

      This is in reference to the statement concerning not being able to use $variable = $value++; You should always consult perldoc - it is your friend.

      From perldoc perlop

      ``++'' and ``--'' work as in C. That is, if placed before a variable, they increment or decrement the variable before returning the value, and if placed after, increment or decrement the variable after returning the value.

      Cheers - L~R