⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perl 语言-perl 中文教程(第三章计数器的编写方法).htm

📁 perl的中文教程
💻 HTM
📖 第 1 页 / 共 2 页
字号:
            name=Image21></A></TD></TR></TBODY></TABLE></TD>
    <TD class=myFont vAlign=top width=30><IMG height=1 
      src="Perl 语言-Perl 中文教程(第三章计数器的编写方法).files/x.gif" width=10> </TD>
    <TD class=myFont vAlign=top>
      <DIV align=center><IMG height=30 
      src="Perl 语言-Perl 中文教程(第三章计数器的编写方法).files/top.gif" width=180><BR><SPAN 
      class=myFont><SPAN class=myFont><FONT face=宋体>翻译:</FONT></SPAN></SPAN> 
      <SPAN class=myFont><SPAN class=myFont>flamephoenix</SPAN></SPAN> <BR>
      <HR width="100%" SIZE=1>

      <DIV align=left>
      <P align=center>第三章 计数器的编写方法(未定稿)</P>
      <P align=center><A href="http://flamephoenix.126.com/" target=_blank>by 
      flamephoenix</A></P>
      <P><A 
      href="http://www.sun126.com/perl5/perl5-17.htm#1">一、记录(log)文件</A><BR>&nbsp; 
      <A 
      href="http://www.sun126.com/perl5/perl5-17.htm#1.1">1、grep</A><BR>&nbsp; 
      <A 
      href="http://www.sun126.com/perl5/perl5-17.htm#1.2">2、page-stats</A><BR>&nbsp; 
      <A href="http://www.sun126.com/perl5/perl5-17.htm#1.3">3、wusage</A><BR><A 
      href="http://www.sun126.com/perl5/perl5-17.htm#2">二、创建自己的计数器</A><BR>&nbsp; 
      <A 
      href="http://www.sun126.com/perl5/perl5-17.htm#2.1">1、使用DBM文件</A><BR>&nbsp; 
      <A 
      href="http://www.sun126.com/perl5/perl5-17.htm#2.2">2、文本文件</A><BR>&nbsp; 
      <A 
      href="http://www.sun126.com/perl5/perl5-17.htm#2.3">3、文件锁定</A><BR>&nbsp; 
      <A 
      href="http://www.sun126.com/perl5/perl5-17.htm#2.4">4、输出计数结果</A><BR>&nbsp; 
      <A href="http://www.sun126.com/perl5/perl5-17.htm#2.5">5、www Homepage 
      Access Counter</A><BR>&nbsp; <A 
      href="http://www.sun126.com/perl5/perl5-17.htm#2.6">6、使用GD图形库</A><BR><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;计数器(Access 
      Counter)可以记录网页被访问的次数,在万维网上的使用十分普遍,其编写方法很多,从简单的SSI命令到用CGI程序生成内嵌图像等。计数器除了记录点击次数外,还可以记录访问者的IP、OS、浏览器类型等内容,使你对自己网站的访问情况有个全面的了解,本章主要介绍点击次数的统计和显示方法。<BR><BR><A 
      name=1>一、记录(log)文件<BR></A><A 
      name=1.1>1、grep</A><BR>&nbsp;&nbsp;&nbsp;&nbsp;对于Web服务器而言,都有记录文件记录着详细的访问信息,其名称通常为access_log,下面是一个例子:<BR></P>
      <BLOCKQUOTE>
        <P>01: dialup-9.austin.io.com - - [02/Oct/1995:20:18:05 -0500] "GET 
        /phoenix/ HTTP/1.0" 200 2330<BR>02: crossnet.org - - 
        [08/Oct/1995:19:56:45 -0500] "HEAD / HTTP/1.0" 200 0<BR>03: 
        dialup-2.austin.io.com - - [09/Oct/1995:07:54:56 -0500] "GET 
        /leading-rein/orders HTTP/1.0" 401 -<BR>04: onramp1-9.onr.com - - 
        [10/Oct/1995:11:11:40 -0500] "GET / HTTP/1.0" 200 1529<BR>05: 
        onramp1-9.onr.com - - [10/Oct/1995:11:11:43 -0500] "GET /accn.jpg 
        HTTP/1.0" 200 20342<BR>06: onramp1-9.onr.com - - [10/Oct/1995:11:11:46 
        -0500] "GET /home.gif HTTP/1.0" 200 1331<BR>07: dialup-3.austin.io.com - 
        - [12/Oct/1995:08:04:27 -0500] "GET /cgi-bin/env.cgi?<BR>08: 
        SavedName=+&amp;First+Name=Eric&amp;Last+Name=Herrmann&amp;Street=&amp;City=&amp;State=&amp;<BR>09: 
        zip=&amp;Phone+Number=%28999%29+999-9999+&amp;Email+Address=&amp;<BR>10: 
        simple=+Submit+Registration+ HTTP/1.0" 200 1261<BR>11: 
        dialup-20.austin.io.com - - [14/Oct/1995:16:40:04 -0500] "GET 
        /leading-rein/index.cgi?unique_id=9658-199.170.89.58-813706781 HTTP/1.0" 
        200 1109 </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;注;当主页在srm.conf中被命名为welcome.html、index.cgi、index.shtml等时,对其的访问记录,可能只含有目录名而不包含该文件名。<BR>&nbsp;&nbsp;&nbsp;&nbsp;我们可以用UNIX命令grep来统计主页被访问的次数,grep命令通常输出每一行匹配结果,但可以加上参数-c以输出匹配行的数目,grep详见UNIX帮助。下面是一个简单的例子grep.cgi:<BR></P>
      <BLOCKQUOTE>
        <P>1: #!/usr/local/bin/perl<BR>2: print "content-type: 
        text/html\n\n";<BR>3: $num = `grep -c 'GET / HTTP' 
        /your-server-root/logs/access_log` ;<BR>4: $num += `grep -c 'GET 
        /index.shtml' /your-server-root/logs/access_log` ;<BR>5: $num += `grep 
        -c 'GET /index.html' /your-server-root /logs/access_log` ;<BR>6: print 
        "$num\n"; </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;现在就可以在主页中加上SSI指令来显示计数了,例如:<BR></P>
      <BLOCKQUOTE>
        <P>01: &lt;html&gt;<BR>02: &lt;head&gt;&lt;title&gt;grep 
        test&lt;/title&gt;<BR>03: &lt;body&gt;<BR>04: &lt;hr noshade&gt;<BR>05: 
        This page has been accessed<BR>06: &lt;!--#exec cgi="grep1.cgi" --&gt; 
        times.<BR>07: &lt;hr noshade&gt;<BR>08: &lt;/body&gt;<BR>09: 
        &lt;/html&gt; </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;别忘了把此文件扩展名改为.shtml。在grep.cgi中,grep命令中包围模式的单引号告诉UNIX 
      shell不改变该串的内容以精确匹配。<BR>&nbsp;&nbsp;&nbsp;&nbsp;这种方法有许多缺陷,首先是效率低,用grep来匹配花时间较长,可能要几秒钟的时间,这对一个简单的文本计数器而言太长了。其次,对每一个需要计数器的页面CGI文件均不相同。最后一个对某些人来说不算是个问题,就是要把Web服务器设置成允许SSI执行,即将其目录映射略加修改。<BR><A 
      name=1.2>2、page-stats</A><BR>&nbsp;&nbsp;&nbsp;&nbsp;有一个叫page-stats的程序较好地解决了grep的问题。它查看HTTP 
      daemon的access_log并寻找在标识文件中指定网页的访问,然后计算其数目并生成一个HTML形式的统计页面。这样,你既得到了页面的详细统计信息,同时又得到了可显示的结果页面,这样的例子可在<A 
      href="http://www.sci.kun.nl/thalia/page-stats/page-stats_sci.html" 
      target=_blank>http://www.sci.kun.nl/thalia/page-stats/page-stats_sci.html</A>找到。还可以用grep命令在统计页面中查找所需信息并生成自己的显示形式,这样速度就快多了。<BR>&nbsp;&nbsp;&nbsp;&nbsp;注意不应在建立自己的统计时运行该程序,否则会导致冲突。应该把它放到任务列表中用UNIX命令cron定时执行,每天、每小时甚至每几分钟运行一次。cron详见UNIX帮助。<BR><A 
      name=1.3>3、wusage</A><BR>&nbsp;&nbsp;&nbsp;&nbsp;另外一个广为应用的服务器统计程序是由Thomas 
      Boutell(<A 
      href="mailto:boutell@boutell.com">boutell@boutell.com</A>)编写的应用于整个服务器的wusage,它生成很详细的信息,包括服务器怎样、何时及从何处被访问等等。它每周运行一次,可以生成漂亮的图表结果,十分直观。<BR>&nbsp;&nbsp;&nbsp;&nbsp;使用wrsage要求使用ncSA或CERN的Web 
      Server或任何有标准记录文件格式的服务器,还需要有C编译器,wusage可在<A 
      href="http://www.boutell.com/">http://www.boutell.com/</A>得到。<BR>&nbsp;&nbsp;&nbsp;&nbsp;随着时间推移,access_file会越来越庞大,必须定期截留,这时先查看最近一周wusage是否已生成了完整的报表,确定统计结束时间,然后把access_log中该时间前的访问记录删掉,并把wusage生成的结果保存在一个目录中,以便wusage可以生成过去访问情况的图表。<BR><BR><A 
      name=2>二、创建自己的计数器</A><BR>&nbsp;&nbsp;&nbsp;&nbsp;除了使用access_log记录文件外,我们可以创建自己的计数器。这时首先必须决定用何种形式存贮计数结果,是用文本文件还是用DBM文件,然后要决定是否进行文件同步访问的保护,这是用文件锁定来实现的,最后就是确定数据的存贮格式了。<BR><A 
      name=2.1>1、使用DBM文件</A><BR>&nbsp;&nbsp;&nbsp;&nbsp;对DBM文件而言,常用的函数有dbmopen()、dbmclose()、reset()、each()、values()和keys(),用于计数器时,主要使用前两个函数。dbmopen()函数把DBM文件与关联数组绑定,调用语法为:<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
      dbmopen (%array_name, DB_filename, 
      Read_write_mode);<BR>&nbsp;&nbsp;&nbsp;&nbsp;如果这时指定的数据库文件不存在,则自动创建两个名为DB_filename.dir和DB_filename.pag的文件,除非把读写模式设为undef值。<BR>&nbsp;&nbsp;&nbsp;&nbsp;缺省的,只有64个记录被读进内存,可以通过给%array_name分配大小来改变此缺省值。如果你只是给自己的网页做计数,缺省值已经足够了,但如果是给整个服务器建立计数器,一般需要更大的值。<BR>&nbsp;&nbsp;&nbsp;&nbsp;现在看看这三个参数。当调用dbmopen时,%array_name原有的值都被清除(如果有的话),用DBM文件中的值替换掉,给之赋予新值很简单:$array_name{'new_key'} 
      = value; 当调用dbmclose 
      (%array_name);语句时绑定被解除,关联数组中的内容被写如DBM文件,也可以不关闭文件而将内容写入,方法是调用reset 
      (%array_name);语句,注意此语句并不是重置DBM文件,而是将内存中的数据写入文件。第二个参数DB_filename是不包含扩展名的,至于读写模式详见本教程的语言部分。<BR>&nbsp;&nbsp;&nbsp;&nbsp;下面是个使用DBM文件的计数器的简单例子:<BR></P>
      <BLOCKQUOTE>
        <P>1: dbmopen(%COUNTERS, $DOCUMENT_ROOT/DBM_FILES/counters,0666);<BR>2: 
        if(!(defined($counters{'my_counter'})){<BR>3: 
        $counters{'my_counter'}=0;}<BR>4: $counters{'my_counter'})++;<BR>5: 
        $count=$counters{'my_counter'};<BR>6: dbmclose (counters); 
      </P></BLOCKQUOTE>
      <P> </P>
      <P><A name=2.2></A><FONT 
      color=#003333>2、文本文件</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;如果不用DBM文件而用文本文件,除了打开、关闭文件外,还要涉及到数据的读写问题,必须确定合适的数据格式,基本步骤如下:<BR></P>
      <BLOCKQUOTE>
        <P>1)打开文件<BR>2)读取计数<BR>3)自增<BR>4)写入新值<BR>5)关闭文件 </P></BLOCKQUOTE>
      <P><A name=2.3></A><FONT 
      color=#003333>3、文件锁定</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;当更新文件内容时,该文件可能同时被另一个进程修改。对计数器程序而言,如果两个或多个人同时访问页面调用了计数器程序,就会出现多个进程同时修改同一文件的情况,这样有的进程的修改就会失效。当然这并不是太大的问题,只是失去一些计数而已,不过计数器就不准确了,访问的人越多,这个问题就越大。解决办法就是修改时通知其它试图打开该文件的进程等待,或叫文件锁定,修改完再释放,允许其它进程打开文件并修改。有两种方法,一是创建自己的锁定机制,一种是使用系统函数flock()。<BR>1)创建自己的文件锁<BR>&nbsp;&nbsp;&nbsp;&nbsp;这种方法具体实现是创建和删除一个特定名称的文件,这在资源共享机制中通常称作semaphore。下面是个例子:<BR></P>
      <BLOCKQUOTE>
        <P>01: While(-f counter.lock){<BR>02: &nbsp; 
        select(undef,undef,undef,0.1);}<BR>03: 
        open(LOCKFILE,"&gt;counter.lock);<BR>04: dbmopen(%COUNTERS, 
        $DOCUMENT_ROOT/DBM_FILES/counters,0666);<BR>05: 
        if(!(defined($counters{'my_counter'})){<BR>06: &nbsp; 
        $counters{'my_counter'}=0;}<BR>07: $counters{'my_counter'})++;<BR>08: 
        $count=$counters{'my_counter'};<BR>09: dbmclose (counters);<BR>10: 
        close(LOCKFILE);<BR>11: unlink(counter.lock); </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;首先检查锁定标志文件是否存在,如果存在,就说明另一个进程正在使用该文件,于是等待直到该文件(此处命名为counter.lock)不存在为止。此处用select()的特殊形式循环等待,此语句使程序进入休眠状态一段时间,该时间段由最后一个参数定义。之所以不用sleep()函数是因为其基本单位为秒,对这种文件锁定而言太长了,几个微秒就足够了。<BR>&nbsp;&nbsp;&nbsp;&nbsp;当锁定标志文件不再存在,就创建自己的锁定标志文件并开始修改计数,完成后关闭该文件并用unlink函数将之删除,这样其它的进程又被允许修改计数。锁定标志文件并不是特殊的文件,其文件名也可以由你自己随意选择。<BR>2)使用flock()<BR>&nbsp;&nbsp;&nbsp;&nbsp;其实锁定文件是很普通的编程步骤,系统函数flock()提供了这一功能,如果在你的系统上不提供的话,可以使用前面介绍的方法自己实现。<BR>&nbsp;&nbsp;&nbsp;&nbsp;flock()的语法为:<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
      flock (filehandle, 
      lock_type);<BR>&nbsp;&nbsp;&nbsp;&nbsp;参数filehandle为用open()函数打开的文件句柄,lock_type可以为下面四个值之一:<BR></P>
      <BLOCKQUOTE>
        <P>1:定义共享锁。对计数器而言不适用。<BR>2:定义排他锁。<BR>3:定义非阻止锁。此处亦不用。<BR>4:解除锁定。 
      </P></BLOCKQUOTE>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;使用flock()实现的文件锁定例子如下:<BR></P>
      <BLOCKQUOTE>
        <P>1a: dbmopen(%counters,"filename", 0666);<BR>or<BR>1b: 
        OPEN(counters,"&lt;filename")'<BR>2: flock(counters,2);<BR>3: 
        if(!(defined($counters{'my_counter'})){<BR>4: &nbsp; 
        $counters{'my_counter'}=0;}<BR>5: $counters{'my_counter'})++;<BR>6: 
        $count=$counters{'my_counter'};<BR>7: dbmclose (counters);<BR>8: 
        flock(counters,8);  </P></BLOCKQUOTE>
      <P><A name=2.4></A><FONT 
      color=#003333>4、输出计数结果</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;现在一切就绪,只剩下输出我们的计数结果了,有三种输出方法:<BR></P>
      <BLOCKQUOTE>
        <P>1)用上面谈到的SSI方法输出。<BR>2)创建各种文本格式输出。<BR>3)生成各种漂亮的图形结果输出,本教程的《动态创建图像》一章讲述了基本原理并提供了一个x-bitmap格式的小例子,下面介绍两个更完善和漂亮的程序/库,这两个例子均需要C编译器。 </P></BLOCKQUOTE>
      <P><A name=2.5></A><FONT color=#003333>5、www Homepage Access 
      Counter</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;这是一个广为应用的网页计数程序,它利用已有的GIF图象连接起来生成一个GIF图象,此程序是用C语言写的,有适用于各种操作系统的版本,可以在<A 
      href="http://www.fccc.edu/users/muquit/Count.html" 
      target=_blank>www.fccc.edu/users/muquit/Count.html</A>下载。它提供了很多参数,功能比较齐全,生成的图象结果也很漂亮,可以选择图像格式,其自带了一些数字样式,但你可以增加自己的数字图像生成各种想要的图像,<A 
      href="http://cervantes.comptons.com/digits/digits.htm" 
      target=_blank>cervantes.comptons.com/digits/digits.htm</A>提供了很多GIF数字图象。其参数通过QUERY_STRING传递,且必须是小写字母,下面是个较复杂的调用例子:<BR>&nbsp;&nbsp;&nbsp;&nbsp; 
      &lt;img 
      src="/cgi-bin/Count.cgi?ft=9|frgb=69;139;50|tr=0|trgb=0;0;0|wxh=15;20|md=6|dd=A|st=5|sh=1|df=count.dat" 
      align=absmiddle&gt;; 
      <BR>&nbsp;&nbsp;&nbsp;&nbsp;其参数详细说明和使用方法详见上述下载网址。如果有必要的话,研究并修改一下其源程序可以使你生成更适合于自己需要的图象。<BR><A 
      name=2.6>6、使用GD图形库</A><BR>&nbsp;&nbsp;&nbsp;&nbsp;www Homepage Access 
      Counter利用现有的数字图象简化了一部分的工作,其目的就是用于图形计数器。GD图形库的功能更加强大,不仅可以用于创建图形计数器,还可以生成各种统计图表,还提供了Perl接口库。GD及其衍生的程序详见本教程《动态创建图像》一章。<BR>&nbsp;&nbsp;&nbsp;&nbsp;在下载的程序中有一个名为gddemo.c的程序演示了其使用方法,在<A 
      href="http://sparke.cs.nyu.edu:8086/cgi.htm" 
      target=_blank>sparke.cs.nyu.edu:8086/cgi.htm</A>有其用于计数器的例子。下面是一个通过GD.pm调用GD图形库生成图像的Perl程序例:<BR></P>
      <BLOCKQUOTE>
        <P>#!/usr/bin/perl<BR><BR>use GD;<BR><BR># create a new image<BR>$im = 
        new GD:Image(100,100);<BR># allocate some colors<BR>$white = 
        $im-&gt;colorAllocate(255,255,255);<BR>$black = 
        $im-&gt;colorAllocate(0,0,0);<BR>$red = 
        $im-&gt;colorAllocate(255,0,0);<BR>$blue = 
        $im-&gt;colorAllocate(0,0,255);<BR># make the background transparent and 
        interlaced<BR>$im-&gt;transparent($white);<BR>$im-&gt;interlaced('true');<BR># 
        Put a black frame around the 
        picture<BR>$im-&gt;rectangle(0,0,99,99,$black);<BR># Draw a blue 
        oval<BR>$im-&gt;arc(50,50,95,75,0,360,$blue);<BR># And fill it with 
        red<BR>$im-&gt;fill(50,50,$red);<BR># Convert the image to GIF and print 
        it on standard output<BR>print $im-&gt;gif; </P>
        <P>(全文完)</P></BLOCKQUOTE></DIV></DIV></TD></TR></TBODY></TABLE>
<DIV align=center></DIV>
<DIV align=center><BR></DIV>
<DIV align=center><SPAN class=myFont><A 
href="http://www.sun126.com/perl5/perl5-16.htm">上页</A> <A 
href="http://www.sun126.com/perl5/perl5index.htm">回目录</A> <A 
href="http://www.sun126.com/perl5/perl5-17.htm#a"><FONT face="Arial, 宋体">Go 
Top</FONT></A></SPAN><BR><BR></DIV>
<TABLE height=50 cellSpacing=0 cellPadding=0 width="100%" bgColor=#000000 
border=0>
  <TBODY>
  <TR>
    <TD bgColor=#cccc99 height=4>
      <DIV align=center><IMG height=4 src="" width=4></DIV></TD></TR>
  <TR>
    <TD height=50>
      <DIV align=center><FONT class=myfont size=2><SPAN class=myfont><FONT 
      color=#99cc99><A href="http://www.sun126.com/bbs/ccb/index.cgi"><FONT 
      color=#99cc99>中国CCB论坛</FONT></A>  整理 麻辣 
      2003.7.10</FONT></SPAN></FONT><FONT class=myfont color=#99cc99 
      size=2><SPAN class=myfont><FONT 
      color=#99cc66><BR></FONT></SPAN></FONT><SPAN class=myfont><FONT 
      class=myfont><SPAN class=myfont><FONT face="Arial, Helvetica, sans-serif" 
      color=#99cc99>&copy; 2000 
      http://www.sun126.com</FONT></SPAN></FONT></SPAN></DIV></TD></TR></TBODY></TABLE></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -