Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

simple web counter

by fred (Acolyte)
on Sep 15, 2000 at 07:33 UTC ( [id://32614]=perlquestion: print w/replies, xml ) Need Help??

fred has asked for the wisdom of the Perl Monks concerning the following question:

I'm attempting to add a very simple hit counter to my web page. The source is from the mouse book, CGI Programming with Perl by Scott Guelich, et al (O'Reilly & Associates, Inc).

It seemed like a fairly safe project. Unfortunately, the code always returns 1. I've double checked permissions, and am pretty sure they are correct. Any help on correcting this would be appreciated.

The prototype web page is simple. The CGI output is called via SSI with the statement <!--#include virtual="/cgi-bin/counter.cgi">.

The CGI code is almost straight from the book, with a correction made on the DBM file path and the USE statement listed in the errata.
#!/usr/bin/perl -wT #use strict; use Fcntl qw( :DEFAULT :flock ); use DB_File; use constant COUNT_FILE => "/home/httpd/data/count.dbm"; my %count; my $url = $ENV{DOCUMENT_URI}; local *DBM; print "Content-type: text/plain\n\n"; if (my $db = tie %count, "DB_File", COUNT_FILE, O_RDWR | O_CREAT) { my $fd = $db->fd; open DBM, "+<&=$fd" or die "Could not dup DBM for lock: $!"; flock DBM, LOCK_EX; undef $db; $count{$url} = 0 unless exists $count{$url}; my $num_hits = ++$count{$url}; untie %count; close DBM; print "$num_hits\n"; } else { print "[Error processing counter data]\n"; }

Replies are listed 'Best First'.
Re: simple web counter
by merlyn (Sage) on Sep 15, 2000 at 10:40 UTC
    That code doesn't work in real life, in spite of the fact that it was in an Animal Book. You can't flock a tied DBM, because some I/O has already happened before the flock is obtained, and not re-triggered once you have a flock.

    You need to use a sentinel file before you tie and open. Super search here for sentinel, since I've mentioned it once or twice before. {grin}

    -- Randal L. Schwartz, Perl hacker

      There is a DB_File::Lock module. Am I missing something?
Re: simple web counter
by extremely (Priest) on Sep 15, 2000 at 08:17 UTC

    I don't know why it doesn't work but I can give you a few things to test.

    Change the following line so it has a "4" where the "0" is. Does it always return 5 now? That would smell like a DB problem. Probably permissions. $count{$url} = 0 unless exists $count{$url};

    Also, are you sure that your ENVironment contains DOCUMENT_URI? Always having a "" for that could be a problem.

    Minor nit, why is "use strict;" turned off? What error made you do that? Is that or any other error in your webserver logs?

    --
    $you = new YOU;
    honk() if $you->love(perl)

      Even i tried this code from the same book . Following is my code
      #!/usr/bin/perl use strict; use Fcntl qw (LOCK_EX); use Fcntl; use DB_File; use constant COUNT_FILE => "count.dbm"; my %count; my $num_hits; my $url = $ENV{REQUEST_URI}; local *DBM; print "Content-type : text/plain\n\n"; my $db = tie %count , "DB_File" , COUNT_FILE , O_RDWR | O_CREAT; if( $db ) { my $fd = $db->fd; open DBM , "+<&=$fd" or die "Count not dump DBM for lock: $!"; flock DBM,LOCK_EX; undef $db; $count{$url} = 0 unless exists $count{$url}; $num_hits = ++$count{$url}; untie %count; close DBM; print "$num_hits\n"; }else{ print "[Error processing counter data]\n"; }
      Following are my observations

      when run the code from my terminal it updates the count and prints

      root@inll11325816l:/usr/lib/cgi-bin# perl counter.cgi Content-type : text/plain 11 root@inll11325816l:/usr/lib/cgi-bin# vi counter.cgi root@inll11325816l:/usr/lib/cgi-bin# perl counter.cgi Content-type : text/plain 12 root@inll11325816l:/usr/lib/cgi-bin# vi counter.cgi root@inll11325816l:/usr/lib/cgi-bin# perl counter.cgi Content-type : text/plain 13 root@inll11325816l:/usr/lib/cgi-bin# perl counter.cgi Content-type : text/plain 14

      When i run from the Browser it just exits from the if loop and prints the statement in the else block I have another question also here , why there is no check for the URI we are accessing here , wht if the DOCUMENT_URI or REQUEST_URI ( in my case has a different .html file that is been accessed Can anyone please help here ?

        Add absolute /path/folder/ that is writeable by the webserver. For example /tmp/

        use constant COUNT_FILE => "/tmp/count.dbm";
        poj

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://32614]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (1)
As of 2024-04-25 05:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found