1、CGI 编程的 COOKIE 技术应用 我们在一些留言本、BBS 讨论区发贴时常会出现这种现象:当进入发贴界面时在要求填写用户名和密码的地方就已经自动地填上了你的资料。这是什么会事呢?这是因为程序中引入了COOKIE 技术的缘故。原来在你第一次登录时,程序就已在你的电脑中安装了一个 COOKIE 信息包,在你今后登陆时电脑就自动检索你的 COOKIE 并取出信息包的信息供程序调用,所以出现上面所述的现象。COOKIE 只不过是 CGI 程序要求浏览器持有的一个信息包,这个信息包可以由 CGI 程序在任何时候收回。每当 CGI 程序要求创建 COOKIE 时,COOKIE 可以从服务器传送到浏览
2、器所属的子目录下(通常是保存在 C:WINDOWSTemporary Internet Files 的目录下,这个过程称为 COOKIE 的安装。COOKIE 的安装和读出通常都由一个 CGI 模块来完成,下面我就将此模块的原代码公布给大家,有了这个 COOKIE 模块我们在编写程序时如要应用 COOKIE 技术可以说易如反掌。cookie 的语法: http cookie 的发送是通过 http 头部来实现的,他早于文件的传递,头部 set-cookie 的语法如下: Set-cookie:name=name;expires=date;path=path;domain=domain;secu
3、re name=name: 需要设置 cookie 的值(name 不能使用“;”和“,“号),有多个 name 值时用“;“分隔例如:name1=name1;name2=name2;name3=name3。expires=date: cookie 的有效期限,格式: expires=“Wdy,DD-Mon-YYYY HH:MM:SS“ path=path: 设置 cookie 支持的路径,如果 path 是一个路径,则 cookie 对这个目录下的所有文件及子目录生效,例如:path=“/cgi-bin/“,如果 path 是一个文件,则 cookie 指对这个文件生效,例如:path=“/
4、cgi-bin/cookie.cgi“。domain=domain: 对 cookie 生效的域名,例如:domain=““secure: 如果给出此标志,表示 cookie 只能通过 SSL 协议的 https 服务器来传递。cookie 的接收是通过设置环境变量 HTTP_COOKIE 来实现的,CGI 程序可以通过检索该变量获取cookie 信息。 以下是一个 cookie 的模块,可以为你编写程序带来方便 $Cookie_Exp_Date = ;#此处设置 cookie 的有效时间$Cookie_Path = ;#此处设置 cookie 的有效路径,默认脚本存在的目录。$Cookie_
5、Domain = ; #此处设置 cookie 的有效域名,默认脚本调用的域名。$Secure_Cookie = 0;Cookie_Encode_Chars = (%, +, ;, , =, %Cookie_Encode_Chars = (%, %25,+, %2B,;, %3B, %2C,=, %3D,# 特殊字符的解码Cookie_Decode_Chars = (+, %3A%3A, %26, %3D, %2C, %3B, %2B, %25);%Cookie_Decode_Chars = (+, ,%3A%3A, :,%26, ,%2B, +,%25, %);# 特殊字符的解码#获取 co
6、okie 信息子程序#sub GetCookies local(ReturnCookies) = _;local($cookie_flag) = 0;local($cookie,$value);if ($ENVHTTP_COOKIE) if ($ReturnCookies0 ne ) foreach (split(/; /,$ENVHTTP_COOKIE) #分割 HTTP_COOKIE 变量的字符串($cookie,$value) = split(/=/);foreach $char (Cookie_Decode_Chars) $cookie = s/$char/$Cookie_Decode
7、_Chars$char/g;#调用转码函数$value = s/$char/$Cookie_Decode_Chars$char/g;#调用转码函数foreach $ReturnCookie (ReturnCookies) if ($ReturnCookie eq $cookie) $Cookies$cookie = $value;$cookie_flag = “1“;else foreach (split(/; /,$ENVHTTP_COOKIE) ($cookie,$value) = split(/=/);foreach $char (Cookie_Decode_Chars) $cookie
8、 = s/$char/$Cookie_Decode_Chars$char/g;$value = s/$char/$Cookie_Decode_Chars$char/g;$Cookies$cookie = $value;$cookie_flag = 1;return $cookie_flag;# 设置 Cookie 信息子程序#sub SetSecureCookie if ($_0 = /01$/) $Secure_Cookie = $_0;return 1;else return 0;sub SetCookies local(cookies) = _;local($cookie,$value,
9、$char);while( ($cookie,$value) = cookies ) foreach $char (Cookie_Encode_Chars) $cookie = s/$char/$Cookie_Encode_Chars$char/g;#调用转码函数$value = s/$char/$Cookie_Encode_Chars$char/g;#调用转码函数print Set-Cookie: . $cookie . = . $value . ;#设置 cookie 值if ($Cookie_Exp_Date) print expires= . $Cookie_Exp_Date . ;
10、#设置有效时间if ($Cookie_Path) print path= . $Cookie_Path . ; #设置有效路径if ($Cookie_Domain) print domain= . $Cookie_Domain . ; #设置有效域名if ($Secure_Cookie) print secure; print “n“;shift(cookies); shift(cookies);sub SetCompressedCookies local($cookie_name,cookies) = _;local($cookie,$value,$cookie_value);while (
11、 ($cookie,$value) = cookies ) foreach $char (Cookie_Encode_Chars) $cookie = s/$char/$Cookie_Encode_Chars$char/g;$value = s/$char/$Cookie_Encode_Chars$char/g;if ($cookie_value) $cookie_value .= else $cookie_value = $cookie . : . $value; shift(cookies); shift(cookies);sub GetCompressedCookies local($c
12、ookie_name,ReturnCookies) = _;local($cookie_flag) = 0;local($ReturnCookie,$cookie,$value);if (foreach $char (Cookie_Decode_Chars) $cookie = s/$char/$Cookie_Decode_Chars$char/g;$value = s/$char/$Cookie_Decode_Chars$char/g;foreach $ReturnCookie (ReturnCookies) if ($ReturnCookie eq $cookie) $Cookies$co
13、okie = $value;$cookie_flag = 1;else foreach (split(/foreach $char (Cookie_Decode_Chars) $cookie = s/$char/$Cookie_Decode_Chars$char/g;$value = s/$char/$Cookie_Decode_Chars$char/g;$Cookies$cookie = $value;$cookie_flag = 1;delete($Cookies$cookie_name);return $cookie_flag;#结束#下面是 cookie 信息包安装代码段0) begi
14、n = dc.indexOf(cname);if (begin != -1) begin += cname.length;end = dc.indexOf(“;“, begin);if (end = -1) end = dc.length;return dc.substring(begin, end); return null;/ STOP HIDING FROM OTHER BROWSERS #结束#下面是读取信息包代码,很简单:$name=$Cookiesusername;$pass=$Cookiespassword;本站用的“BBS 讨论区”程序和本人写的“会员管理”程序就采用了此模块。
15、思维稿MYSQL 数据库的使用方法现在网上有很多交互式的程序如 BBS、留言本等都使用 PHP 来编写,而 PHP 是支持 MYSQL数据库的,因此很多人在用 PHP 编程时都使用 MYSQL 数据库。最近有一个网友送给我一份用PHP+MYSQL 编写的留言本程序,在这里我将在调试此程序的体会讲一下(重点是 MYSQL 数据库部分),希望能对喜欢 PHP+MYSQL 的朋友提供有用的参考。此程序由 4 个文件组成,一个是显示贴子的子程序,一个是贴子输入程序,一个是产生框架结构页面的 HTM 文件,一个是数据库结构文本文件。要使用此程序,你的空间必须要支持PHP 和 MYSQL 数据库,我现在使
16、用的空间是由 WWW.51.NET 所提供的满足上述要求。安装此程序的第一步是要安装程序所用的数据库,要成功生成一个数据库你必须要知道你的 MYSQL 服务器的主机名、密码、和在 MYSQL 服务器中分配给你使用的数据库目录名,这些参数都由 ISP 商提供给你,然后用文本编辑器编写一个数据库结构的一般文本文件,格式如下:设你的主机名是:localhost;密码是:12345;用户名:gzdzw;数据库目录名:test# 数据表的结构表 catv#CREATE TABLE catv (id int(11) NOT NULL auto_increment,mail varchar(60),home
17、 varchar(60),content text,reply text,aaa varchar(20),ip varchar(255),replydate varchar(255),date varchar(255),name varchar(10),PRIMARY KEY (id);接着用 phpMyAdmin 程序(此程序是一个专门针对 MYSQL 数据库而编写的 PHP 程序,它可对MYSQL 数据库进行包括:数据库的生成、数据库结构的修改、字段的修改、数据的删除、数据库结构和数据的导出和导入等操作,是使用 MYSQL 的必备工具程序。此程序在网上有很多网站都提供免费下载。)下面讲一讲
18、此程序的设置:找到此程序下的文件:config.inc.php,修改其中的$cfgServers1host = localhost; / 你的主机名$cfgServers1port = ; / 端口设置,空为默认值可不作修改$cfgServers1adv_auth = false; / 出错处理,false 是默认值可不修改。$cfgServers1stduser = root; / MYSQL 默认用户名$cfgServers1stdpass = ; / MYSQL 默认用户密码(一般为空)$cfgServers1user = gzdzw; / MySQL 指定使用者的用户名$cfgServ
19、ers1password = 12345; / MySQL 指定使用者的密码$cfgServers1only_db = test; / 指定使用的数据库目录名$cfgServers1verbose = ; / 指定使用的数据库名然后修改 require(“english.inc.php“);为 require(“chinese_gb.inc.php“);这时程序运行时将显示中文。修改完毕后,将整个程序用 FTP 软件上传到你的使用空间,然后运行 index.php 出现上图的界面,双击左上角的数据库目录名(分配给你的数据库目录名),会出现下图的界面,此时点选“浏览”按钮选取你的库结构文件,然后
20、按“开始”按钮这时程序就自动地将数据库结构导入到 MYSQL 数据库中并产生一个名为 CATV 的数据库文件了,OK!此时你就可以调试你的程序了。那末如何在本地机上调试 MYSQL 的程序呢?很简单只要安装一个 MYSQL 服务器软件(在网上有下载),再将 phpMyAdmin 的 config.inc.php 文件修改一下就万事大吉了。本站的“站务论坛”就是应用了 MYSQL 数据库技术编写的。思维稿SMTP 服务器软件的设置ADR(Advanced Direct Remailer)是一套专门发送邮件的软件,它能够更快、更安全、简便地发送邮件,通过它不仅能节省金钱,还能节省时间。ADR 的主
21、要功能是在我们自己的微机上建立一个本地 SMTP 服务器,在发送邮件时使用自身的 SMTP 端口而不需使用 ISP 提供的发信服务器,ADR 通过 DNS 解析收件人的地址把邮件直接快速地发送到对方的邮件服务器上。在此期间,由于不受 ISP 提供的 SMTP 服务器是否拥挤的影响,而且几乎不用转发服务器,所以邮件发送更加快速、更加安全,而不会造成丢信的现象,更不会因为 SMTP 服务器的关闭而影响邮件的发送。对于经常使用 Email 的广大网友来说,不失为一种绝好的选择。下面,将 ADR 的使用方法详细介绍给大家。一、软件的下载和安装我们可以到 http:/ 版大小为 880KB,也可以到华军
22、软件园(http:)上下载。下载后得到一个压缩文档 Adr.zip,把这个软件包解压到任一目录,执行其中的 Setup.exe 即可顺利安装。该软件是一款共享软件,不注册可以有 15 天的使用期限。二、软件的使用软件安装完毕后,会在“程序”组中生成 Advanced Direct Remailer 项,在桌面上生成快捷图标。双击快捷图标执行程序后,软件会退至任务栏托盘内,形成一个蓝色箭头状的小图标。右击这个图标,会弹出一个菜单,程序提供的各种功能可以在这个菜单中进行调用。1ADR 的设置:在右击图标弹出的菜单中选择“General Settings”,弹出设置窗口,在设置窗口中共有八个标签,下
23、面我们分别予以介绍:General:在这个标签页中共有八个复选框:“Run program when Windows startup”,如果选中,则表示软件将随系统同时启动;“Show Monitor window always topmost”,如果选中此项,则软件的窗口始终在桌面的最上方,不被其他窗口覆盖;“Delete messages after sending,dont move it in Sent”,这个选项如果被选中,则发送的邮件信息将被直接删除,而不是放到 Sent 文件夹中;“Integration with Eserv”,建议选中这个选项,因为Eserv 网站是一个集邮件
24、服务器、新闻服务器、代理服务器、Web 服务器于一身的服务器,把这个选项选中,软件将会更好地运行;“Beep when message is moved in Bad”,当发送出现错误并把邮件转移到 Bad 文件夹中时发声;“Beep when all mail will be sent”,当发送所有邮件时发声(这里提到的发声是通过声卡的外接喇叭发声,而不是通过计算机的小喇叭);“Use message priority in Outbox queue”,如果把此项选中,则在发送邮件时,将首先发送标识为高优先级的邮件;而最后一项“Use delay list”则是过滤垃圾邮件之用。在这几个选项
25、中,我们可以根据自己的情况灵活选用。Actions:在这个标签页中设置邮件的发送情况。在“Start delivery”中有三个单选按钮:“Manually throught program menu”表示通过手工发送邮件;“When dialup connection is established”表示通过指定的连接进行发送,而如果此时连接的名称设定为“Any connection”,则表示只要连接到互联网上就会发送邮件;“Automatically when mail present in Outbox”是给使用专线之类长期在线的用户设置的,自动发送邮件。在“Purge old mail”
26、中有两个选项:“In Sent box after several last days”表示如果在“Sent box”(待发信箱)中信件存放超过指定天数,则将其删除,默认是 15;“In Bad box after several last days”就表示在“Bad Box”中的信息存放到指定天数时将其删除。DNS:ADR 需要指定 DNS(即域名服务器),它需要通过 DNS 解析收件人的邮件地址。这个 DNS 服务器地址,我们可以向 ISP 询问,也可以在软件运行时连入互联网,在这个页面内的“Windows DNS setting”下有显示,按显示顺序顺次填入“Primary DNS”(主
27、控 DNS)、“Secondary DNS”(辅助 DNS)中。在该页面内还有两个复选框,一个是“Try to deliver by name to host,if host was not found in DNS”,默认状态下是选中该项,不用更改。第二个选项是“Dont use internal DNS cache”,这个选项不要选中。因为在发送邮件时,如果不使用 DNS cache,则会在每次发送时都要通过 DNS 进行搜索,即使是向同一个邮件服务器发送邮件也是如此,而如果使用 DNS cache,则在向相同的邮件服务器发送邮件时只须 DNS 解析一次即可,这样能够提高发信速度。Prox
28、y:ADR 支持 Socks5 代理服务器,如果我们是通过代理服务器接入互联网,就可以在这个页面里把代理服务器的地址填入,否则不要进行设置。对于其他几个标签页,如 Logs、Mailbox 等不用设置,软件即可正常工作。2邮件软件的设置ADR 运行之后,我们自己的微机上就已经开通了一个 SMTP 服务器,所以在发邮件时再也不用通过 ISP 提供的 SMTP 服务器了,那么在收发邮件的软件中该如何进行设置呢?在 Outlook Express 5.0 中,我们可以选择主菜单上的“工具”“账号”,选择“邮件”标签,选中邮件名称,按下“属性”按钮,选择“服务器”标签,在“外发邮件(SMTP)”中输入
29、“localhost”,也就是本机地址,或者填入 127.0.0.1,按下“确定”即可。在 FoxMail 中,选择主菜单上的“账户”“属性”,选择“邮件服务器”,在“发送邮件服务器”中填入“localhost”。如果是在局域网中,则需要查询一下安装 ADR 软件的 IP 地址(局域网内地址),然后把其他机器邮件软件的发送邮件服务器地址填为这个地址即可。3邮件的发送把 ADR 和邮件软件设置好后,我们就可以通过我们自己的机器向外直接发送邮件了。和以前一样,在 OE 或者 FoxMail 中撰写好一封邮件,然后按下发送按钮,我们就会看到邮件非常快速地被发送出去。但邮件真的被发到了对方的邮件服务器
30、上了吗?不是,邮件首先被发送到ADR 构造的 SMTP 服务器上,此时我们需要右击托盘内的图标,选择“Open Monitor”查看一下。在 Monitor 界面上我们可以看到三个标签,一个称为“OutBox”,一个是“Sent”,另一个是“Bad”。我们在邮件软件中发送的邮件被送到 OutBox 中待发。如果我们在前面设置时把ADR 设置为手工发送邮件。在这里可以按下“发送”快捷按钮(黑三角形)进行真正的发送邮件,选择主菜单上的“Delivery”“Run Delivery”也可以完成这个功能。发送时,在下面的提示行内会有一个蓝色的进度指示条表示邮件发送的进度,当待发邮件全部发送出去后,Ou
31、tBox 将会被清空。如果在发送中途想中止或停止发送,可以按下“暂停”按钮或“终止”按钮。发送邮件也可以不打开 Monitor 程序,而直接右击托盘内的图标,选择“Run Delivery”进行发送,选择“Pause Delivery”暂停,选择“Stop Delivery”终止发送。由于这款软件不经过 ISP 提供的 SMTP 服务器,所以发信速度很快,尤其是发送大邮件时更加明显。同时,经过 ADR 发送的邮件直接传输到对方的邮件服务器上,我们在邮件发出后,对方可以马上收到,几乎不存在延迟现象。但由于它是一款英文软件,对于一般网友来说在使用过程中稍有困难,好在它的操作、设置都非常简单。 CG
32、I 聊天室程序的剖析一般用 CGI 编写的聊天程序其页面结构均为框架式结构,通常分为四个框架:聊天区、在线人员名单显示区、发言区、其他项目附加区。这些区都显示由 CGI 程序所生成的四个不同的页面。一、发言区发言区其实是一个普通表单页面,根据功能的多少可设置多个参数,如发言者的表情、字体颜色、悄悄话、发言内容、发言者的姓名等,每一个功能都有一个对应的变量,这些变量通过提交按钮传给服务器端的 CGI 程序进行处理。另外,在此区内还可设置一些必要的管理功能,如聊天区的清屏、人员管制(如踢人功能)等功能。这些功能的提交方式一般是用超连接方式进行,即运行 CGI 程序的相应模块来完成相应的操作。二、在
33、线人员名单显示区此区主要是显示在线聊天的人员名单,进入聊天室的人员首先需通过一个入口表单,填入如姓名、密码、性别等参数,然后提交到 CGI 程序,程序就会将此人的这些资料写入到一个在线人员记录文件中,然后利用这条语句对此文件进行定时读取和写入(定时时间可自定),并将读取的数据显示在“在线人员名单显示区”内同时程序还定时地对在线人员是否离线进行检测,如某人已离线,程序将清除此人在人员记录数据文件中的资料。三、聊天区当在发言区按下提交按钮后,表单的所有参数都通过 CGI 程序写入到一个聊天内容记录文件中,同时也是利用这条语句对此文件进行定时读取和写入,将读取的此记录文件中的内容显示在聊天区内,并写
34、入新的发言内容。即对聊天内容记录文件进行不断的定时刷新。 四、其他项目附加区此区一般都是放置一些作者信息或其他的辅助功能。综上所述,聊天室程序一般由六大块模块所组成:1、入口登陆信息处理模块。2、发言表单生成模块。3、在线人员读写显示模块。4、聊天内容读写显示模块。5、框架页面生成模块。6、基本设置模块。从以上分析可知,程序在运行时要不断地对记录文件进行读写,这严重地耗费服务器的资源,使服务器运行其他程序的速度变慢,难怪 ISP 商们都严禁将这种聊天程序放在普通服务器上运行。本人编写的 CGI 聊天程序就以此思路进行编写的,初学 CGI 编程的朋友可随意下载回去作为学习参考。思维稿CGI 程序
35、运行时数据丢失的改进 在用 PERL 写的 CGI 程序在运行当中,常常会发生数据文件丢失的问题,如本站的浏览计数程序就曾经发生过多次数据丢失的情况。这是什么原因呢?据我分析,数据丢失是发生在多个用户对数据文件进行操作时。在程序中对数据文件中的数据更新的程序通常如下: open(re,“tj.txt“);#设此时 tj.txt 文件里面的数据为 100 $a=; close(re); $a+; open(WR,“tj.txt“);#注意此时 tj.txt 数据文件已经被清空 print WR “$a“; close(WR); 执行上面的程序后,数据文件 tj.txt 里面的数据应该为 101。
36、如两个人在一定的时间差内执行以上程序,当第一个人执行完 open(WR,“tj.txt“);这一语句(注意此时 tj.txt 数据文件已经被清空) ,这个时候第二个人刚好跟着执行这一语句,有于数据文件里面的数据是空的,那么变量 a的值为零,当后者执行完整个进程后,显而易见,数据文件里面的数据为 1。综观整个进程,造成数据丢失的关键语句是 open(WR,“tj.txt“);。 针对以上问题,有两种改进方法: 1、给数据文件加锁,即当某一进程打开数据文件后,马上对这一数据文件加锁,防止了其他进程使用它。在完成了对数据文件的操作后,才对数据文件解锁,释放给其他进程使用。加锁语句:flock(WR,1),只要将此语句放到 open(WR,“tj.txt“)的下面即可,当进程执行完 close(WR)语句后,将自动解锁。此语句只能在 UNIX 和 WINDOWS NT 系统下使用。 2、将 open(WR,“tj.txt“)语句改成 open(WR,“+tj.txt“),在执行此语句时,并不清空数据文件里面的数据,从而防止了数据丢失。思维稿