Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5287015
  • 博文数量: 1144
  • 博客积分: 11974
  • 博客等级: 上将
  • 技术积分: 12312
  • 用 户 组: 普通用户
  • 注册时间: 2005-04-13 20:06
文章存档

2017年(2)

2016年(14)

2015年(10)

2014年(28)

2013年(23)

2012年(29)

2011年(53)

2010年(86)

2009年(83)

2008年(43)

2007年(153)

2006年(575)

2005年(45)

分类: LINUX

2007-03-14 11:57:03

一个取得文件扩展名的php函数
 
/*
GetFileType
用法:GetFiletype($filename)
*/
function GetFiletype($Filename) {
if (substr_count($Filename, ".") == 0) { // 检查文件名中是否有.号。
return; // 返回空
} else if (substr($Filename, -1) == ".") { // 检查是否以.结尾,即无扩展名
return; // 返回空
} else {
$FileType = strrchr ($Filename, "."); // 从.号处切割
$FileType = substr($FileType, 1); // 去除.号
return $FileType; // 返回
}
}
$Filename = "Testfilename.php4";
$Filename = GetFileType($Filename);
echo $Filename; //  打印出php4
?>
php的substr函数真是强大(substr.php3)


 
 $rest = substr("abcdef", 1); // returns "bcdef"
echo 'substr("abcdef", 1) returns ' .  $rest . "
";
 $rest = substr("abcdef", 1, 3); // returns "bcd"
echo 'substr("abcdef", 1, 3) returns ' .  $rest . "
";
 $rest = substr("abcdef", -1); // returns "f"
echo 'substr("abcdef", -1) returns ' .  $rest . "
";
 $rest = substr("abcdef", -2); // returns "ef"
echo 'substr("abcdef", -2) returns ' .  $rest . "
";
 $rest = substr("abcdef", -3, 1); // returns "d"
echo 'substr("abcdef", -3, 1) returns ' .  $rest . "
";
 $rest = substr("abcdef", 1, -1); // returns "bcde"
echo 'substr("abcdef", 1, -1) returns ' .  $rest . "
";
?>
我这个程序可以让你上传任何类型的文件并可以直接显示或下载下来(upload_and_show.php3):
    if( $submit)
  {
   header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
   header("Cache-Control: no-cache, must-revalidate");
   header("content-type:application/octet-stream");
   header("content-disposition:inline;filename= $form_data");
   header("content-description:php3 generated data");
  
    $fd = fopen( $form_data,"r");
   while( $string = fread( $fd,200)){
   echo  $string;
   }
   fclose( $fd);
  }
else { ?>
  


   file description:

  
  
  
file to upload/store in database:

  
  


    


  

例子:用PHP3实现MySQL数据的分页显示


 
建表及生成测试数据(mysql.sql):
create table pagetest(
id int unsigned not null primary key auto_increment,
name text not null
);
insert into pagetest(name) values('您好,朋友,这是分页测试数据!');
insert into pagetest(name) values('第2条');
insert into pagetest(name) values('第3条');
insert into pagetest(name) values('第4条');
insert into pagetest(name) values('第5条');
insert into pagetest(name) values('第6条');
insert into pagetest(name) values('第7条');
insert into pagetest(name) values('第8条');
insert into pagetest(name) values('第9条');
insert into pagetest(name) values('第10条');
insert into pagetest(name) values('第11条');
insert into pagetest(name) values('第12条');
insert into pagetest(name) values('第13条');

显示程序(mysql.php3):
 $pagesize = 2;//每页显示2条记录

 $server = mysql_pconnect("localhost","test","test") or die("无法连接到localhost主机上的MySQL数据库服务器!");//以test账号、test密码连接localhost主机上的MySQL数据库
 $db = mysql_select_db("test") or die("无法连接到test数据库!");

 $sql = "select count(*) as total from pagetest";//生成查询记录数的SQL语句
 $rst = mysql_query( $sql) or die("无法执行SQL语句: $sql !");//查询记录数
 $row = mysql_fetch_array( $rst) or die("没有更多的记录!");//取出一条记录
 $rowcount =  $row["total"];//取出记录数
mysql_free_result( $rst) or die("无法释放result资源!");//释放result资源

 $pagecount = bcdiv( $rowcount  $pagesize-1, $pagesize,0);//算出总共有几页

if(!isset( $pageno))  $pageno = 1;//在没有设置pageno时,缺省为显示第1页
if( $pageno<1)  $pageno = 1;//若pageno比1小,则把它设置为1
if( $pageno> $pagecount)  $pageno =  $pagecount;//若pageno比总共的页数大,则把它设置为最后一页

if( $pageno>0){
 $href = eregi_replace("/","/",urlencode( $PHP_SELF));//把 $PHP_SELF转换为可以在URL上使用的字符串,这样的话就可以处理中文目录或中文文件名
if( $pageno>1){//显示上一页的裢接
echo '上一页 ';
}
else{
echo '上一页 ';
}
for( $i=1; $i< $pageno; $i ){
echo '' .  $i . ' ';
}
echo  $pageno . ' ';
for( $i ; $i<= $pagecount; $i ){
echo '' .  $i . ' ';
}
if( $pageno< $pagecount){//显示下一页的裢接
echo '下一页 ';
}
else{
echo '下一页 ';
}

 $offset = ( $pageno-1) *  $pagesize;//算出本页第一条记录在整个表中的位置(第一条记录为0)
 $sql = "select * from pagetest LIMIT  $offset, $pagesize";//生成查询本页数据的SQL语句
 $rst = mysql_query( $sql);//查询本页数据
 $num_fields = mysql_num_fields( $rst);//取得字段总数
 $i = 0;
while( $i< $num_fields){//取得所有字段的名字
 $fields[ $i] = mysql_field_name( $rst, $i);//取得第i 1个字段的名字
 $i ;
}
echo '

';//开始输出表格
echo '';
reset( $fields);
while(list(, $field_name)=each( $fields)){//显示字段名称
echo "";
}
echo '';
while( $row=mysql_fetch_array( $rst)){//显示本页数据
echo '';
reset( $fields);
while(list(, $field_name)=each( $fields)){//显示每个字段的值
 $field_value =  $row[ $field_name];
if( $field_value==""){
echo '';
}
else{
echo "";
}
}
echo '';
}
echo '
 $field_name
 $field_value
';//表格输出结束
mysql_free_result( $rst) or die("无法释放result资源!");//释放result资源
}
else{
echo "目前该表中没有任何数据!";
}

mysql_close( $server) or die("无法与服务器断开连接!");//断开连接并释放资源
?>

 

正则表达式判断email和URL, 帮忙看看有没有要补充的.


 

echo 'a:'.htmlspecialchars( $a);
echo '
a1:';
 $a1 = eregi_replace('(^[_.][:alnum:]-] @([[:alnum:]][[:alnum:]-]*.) [[:alpha:]]{2,3} $)',' a1: $a1";

echo '
a2:';
 $a2 = eregi_replace('([[:alnum:]] ://([[:alnum:]][[:alnum:]-]*\.) [[:alpha:]]{2,3}([#\?/\\][^#\?/\\][:space:]][^[:space:]]*)?)',
'
\1',  $a);
echo htmlspecialchars( $a2);
echo "
a2: $a2";
// eregi('^[_.][:alnum:]-] @([[:alnum:]][[:alnum:]-]*\.) [[:alpha:]]{2,3} $', $a) or die("not a email");
?>





怎样校验输入的日期为合法的日期?这里有一个例子(checkdate.php3


 


function is_numeric( $var){
 $str = (string) $var;
 $int = (int) $var;
 $strstr = (string) $int;
if( $strstr== $str) return true;
else return false;
}

function check( $year, $month, $day)
{
if(is_numeric( $year) and is_numeric( $month) and is_numeric( $day)){
if(checkdate( $month, $day, $year)){
echo  $year . "年" .  $month . "月" .  $day . "日 是合法日期!
";
}
else{
echo  $year . "年" .  $month . "月" .  $day . "日 不是合法日期!
";
}
}
else{
echo  $year . "年" .  $month . "月" .  $day . "日 不是合法日期!
";
}
}

check("1999","1","1");
check("2000","2","31");
check("1900","2","1");
check("1900.2","2","1");
check("aaa","1","1");
?>

在PHP中include和require到底有什么区别呢?看这里的例子就知道


 
include.php3的运行结果是:
  这是inc1.inc文件中的一个变量的值!
  这是inc2.inc文件中的一个变量的值!
  inc1.inc文件中的 $int变量值为1!

require.php3的运行结果是:
  这是inc1.inc文件中的一个变量的值!
  inc1.inc文件中的 $int变量值为2!

你可以看到在require.php3中 $int变为了2,也就是说inc1.inc中的语句被执行了2次,这样看来在循环中require语句只被解释一次,而且会把require语句所在的位置用require的文件内容替代并运行,而在循环中include语句每次都会被解释运行。

[sonymusic]补充道:
require是只执行一次的,不,这么说不恰当。应当说,require是先替代,将指定文件的内容代进来,再运行,所以它不知道你设置了一FOR循环。而include语句,是什么时候执行到了,什么把指定文件的内容代进来,继续执行。

include.php3:
  
  
    for( $i=1; $i<=2; $i ){
   include("inc $i.inc");
  }
  echo  $var1;
  echo  $var2;
  echo 'inc1.inc文件中的 $int变量值为' .  $int . "!
";
  ?>
  
  

require.php3:
  
  
    for( $i=1; $i<=2; $i ){
   require("inc $i.inc");
  }
  echo  $var1;
  echo  $var2;
  echo 'inc1.inc文件中的 $int变量值为' .  $int . "!
";
  ?>
  
  

inc1.inc:
     $var1 = "这是inc1.inc文件中的一个变量的值!
";
  if(isset( $int)){
    $int ;
  }
  else{
    $int = 1;
  }
  ?>

inc2.inc:
     $var2 = "这是inc2.inc文件中的一个变量的值!
";
  ?>


例子:计算两个相差的天数


 
 $time1 = mktime(10,20,30,2,5,2000); //2000-2-5 10:20:30
 $time2 = mktime(18,30,20,5,2,2000); //2000-5-2 18:30:20

 $diff = (int)(( $time2- $time1)/(24*3600));

echo " $time2 和  $time1 的时间差为:" .  $diff . "天
";
?>


例子:用PHP3发送MIME格式的邮件(可以发附件了哦)


 
这有个例子:

/*
* Class mime_mail
* Original implementation by Sascha Schumann <>
* Modified by Tobias Ratschiller <>:
* - General code clean-up
* - separate body- and from-property
* - killed some mostly un-necessary stuff
*/

class mime_mail
{
var  $parts;
var  $to;
var  $from;
var  $headers;
var  $subject;
var  $body;

/*
* void mime_mail()
* class constructor
*/
function mime_mail()
{
 $this->parts = array();
 $this->to = "";
 $this->from = "";
 $this->subject = "";
 $this->body = "";
 $this->headers = "";
}

/*
* void add_attachment(string message, [string name], [string ctype])
* Add an attachment to the mail object
*/
function add_attachment( $message,  $name = "",  $ctype =
"application/octet-stream")
{
 $this->parts[] = array (
"ctype" =>  $ctype,
"message" =>  $message,
"encode" =>  $encode,
"name" =>  $name
);
}

/*
* void build_message(array part=
* Build message parts of an multipart mail
*/
function build_message( $part)
{
 $message =  $part["message"];
 $message = chunk_split(base64_encode( $message));
 $encoding = "base64";
return "Content-Type: ". $part["ctype"].
( $part["name"]?"; name=\"". $part["name"]."\"":"").
"\nContent-Transfer-Encoding:  $encoding".
"\nContent-Disposition: inline".
( $part["name"]?"; filename=\"". $part["name"]."\"":"").
"\n\n $message\n";
}

/*
* void build_multipart()
* Build a multipart mail
*/
function build_multipart()
{
 $boundary = "b".md5(uniqid(time()));
 $multipart = "Content-Type: multipart/mixed; boundary = \" $boundary\"\n\nThis
is a MIME encoded message.\n\n-- $boundary";

for( $i = sizeof( $this->parts)-1;  $i >= 0;  $i--)
{
 $multipart .= "\n". $this->build_message( $this->parts[ $i])."-- $boundary";
}
return  $multipart.= "--\n";
}

/*
* void send()
* Send the mail (last class-function to be called)
*/
function send()
{
 $mime = "";
if (!empty( $this->from))
 $mime .= "From: ". $this->from."\n";
if (!empty( $this->headers))
 $mime .=  $this->headers."\n";

if (!empty( $this->body))
 $this->add_attachment( $this->body, "", "text/plain");
 $mime .= "MIME-Version: 1.0\n". $this->build_multipart();
mail( $this->to,  $this->subject, "",  $mime);
}
}; // end of class

/*
* Example usage
*

 $attachment = fread(fopen("test.jpg", "r"), filesize("test.jpg"));

 $mail = new mime_mail();
 $mail->from = "";
 $mail->headers = "Errors-To: ";
 $mail->to = "";
 $mail->subject = "Testing...";
 $mail->body = "This is just a test.";
 $mail->add_attachment(" $attachment", "test.jpg", "image/jpeg");
 $mail->send();

*/
?>

 

实例学习PHP之投票程序篇


 
要想学习PHP,当然少不了要安装PHP啦,所以如果你是初次学习,请先阅读网络学院的文章:

 

   PHP4.03在linux下的安装

   PHP4.04在win98下的安装

   PHP4.04在英文win2000下的安装

   如果你找不到安装程序请到下面下载:

   PHP4.04Beta WIN32 安装程序


   PHP4.03源程序


   PHP3.0.16 WIN32 安装程序


   PHP3.0.16源程序

   本篇是"实例学习 PHP 之表单处理"的后继篇,请对php处理表单不清楚的朋友先看前篇————实例学习 PHP 之表单处理。

   大家学习完前一篇表单处理之后,是不是信心十足的想做点小程序呢?OK,下面我们来开始做一点真正有用的东西吧!一个可以应用的PHP的投票程序。在这篇里大家将学习到cookie技术的使用,PHP的数组操作及档案的处理。如何?大家准备好了吗?Let's go!

   在开始具体的程序设计之前,我们先学习一下几个下面需要用到的重要概念和函数:

   首先是cookie,我们需要用他来防止同一台机器进行重复投票。

   那么什么是cookie?如果你的英文够好,又想吃块原味的cookie,那么先到这里来尝尝鲜;要不然你就只有吃地藏给你热的啦………(不好吃别扁我哟,:-)) )

   cookie原义在美语中是小甜饼的意思,当然我们现在不是要吃饼,在这cookie指的是一个有许多限制的ASCII文件。它是由服务器发给用户用于记录着用户在浏览过程中的一些信息。Cookies的文件大小被限制在4K以内。 cookie的用途是非常多的,比如你到过的一些网站有记录你来过次数,那就多半是用了cookie。 在这里我们用他来记录访问者是否已经投过票。

   在PHP里我们可以非常方便的用setcookie函数来使用cookie,cookie实际上是HTTP协议中header的一部分。因此setcookie函数必须在没有任何其它信息输出到浏览器之前调用。说简单点就是要在< html>标志前用这个函数啦………。下面是setcookie的用法示例,来自星空浪子的PHP4中文手册,大家等下还可以再参照一下我们在程序中的具体用法。

   setcookie

   送出 Cookie 资讯到浏览器。

   语法: int setcookie(string name, string value, int expire, string path, string domain, int secure);

   传回值: 整数

   函式种类: 网路系统

   内容说明

   本函式会跟着标头 Header 送出一段小资讯字串到浏览器。使用本函式要在送出 HTML 资料前,实际上 cookie 也算标头的一部份。本函式的参数除了第一个 name 之外,都是可以省略的。参数 name 表示 cookie 的名称;value 表示这个 cookie 的值,这个参数为空字串则表示取消浏览器中该 cookie 的资料;expire 表示该 cookie 的有效时间;path 为该 cookie 的相关路径;domain 表示 cookie 的网站;secure 则需在 https 的安全传输时才有效。

   expire时间的格式如下:

   Wdy, DD-Mon-YYYY HH:MM:SS GMT

   GMT表示格林尼治标准时间

   使用范例

   (27-May-1999) 所提供的 setcookie() 及 header() 范例。

   < ?php
    $status = 0;
   if (isset( $myTstCky) && ( $myTstCky == "ChocChip"))  $status = 1;
   if (!isset( $CCHK)) {
   setcookie("myTstCky", "ChocChip");
   header("Location:  $PHP_SELF?CCHK=1");
   exit;
   }
   ?>
   < html>
   < head>< title>Cookie Check< /title>< /head>
   < body bgcolor="#FFFFFF" text="#000000">
   Cookie Check Status:
   < ?php
   printf ('< font color="#%s">%s< /font>< br>;',
    $status ? "00FF00" : "FF0000",
    $status ? "PASSED!" : "FAILED!");
   ?>
   < /body>
   < /html>

 

   怎么样?大家对cookie的用法是不是有所了解呢?地藏在这里告诉大家一个关于expire日期的小技巧,如果你想让cookie的expire日期为从当前算起的第三天。那么你可以使用time()函数,这个函数将返回一个以秒为单位的当前时间(注意哟!这个时间是包括了年月日的,是不是很奇怪?:)),那么如果你想把expire日期定为第三天,那么就是 time() 60*60*24*3。

   PHP的数组使用非常简单,大家只要注意它默认的起始下标是象C语言一样从零开始的,当然你也可以自己设定它的下标,如下面这样:

    $descArray=array(
   1=>"英文:源代码、程序下载",
   2=>"英文:php动态",
   3=>"英文:新闻组、公告栏",
   4=>"英文:教学类",
   5=>"中文:源代码、程序下载",
   6=>"中文:新闻组、公告栏",
   7=>"中文:教学类" );

 

   使用的时候  $descArray[1]= "英文:源代码、程序下载"。更绝的是你还可以………

    $MyArray2 = array( "
   地支" => array("子", "丑", "寅", "卯"),
   "生肖" => array("鼠", "牛", "虎", "兔"),
   "数字" => array(1, 2, 3, 4) );

 

   用的时候 $MyArray2["地支"][0]="子"; 怎么样?是不是很有人情味啊,:)

   最后我们来看看PHP的档案处理,PHP中用于档案处理的函数有大概几十个,在我们这一节里,使用了其中的五个函数fopen(); fclose(); flock();fexists();fwrite(); 其中我想重点说一下flock();其它的大家就去自己查手册吧。

   为什么要重点说flock()?因为这是一个对于网络编程非常重要的功能,我举个例子,两个人同时投票,而且选的都是选项A,假设他们同时打开数据文件,这时A的选票是2,然后两个进程都在原有的基础上加1,接着一个写入了数据,另外一个也跟着写完了写入,大家想这时会出现什么情况?A的选票是多少?正确结果应该是4,但实际上却会是3。为什么会这样?这就是因为网络的多人环境的特点啦,所以我们在投票前一定要先用flock()函数把文件锁住,投完后再打开文件让其它的进程进行操作,这样才能防止出现上面的那类错误。下面是flock函数的用法说明。

   flock 锁住档案。

   语法: boolean flock(int fp, int operation);

   传回值: 布林值

   函式种类: 档案存取

   内容说明 本函式用来锁住档案,使别的行程无法存取。传入的参数 fp 为档案的指标。参数 operation 的值为下列的数字之一:

   1 、表示设定锁住档案可以允许别的行程读取;

   2 、表示只有该行程可以写入档案;

   3 、表示读写均锁住;

   4 、不锁住区块 (block)。

   而本函式无论在 UNIX 或是 Windows 系列中的锁住效果都相近。执行成功则传回 true 值,否则传回 false 值。

 

   好了,基础的东西已经学完,让我们来进行实战吧!大家先下这个范例程序。然后可以在自己的平台上先试试看。相信这样会得到一点感性认识。

   在这个应用中一共使用了三个文件vote.php,config.php,1.gif以及一个保存数据的文件(该文件的名字可以自由设定,在这里我们设为sum.txt),其中vote.php是主程序文件,config.php则用于设置一些经常需要修改的信息。

   //config.php文件

   < ?

   //title变量设定本html档中的title标记,也就是在浏览器标题栏里出现的标题
    $title=读者类型调查表;

   //设定调查内容。这里用了一个数组,注意用""号把内容括起来
    $option= array("学生","工人","农民","知识分子","资本家","流氓");

   //设定调查结果保存到哪个文件中去
    $countfile = "sum.txt";

   //设定同一机器可以再次投票的时间
    $limitdate = time() 60*60*24*365;

   ?>

   // vote.php文件

   /*首先将配置信息装进来,这里我简单说明一下 require和include的区别,require通常放在PHP 程序的最前面,PHP 程式在执行前,就会先读入 require 所指定引入的档案,使它变成 PHP 程式网页的一部份。常用的函式,亦可以这个方法将它引入网页中。 include 则一般是放在流程控制的处理区段中。PHP 程式网页在读到 include 的档案时,才将它读进来。这种方式可以把程式执行时的流程简单化。 */

   < ? require "config.php";?>

   /*下面这部分就是cookie了,它的expire时间在上面的config.php中设置,另外大家可能已经发现了,在这里有两个 if比较语句,第一个是检测是否已经有cookie设置,第二个则是为了避免人家还没有投票程序就把cookie发出去。*/
   < ?
   if (isset( $vote) &&  $vote=="Ready")  $status = 1;
   else  $status=0;
   if ( $ready=="true")
   {
   setcookie("vote","Ready", $limitdate);
   }
   ?>

   < html>
   < head>
   < title>< ? echo  $title ?>< /title>
   < meta http-equiv="Content-Type" content="text/html; charset=gb2312">
   < /head>

   < body bgcolor="#FFFFFF">

   //读出原来的选票结果,赋给变量 $result
   < ?
   if (file_exists ( $countfile)){
    $result = file( $countfile);
   }
   ?>

   /*下面是主程序 用switch做了三个分支,Case 1、查看结果;Case 2、提交选择;Case 3、生成表   单*/
   < ?
   switch ( $elect) {


   /* 查看结果,实际就是把上面用file()函数读出来的变量显示出来*/
   case "查看结果":
   echo "< table border='0'>";
   for( $i=0; $i< count( $result); $i ){
   echo "< tr>"."< td>". $option[ $i]."< /td>";
   echo "< td>"."< img src='1.gif' width='";
   echo " $result[ $i]*10";
   echo "' height='8'> < /td>";
   echo "< td>"." ". $result[ $i]."< /td>< /tr>";
   }
   echo "< /table>";
   break;


   /*把选择结果写入到文件中去,注意要用flock把文件锁住!虽然对投票程序来说这个问题不是特别   突出*/
   case "提交":
   if ( $status == 1){
   echo "你已经投过票了";
   }elseif( $sugest == 0){
   echo "you havn't choice";
   }else{
   if( $fp=fopen( $countfile,"w")){
   if(flock( $fp,3)){
   for ( $i=0;  $i< count ( $option);  $i ){
   if ( $sugest ==  $i 1){
    $result[ $i]= $result[ $i] 1;
   }else  $result[ $i]= $result[ $i] 0;
   echo  $option[ $i]." ". $result[ $i]."< br>";
   fwrite( $fp, $result[ $i]." ");
   }
   }else "投票失败";
   }else echo "投票失败";
   fclose( $fp);
   }
   break;

   /*显示投票的表单*/
   default:
   echo "< form action='vote.php' method='post' name='form1'>";
    $sum = count( $option);
   for ( $i=0;  $i<  $sum;  $i ){
   echo "< input type='radio' name='sugest' value=";
   echo  $i 1;
   if ( $i==0) echo " CHECKED";
   echo ">". $option[ $i]."< br>";
   }
   echo "< input type='hidden' name='ready' value='true'>";
   echo "< br>";
   echo "< input type='submit' name = 'elect' value='提交'>";
   echo "< input type='submit' name='elect' value='查看结果'>";
   echo "< /form>";
   }
   ?>
   < /p>
   < /body>
   < /html>

一个简单的PHP入门源程序如留言板(中文)--新手入门


 
引用“星空浪子”php中文文档的例子:

聊天室,是 Web 站上打发无聊人士的秘密武器。同时,站长或其它人员也可以在这儿杀时间。甚至发生一段轰轰烈烈的网路恋情呢,就算没有,起码可以增加打字的速度。
聊天室,其实就是多人共同使用的 CGI 程式。程式将每个人输入的字串,依系统接收完成的时间整理过后,再送给各个使用者。而 Web 聊天室和 BBS 的聊天室不同的地方是 BBS 聊天室可以每收到一句话,就马上分送给每位在聊天室的网路使用者;Web 由于 CGI 程式不能像 BBS 的 telnet 一直连线,Web CGI 必须以最快的速度将资讯送出,然后结束连线。会形成这种情形,就是因为 Web 聊天室还是使用 HTTP 传输协定,在 HTTP 实作的版本,无论是 0.9、1.0 或是 1.1 版都不能长期占据网路连线的 Port。

为了解决资料无法马上传输的问题,及更新讯息的问题,Netscape 在 3.0 版浏览器之后使用了新的技术,而 Internet Explorer 也实作了这些 Netscape 研发出来的技术。Netscape 将它分成 Server Push 及 Client Pull 二种技术。Server Push 由 Web 伺服器将资料以多重 MIME 编码,送给使用者端,目前较少网站使用这种方式;而 Client Pull 则利用了 HTML 的 meta 标签,并利用 http-equiv="Refresh" 的属性,表示资料要重新载入,至于载入时间,则利用 content 属性来达成。

标签通常都放在 .. 的区段中,以便让浏览器可以仅早准备更新使用者端的网页。下面为 meta 和 PHP 合用的例子,设定为每十五秒重新载入一次。

如果不用 Server Push 或是 Client Pull 来做聊天室,是否有其它的方法,让 Web 的浏览器能聊天呢?答案是肯定的。可以使用 Java 或是 ActiveX (限 IE4、5) 来做甚至自行开发专属的 Browser Plug-in 程式 (如奇摩的聊天室),不过这就和 PHP 没有关系了,不是我们要的重点。

除此之外,由于定期更新所有网友的留言,为了怕写了一半因为 refresh 而被清掉尚未写好的字串,因此将聊天室以 frame 的页框技术来做是有必要的。下例就是聊天室的主程式。




聊天室




<BR><body><BR>本聊天室需使用页框,您的浏览器无法使用<BR></body><BR>

 


程式中以 frame 带出二支 PHP 程式,建议将它们放在同一目录之中,例如 /chatroom,以便日后维护。另外,为了 list.php 及 post.php 可以使用相同的变数,下例将共通的变路路径放在 env.inc 中,可以将它放在 /chatroom 或是 Web 伺服器 (如 Apache) 的 PHP include 设定路径中。


// 档名: env.inc
 $tempdir="/tmp/";
 $chatfile="/tmp/abc";
?>


聊天室的后端可以设计的很简单,单纯的使用档案来做,也可以弄个资料库,将聊天的内容丢入,若是真的很在意系统效率,或许可以考虑使用 UNIX 的行程通讯 IPC 了。

本节即将使用者留言的内容放入档案中,在这儿的例子大部份都使用 UNIX/Linux 的外部指令。若系统无该指令 (或称程式),请自行安装相关程式。

实际上将资料丢入档案中会比使用资料库还快,若还很在乎速度,可以在 UNIX 机器中装上 RAM Disk,再将档案的存取路径都设在该 RAM Disk 上,保证存取速度能满足严苛的要求。在有些以高速度搜寻引擎为号召的网站,甚至将整个资料库资料都放到 RAM Disk 中,马上让系统速度提高十倍百倍,而且 RAM 的价格和其它解决方案相比的话还算很便宜。若使用 Windows NT,那就没办法了,看微软什么时候提供,或者用 Third Party 的产品了。

有些使用者可能对 UNIX 还不是很熟,在这儿先简介会用到的指令:

touch: 建立新档案,或修改旧档的最后更新日期。

echo 加上二个大于符号: 将字串显示转向到指定的地方。

tail: 显示档案最后数行的资料,内定值为十行,可使用减号加数字,修改欲显示的行数。

下面为送出及处理留言字串的程式,程式用到 env.inc 的档案。


// 档名: post.php
require("env.inc");
if (( $chatuser!="") and ( $chattext!="")) {
 $chatstr="".date("h:i:s")."-". $chatuser.": ". $chattext;
 $cmdstr="echo \"". $chatstr."\" >> ". $chatfile;
if (!file_exists( $chatfile)) passthru("touch ". $chatfile);
passthru( $cmdstr);
}
?>

method=post>






匿称:发言:




程式先检查是否有输入字串,若无匿名及发言内容字串则显示发言的表单 (Form),若有资料则将字串及当时时间存入档案中 (利用 UNIX 的转向指令)。当然,为了防止错误,先检查是否有档案可存档,若没有则先 touch 该档,例中的档案就是 /tmp/abc。






// 档名: list.php
require("env.inc");

if (!file_exists( $chatfile)) {
echo "尚未开张";
exit;
}

 $uniqfile= $tempdir.uniqid(rand());
 $shellcmd="/usr/bin/tail -50 ". $chatfile. " > ". $uniqfile;
passthru( $shellcmd);
 $chatfilearray=file( $uniqfile);
 $j=count( $chatfilearray);
for ( $i=1;  $i<= $j;  $i ) {
echo  $chatfilearray[ $j- $i]."
\n";
}
unlink( $uniqfile);
?>


上面的程式就是使用 Client Pull 的技术,每五秒就重新更新一次。同样地,它也 require 共用的 env.inc 档,要改变其中的变数时,马上就可以让所有的程式用到,这对开发网站来说,是蛮重要的方法,可以将网页程式中都会出现的地方。例如 Copyright (C) 1996-2000 的字串,放在一个档案上,到了新的一年,只要改一个档,整个站都改了。

if (!file_exists( $chatfile)) {
echo "尚未开张";
exit;
}

 $uniqfile= $tempdir.uniqid(rand());
 $shellcmd="/usr/bin/tail -50 ". $chatfile. " > ". $uniqfile;
passthru( $shellcmd);

程式先检查有没有使用者发送聊天内容的档案 /tmp/abc,若没有就显示尚未开张,等使用者送聊天内容。若已有聊天资料,就抓出最后五十笔,在在另外的档案中准备显示。

 $chatfilearray=file( $uniqfile);
 $j=count( $chatfilearray);
for ( $i=1;  $i<= $j;  $i ) {
echo  $chatfilearray[ $j- $i]."
\n";
}
unlink( $uniqfile);

将档案读入阵列变数  $chatfilearray 中,并以最后的资料最先显示的方式送给浏览器端,当然可以使用对阵列排序的方法,但确定一定时最后存入的资料在最后面,将它排序实在很浪费 CPU 时间,因此就从最后 echo 到最前面的资料。使用完成还要用 unlink() 指令,将临时档杀掉。

 

删除目录及其下的文件还有问题吗?送大家一个写好的函数


 
/**
* c_function::dir_delete()
* 删除目录
* @param  $file 目录名(不带/)
* @return
*/
function dir_delete( $file)
{
if(file_exists( $file))
{
if(is_dir( $file))
{
 $handle =opendir( $file);
while(false!==( $filename=readdir( $handle)))
{
if( $filename!="."&& $filename!="..") $this->dir_delete( $file."/". $filename);
}
closedir( $handle);
rmdir( $file);
return true;
}
else
{
unlink( $file);
}
}
}
?>

如何利用PHP会话显示出当前在线的用户


 
此文是我前一阵子写的,帖上来以谢大家对我的帮助。
=============

综述
PHP会话即SESSION是指用户从进入网站到关闭网站这段时间内活动的一种机制,它提供了所有网页都共同使用的公共变量存贮机制。那么SESSION到底有什么用处呢?网上购物时大家都用过购物车,你可以随时把你选购的商品加入到购物车中,最后再去收银台结帐。在整个过程中购物车一直扮演着临时存贮被选商品的角色,用它追踪用户在网站上的活动情况,这就是SESSION的作用。
SESSION的发明填补了HTTP协议的局限,HTTP协议被认为是无状态协议,当它在服务端完成响应之后,服务器就失去了与该浏览器的联系。会话的发明使得一个用户在多个页面间切换时能够保存他的信息。
在PHP3版本未直接提供session功能,我们只能用其它办法来实现,比如用PHPLIB。如果说PHP4与PHP3相比,它最大的进步就是提供了SESSION。

Session基础知识
要使用session需要PHP4.1以上的版本,而且需要把php.ini中的register_globle=Off设成register_globle=On。另外,session.cookie_path = / 这行不易更改。
PHP中的session默认情况下是使用客户端的Cookie。当客户端的Cookie被禁用时,会自动通过Query_String来传递。

Php处理会话的函数一共有11个,我们详细介绍一下将要用到几个函数。
1、 session_start
函数功能:开始一个会话或者返回已经存在的会话。
函数原型:boolean session_start(void);
返回值:布尔值
功能说明:这个函数没有参数,且返回值均为true。最好将这个函数置于最先,而且在它之前不能有任何输出,否则会报警,如:Warning: Cannot send session cache limiter - headers already sent (output started at /usr/local/apache/htdocs/cga/member/1.php:2) in /usr/local/apache/htdocs/cga/member/1.php on line 3
2、 session_register
函数功能:登记一个新的变量为会话变量
函数原型:boolean session_register(string name);
返回值:布尔值。
功能说明:这个函数是在全局变量中增加一个变量到当前的SESSION中,参数name就是想要加入的变量名,成功则返回逻辑值true。可以用 $_SESSION[name]或 $HTTP_SESSION_VARS[name]的形式来取值或赋值。
3、 session_is_registered
函数功能:检查变量是否被登记为会话变量。
函数原型:boobean session_is_registered(string name);
返回值:布尔值
功能说明:这个函数可检查当前的session之中是否已有指定的变量注册,参数name就是要检查的变量名。成功则返回逻辑值true。
4、 session_unregister
函数功能:删除已注册的变量。
函数原型:boolean session_session_unregister(string name);
返回值:布尔值
功能说明:这个函数在当前的session之中删除全局变量中的变量。参数name就是欲删除的变量名,成功则返回true.
5、 Session_destroy
函数功能:结束当前的会话,并清空会话中的所有资源。
函数原型:boolean session destroy(void);
返回值:布尔值。
功能说明:这个函数结束当前的session,此函数没有参数,且返回值均为true

上面介绍函数下文将会用到,但还有一些有关session的函数也介绍一下:
6、 session_encode
函数功能:sesssion信息编码
函数原型:string session_encode(void);
返回值:字符串
功能说明:返回的字符串中包含全局变量中各变量的名称与值,形式如:a|s:12:"it is a test";c|s:4:"lala"; a是变量名 s:12代表变量a的值"it is a test的长度是12 变量间用分号”;”分隔。
7、 session_decode
函数功能:sesssion信息解码
函数原型:boolean session_decode (string data)
返回值:布尔值
功能说明:这个函数可将session信息解码,成功则返回逻辑值true
8、 session_name
函数功能:存取当前会话名称
函数原型:boolean session_name(string [name]);
返回值:字符串
功能说明:这个函数可取得或重新设置当前session的名称。若无参数name则表示获取当前session名称,加上参数则表示将session名称设为参数name
9、 session_id
函数功能:存取当前会话标识号
函数原型:boolean session_id(string [id]);
返回值:字符串
功能说明:这个函数可取得或重新设置当前存放session的标识号。若无参数id则表示只获取当前session的标识号,加上参数则表示将session的标识号设成新指定的id
10、 session_unset
函数功能:删除所有已注册的变量。
函数原型:void session_unset (void)
返回值:布尔值
功能说明:这个函数和Session_destroy不同,它不结束会话。就如同用函数session_unregister逐一注销掉所有的会话变量。

 

编程思路
在社区、论坛中,我们常能看到当前在线的会员,使访问者有宾至如归之感。但这种程序是怎么做出来的呢?

流程如下:

 

 

 

 

 

建表user,保存注册用户信息。
字段 类型 备注
userid Int(10) 用户序列号 auto_increment 关键字
username Varchar(50) 用户匿称
userpwd Varchar(50) 密码
email Varchar(50) 电子信箱
oicq Varchar(50) OICQ号
signature mediumtext 签名
imgurl Varchar(50) 头像
joindate Varchar(50) 加入时间
建类文件user.php 定义函数
exist( $username)确认新注册用户是不是已经存在
nsert( $username, $userpwd, $email, $oicq, $imgurl, $signature)插入注册用户
update( $userid, $username, $userpwd, $email, $oicq, $imgurl, $signature) 更新用户数据
get_from_condition( $con) 返回满足查询条件的记录集

建表session。当用户登录时即向此表插入新记录,离开或超时后删除记录,保证表中保存的是当前在线的用户。
字段 类型 备注
sessionid Int(10) 序列号 auto_increment 关键字
userid Int(10) 用户序列号取自user表
ipaddress Varchar(50) Ip地址
lastactivity Int(10) 最后活动时间,用它来判断用户是否还在线
建类文件session.php 定义函数
insert( $userid, $ipaddress, $lastactivity) 把登录成功的用户插入到表中
update( $userid, $ipaddress, $lastactivity)更新在线用户最后活动时间
del( $con)删除满足条件的用户,用它来清除离线用户
get_from_condition( $con) 返回满足查询条件的记录集

公用文件global.php
include "class/config.inc.php"; //把配置文件包含进来
 $db = new db;
 $db-> db_connect( ); //连接数据库
 $user = new user; //初始化
 $session = new session;

//启动会话
session_start();
//删除session表中已经过期的用户(即非在线网友)因为此文件总是被调用从而保证显示的都是当前在线的用户
 $curtime=time();
 $con="lastactivity< $curtime";
 $session->del( $con);

//正在线的网友需不断更新session表中的lastactivity时间,并重新设置用户的COOKIES
if ( $HTTP_SESSION_VARS["online"]=="on"){ //此处也可用 $_SESSION[“online”]
 $userid= $HTTP_SESSION_VARS["userid"]; //取当前在线用户的userid
 $ipaddress=substr( $REMOTE_ADDR,0,50);
 $lastactivity=time() 3600; //更新最后活动时间,如时一个小时之内未调动页面就认为用户已离线,从而会被删除。
 $session->update( $userid, $ipaddress, $lastactivity);
}else{
//如果未登录那直接转入登录页面
 $firstpage="logon.php";
header ("Location:  $firstpage");
exit;
}
登录文件logon.php

if ( $hiddenField=="0"){ //测检表单有未被提交

 $con="username=' $username' and userpwd=' $userpwd'";
 $result= $user->get_from_condition( $con);
if ( $user->counter==1){
if (!session_is_registered("online")){//检测是否被登记过
session_register("online"); //登记一个新的变量为会话变量
}
if (!session_is_registered("ccauser")){
session_register("ccauser");
}
if (!session_is_registered("userid")){
session_register("userid");
}
 $ccauser= $username; //给会话变量赋值
 $online="on"; //这个变量在global.php用到以更新最后活动时间lastactivity
 $userid= $user->userid;
 $ipaddress=substr( $REMOTE_ADDR,0,50);
 $lastactivity=time() 3600;
 $con=" userid= $userid";
 $session->get_from_condition( $con);
//判断会话是否存在,有可能你在不同的机器上登两次。
if ( $session->counter==1){
 $session->update( $userid, $ipaddress, $lastactivity); //如存在,更新
}else{
 $session->insert( $userid, $ipaddress, $lastactivity); //如不存在,插入
}

//在客户机设置COOKIES
SetCookie("ccauser", $username,time() 3600);
Header("Location:test.php");//然后导向测试页
}
}
?>
if( $HTTP_SESSION_VARS["online"]=="") { //判断是否已登录
?>
//下面是登录的表单


名称:
密码:




}else{
echo "网友:". $HTTP_COOKIE_VARS["ccauser"]."你已经登录了"; //如果已登录则显示提示
 $str="

退出社区";
echo  $str;
}
?>

测试文件test.php
include "global.php"; //把global.php文件包含进来
 $strWelcome="欢迎". $_SESSION['ccauser']."
";
echo  $strWelcome; //显示欢迎信息
 $str=” 当前在线用户:
===================
”;
 $con=" 1=1";
//提出session表中所有记录即是当前在线用户,未把游客算在内
 $result= $session->get_from_condition( $con);
while( $row=mysql_fetch_array( $result)){

 $con1="userid= $row[userid]";
 $user->get_from_condition( $con1);
 $str.= $user->username." ";
}
echo  $str;
?>

退出社区

退出文件exit.php
include "global.php"; //把global.php文件包含进来
if ( $_SESSION["online"]=="on"){
 $con="userid= $userid";
 $session->del( $con); //在session表中删除用户信息。
session_destroy(); //结束当前的会话,并清空会话中的所有资源
echo "已经退出社区......";
}
?>

 


 

阅读(2564) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~