用PHP来写记数器(详细介绍)

 更新时间:2016年11月25日 16:14  点击:2164
PHP实例剖析:计数器
作者:Sucre_tiger
本款计数器用文本计数,没有用到数据库,可以实现如下功能:
利用一个文本文件实现多个页的计数减少服务器的I/O占用率在需要纪录的文件里,只需加入很少的几行代码
基本思路如下:
服务器程序从文本文件中读取该页被浏览的次数,(因为所有文件向服务器提出请求时,他们的环境变量REQUEST_URI都代表他来自于何处... ...,所以,以请求文件的环境变量REQUEST_URI来辨别到底是那一页正被浏览。),将这个次数加一储存,并在调用这页的用户的计算机上显示出来。
请先看我的数据文本中纪录的数据样本,(红色为浏览次数,其前面为相应的被浏览的文件)
Counter.dat/script/s2.php|3|/script/s1.php|11| /script/counter.php|5| /testhtml/s2.php|7|/testhtml/s3.php|6|
Now,Let’s go!
counter.php
<html><head>
<title>计数器</title>
<head>
<body>
<?php
/* 定义储存数据的文本文件 */
$counterFile="counter.dat";
/* 定义一个标记,用来辨别现在需纪录的数据是否已经文本数据中 */
$sign=False;
/* 将数据以数组的方式读入变量 $sounterData 备用, */
$counterData=file($counterFile);
/* 用count()函数计算共有多少个纪录 */
/* 用explode()函数把$counterData[$i]按符号"|"分开,并以数组的方式送回到变量$varArray里 */
/* 函数implode()与explode()刚刚相反,把数组$varArray以符号"|"连接起来送回到$counterData */
/* 还利用了环境变量$PATH_INFO
for($i=0;$i<=count($counterData)-1;$i )
 {
  $varArray=explode("|",$counterData[$i]);
  if ($varArray[0]==$GLOBALS["REQUEST_URI"])
   {
    $varArray[1] ;
    print($varArray[1]);
    $counterData[$i]=implode("|", $varArray);
    $sign=True;
    /* 找到本纪录所在的位置后, 用break 退出循环 */ 
    break;
   }
 }
/* 在这里,利用implode()这个函数的功能,将数据整理好了,一起写入文本文件中 */
/* 这样,对服务器的I/O占用就降到了最低点

break
break 结束当前 for,foreach,while,do-while 或者 switch 结构的执行。

continue

结束当前循环,跳转到下次例:

while(1){

  if( $mrs['lm_name']=='首页' || $mrs['lm_name']=='论坛'){continue;}

}

break 可以接受一个可选的数字参数来决定跳出几重循环。


<?php
$arr = array('one', 'two', 'three', 'four', 'stop', 'five');
while (list (, $val) = each($arr)) {
if ($val == 'stop') {
break; /* You could also write 'break 1;' here. */
}
echo "$val<br />\n";
}

/* Using the optional argument. */

$i = 0;
while (++$i) {
switch ($i) {
case 5:
echo "At 5<br />\n";
break 1; /* Exit only the switch. */
case 10:
echo "At 10; quitting<br />\n";
break 2; /* Exit the switch and the while. */
default:
break;
}
}
?> 
 
 

6。bbsd和cq66服务器端改造
bbsd中,关于用户的模块应该比较好改,只要将写.PASSWD文件的操作换为
操作数据库的UserManage类的成员函数即可,但可能要先判断什么数据更改,
要调用哪个函数。并发操作的一致性,则由数据库的加锁功能保证,mysql应该
支持这种的锁吧。文章方面可能比较麻烦,也是将原来对文件的操作转换成操作
数据库的BoardManage类的成员函数即可。
cq66模式应该比较好改动,可能就是原来取文章的协议要变化一下。取文章
标题的时候,同时也将文章的长度发送过去,然后客户端可以根据显示区的大小,
逐步请求文章的内容,请求文章的时候要给出请求的范围。
关于系统模块层,可能做成so的形式会不会较好,(so是不是相当于dll,
容不容易做的,有没有必要?),同时系统模块层应不应该保存一些局部数据呢?
还是做成公用函数一样的接口呢?回想UserManage类,可能没必要区分特权指令,
所有操作都要提供操作对象的id,而权限检查交到上面的服务层来完成?
7。初步测试计划
要测试,等先要把东西做出来,要做东西,先要有别的东西。。。。。
首先将167系统装好,配好mysql,然后学学mysql的 C API 接着建好表,
要做这个计划,先要将短学期的5000行代码写完,然后是复习考研,复习之余将编译器作业作好,再有时间而且没有mm来找我,就可以开始做了。。。。。

4。用户模块设计
对于底层数据库,调用mysql的C API函数来进行数据库的修改,内部保存
一定的状态变量(例如用户名,还是留给上一层完成?),对上一层,则提供
用户管理的接口。
Class UserManage {
private:
char myuserid[20]; // 用户的id,未登陆前为空
time logintime; // 用户登陆时间,并用于计算停留时间
char loginhost[20]; //上站地点。
public:
int NewUser( char *userid, char *passwd );
新建一个用户,判断是否已经有,其他资料暂时为空,
firstlogintime,权限等设缺省值。
int UserLogin( char *userid, char *passwd );
用户登陆,验证密码,
int ChangePasswd( char *oldpasswd, char *newpasswd );
修改密码,要求原密码一致。
int ChangePriData( char *newname, char *newemail,
char *newaddr );
改变基本数据,泥称,email,住址。。。。
int ModifyNumData( int addlogin, int addpost );
修改文章数,上站次数,等数据。。。。注意调用对象。
int UserLogout();
用户退出,修改lastlogin,staytime,loginhost等
// 普通查询命令
int QueryCommonData( const char * userid, int& loginnum,
char * username, int& postnum,
time& lastlogin, char *lasthost );
查询网友基本信息。
// 特权指令,函数在完成功能前,先判断权限。
int QueryPriData( const char * userid, char *email,
char *addr );
查询基本信息,普通人只能查自己,有特权才能查其他人。
int ModifyUserLevel( BOOL isAdd, unsigned long level );
修改用户的权限,
int ModifyUserId( char *oldid, char *newid );
char *newemail, char *newaddr );
修改用户的基本数据。
int ModifyUserNumdata( char *userid, int addlogin, int addpost );
修改用户的文章数等数据。
int ModifyUserPasswd( char *userid, char *newpasswd );
修改用户的密码。
}
以上各个函数难度不大,都是执行相应的sql语句,访问mysql数据库,
是否将一般指令归到特权指令中去呢?权限的检查,是放在这一层还是上一层?
这更多的是看考虑的着重点,是看程序的清晰性还是代码的简练,可能还是
看代码吧,毕竟要考虑访问量,另外,上层服务层是否也应该考虑权限检查
问题呢?
5。版面模块设计
所谓分类,更多的是为telnet服务端考虑的,在cq66模式下,用户可以按
照自己的意愿进行分类,反正最后都是直接以版为基本单位访问的。
对于版面文章的访问,存放的时候以整篇文章为参数,文章的分块由本层
完成,如果上层以块为单位传送,则在上层全部传完,组合后,再传参到本层
分解;在读取 的时候,本层则以块为单位访问,如果上层要以全文为单位访问
,则在上层做合并 工作,本层不管。
至于要不要独立出索引,不影响上层的操作,主要和下层的数据库构造有
关, 主要考虑可行性,效率需求等。
权限的检查放在哪里进行呢?还是放在上层吧,其实就telnet服务器端,
和cq66 的客户端,根本不会给一般用户显示特殊指令的菜单,当然,用户可
以直接发送cq66 的指令,服务器方还是要检查的。但应该不用在它下面的功
能模块层再检查一次吧

  Class BoardManage {
private:
public:
// 有关分类的操作
int GetClassNameInfo( int maxclass, char **classid,
char ** classname );
返回分类的信息,中英文名。
int GetBoardName( int maxboards, char *classid,
char **boardname );
返回某分类中的版面信息,一般分类,直接select ..
from sboard
where boardclass == .... 特殊分类则查相应的表。。。。
// 修改需要版面管理员以上的特权
int NewClass( char * newclassname, int type );
新建分类,普通分类还是特殊分类,
int DeleteClass( char *newclassname );
删除分类,但不cascade,即本层不负责一致性,由上层负责将
相应的版面的分类信息改为别的。分类改名也是先删再建,
int AddClassBoard( const char *classname, char *newboardname );
将已建好的版加入某分类中,专门针对特殊分类,对一般分类,其
效果和modifyboardinfo一样,
int DeleteClassBoard( const char *classname, char *boardname );
从分类中删除某个版,也是针对特殊分类,对一般分类,效果也
是和modifyboardinfo一样,一个版的分类属性可以为空,即不属
于任何分类。
[!--infotagslink--]

相关文章

  • php正确禁用eval函数与误区介绍

    eval函数在php中是一个函数并不是系统组件函数,我们在php.ini中的disable_functions是无法禁止它的,因这他不是一个php_function哦。 eval()针对php安全来说具有很...2016-11-25
  • php中eval()函数操作数组的方法

    在php中eval是一个函数并且不能直接禁用了,但eval函数又相当的危险了经常会出现一些问题了,今天我们就一起来看看eval函数对数组的操作 例子, <?php $data="array...2016-11-25
  • Python astype(np.float)函数使用方法解析

    这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08
  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • C# 中如何取绝对值函数

    本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
  • C#学习笔记- 随机函数Random()的用法详解

    下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • 源码分析系列之json_encode()如何转化一个对象

    这篇文章主要介绍了源码分析系列之json_encode()如何转化一个对象,对json_encode()感兴趣的同学,可以参考下...2021-04-22
  • php中去除文字内容中所有html代码

    PHP去除html、css样式、js格式的方法很多,但发现,它们基本都有一个弊端:空格往往清除不了 经过不断的研究,最终找到了一个理想的去除html包括空格css样式、js 的PHP函数。...2013-08-02
  • c# 数据类型占用的字节数介绍

    本篇文章主要是对c#中数据类型占用的字节数进行了详细的介绍。需要的朋友可以过来参考下,希望对大家有所帮助...2020-06-25
  • 金额阿拉伯数字转换为中文的自定义函数

    CREATE FUNCTION ChangeBigSmall (@ChangeMoney money) RETURNS VarChar(100) AS BEGIN Declare @String1 char(20) Declare @String2 char...2016-11-25
  • Nest.js参数校验和自定义返回数据格式详解

    这篇文章主要给大家介绍了关于Nest.js参数校验和自定义返回数据格式的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-28
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • C++中 Sort函数详细解析

    这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
  • PHP用strstr()函数阻止垃圾评论(通过判断a标记)

    strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回 false。语法:strstr(string,search)参数string,必需。规定被搜索的字符串。 参数sea...2013-10-04
  • index.php怎么打开?如何打开index.php?

    index.php怎么打开?初学者可能不知道如何打开index.php,不会的同学可以参考一下本篇教程 打开编辑:右键->打开方式->经文本方式打开打开运行:首先你要有个支持运行PH...2017-07-06
  • C#中decimal保留2位有效小数的实现方法

    这篇文章主要介绍了C#中decimal保留2位有效小数的实现方法,针对decimal变量保留2位有效小数有多种方法,可以使用Math.Round方法以及ToString先转换为字符串等操作来实现。具体实现方法感兴趣的朋友跟随小编一起看看吧...2020-06-25
  • PHP函数分享之curl方式取得数据、模拟登陆、POST数据

    废话不多说直接上代码复制代码 代码如下:/********************** curl 系列 ***********************///直接通过curl方式取得数据(包含POST、HEADER等)/* * $url: 如果非数组,则为http;如是数组,则为https * $header:...2014-06-07
  • php中的foreach函数的2种用法

    Foreach 函数(PHP4/PHP5)foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。...2013-09-28
  • C语言中free函数的使用详解

    free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
  • 解决Springboot get请求是参数过长的情况

    这篇文章主要介绍了解决Springboot get请求是参数过长的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-17