存档

文章标签 ‘PHP’

让页面不缓存

2010年7月18日 评论已被关闭

# 让它在过去就“失效”
header(“Expires: Mon, 26 Jul 1997 05:00:00 GMT”);

# 永远是改动过的
header(“Last-Modified: “.gmdate(“D, d M Y H:i:s”).” GMT”);

# HTTP/1.1
header(“Cache-Control: no-store, no-cache, must-revalidate”);
header(“Cache-Control: post-check=0, pre-check=0″, false);

# HTTP/1.0
header(“Pragma: no-cache”);
?>

分类: PHP 标签:

php存储图像为带透明的png

2010年6月9日 评论已被关闭

最近在做个东东,用flash传输base64编码的图像数据给php端,php接收后自动分析是jpg的还是png的格式,可是有个问题,在存为png的时候,本来是透明的啊,可是为什么在php输出来却总是带黑底的啊。

最终解决方法:

在php端给图像标识加个imagesavealpha($im,true) ,就OK了。

分类: Flash Platform, PHP 标签: ,

Debugging Flex and PHP

2010年4月8日 评论已被关闭
分类: Flex 标签: ,

解决Cannot modify header information – headers

2008年10月19日 评论已被关闭

今天在编写一个wordpress小插件的时候,在点击禁用的时候,碰到了Cannot modify header information 提示信息,经过搜索找到了解决办法:

  • 在Dreamweaver CS3中打开文件,按ctrl+j 打开页面属性,选择标题/编辑选项,Unicode 标准化表单中选择玩,去掉ROM前面的勾,然后再保存文件,就可以了。
  • 还有一点就是:<?php … <?> 前面不要用空白符
分类: 生活杂谈 标签:

[转]国外主流PHP框架比较

2008年5月16日 评论已被关闭

原文链接:http://blog.csdn.net/heiyeshuwu/archive/2008/05/05/2394800.aspx

最近简单的使用了目前在国内用的比较多的几个主流国外PHP框架(不包括国内框架),大致对这些框架有个直观上的感受,简单分享一下,对于哪些做框架选型的时候,权当一个参考。
主要参考的框架包括:CodeIgniter、CakePHP、ZendFramework、Symfony

说明:我对很多框架也没有认真使用,只是简单试用了一下,可能很多看法不成熟或者是错误的,请大家指正,一起成长。
【 CodeIgniter 】

官方网站:http://codeigniter.com
中文网站:http://codeigniter.org.cn
中文手册:http://codeigniter.org.cn/user_guide
视频教程:http://codeigniter.org.cn/tutorials
测试版本:CodeIgniter_1.6.1

优点:
1. 配置简单,全部的配置使用PHP脚本来配置,执行效率高;具有基本的路由功能,能够进行一定程度的路由;具有初步的Layout功能,能够制作一定程度的界面外观;数据库层封装的不错,具有基本的MVC功能
2. 快速简洁,代码不多,执行性能高,框架简单,容易上手,学习成本低,文档详细;自带了很多简单好用的library,框架适合小型应用

缺点:
1. 把Model层简单的理解为数据库操作
2. 框架略显简单,只能够满足小型应用,略微不太能够满足中型应用需要

评价:
总体来说,拿CodeIgniter来完成简单快速的应用还是值得,同时能够构造一定程度的 layout,便于模板的复用,数据操作层来说封装的不错,并且CodeIgniter没有使用很多太复杂的设计模式,执行性能和代码可读性上都不错。至 于附加的 library 也还不错,简洁高效。

【 CakePHP 】

官方网站:http://www.cakephp.org
中文手册:http://www.1×3x.net/cakephp
视频教程:http://search.you.video.sina.com.cn/s?key=cakephp
测试版本:cake_1.1.19.6305

优点:
1. CakePHP是最类似于RoR的框架,包括设计方式,数据库操作的Active Record方式;设计层面很优雅,没有自带多余的 library,所有的功能都是纯粹的框架,执行效率还不错;数据库层的 hasOne, hasMany 功能很强大,对于复杂业务处理比较合适;路由功能,配置功能还不错;自动构建脚手架(scaffold)很强大;适合中型应用;基本实现过了MVC每一 层;具有自动操作命令行脚本功能;
2. 文档比较全,在国内推广的比较成功,大部分都知道CakePHP,学习成本中等

缺点:
1. CakePHP非常严重的问题是把Model理解为数据库层操作,严重影响了除了数据库之外的操作能力
2. CakePHP的cache功能略显薄弱,配置功能稍嫌弱;CakePHP不适合大型应用,只适合中型应用,小型应用来说略微的学习成本高了点

评价:
总体来说CakePHP框架代表了PHP框架很重要的一个时代和代表,并且目前发挥着很重要的作 用,不少自己写的框架都模仿了CakePHP的方式,是个里程碑式的产品;CakePHP透露着RoR的敏捷开发方式和把数据库操作认为是唯一Model 的设计思想,作为开发快速应用和原型是绝好的工具;同样,用来做Web2.0网站的开发框架,也是值得选择的。
【 Zend Framework 】

官方网站:http://framework.zend.com
中文手册:http://www.phpeye.com/zf
视频教程:http://framework.zend.com/docs/screencasts
测试版本:ZendFramework-1.5.0

优点:
1. 官方出品,自带了非常多的 library,框架本身使用了很多设计模式来编写,架构上很优雅,执行效率中等;MVC设计中,比较简洁,具有路由功能,配置文件比较强大(能够处理 XML和php INI),各种 library 很强大,是所有PHP框架中各种功能最全面的,包括它不仅是一个框架,更是一个大类库(取代PEAR),这是它的主要特色;能够直观的支持除数据库操作之 外的Model层(比 CodeIgniter 和 CakePHP 强),并且能够很轻易的使用Loader功能加载其他新增加的Class;Cache功能很强大,从前端Cache到后端Cache都支持,后端 Cache支持Memcache、APC、SQLite、文件等等方式;数据库操作功能很强大,支持各种驱动(适配器)
2. 文档很全,在国内社区很成熟,并且目前不少Web 2.0网站在使用,学习成本中等

缺点:
1. MVC功能完成比较弱,View层简单实现(跟没实现一样),无法很强大的控制前端页面
2. 没有自动化脚本,创建一个应用,包括入口文件,全部必须自己手工构建,入门成本高
3. Zend Framework 作为一个中型应用框架问题不大,也能够勉强作为大型应用的框架,但是作为一个很成熟的大型PHP框架来说,还需要一些努力

评价:
作为官方出品的框架,Zend Framework的野心是可以预见的,想把其他框架挤走,同时封装很多强大的类库,能够提供一站式的框架服务,并且他们的开发团队很强大,完全足够有能 力开发很强大的产品出来,所以基本可以确定的是Zend Framework前途无量,如果花费更多的时间去完善框架。同样的,Zend Framework架构本身也是比较优雅的,说明Zend官方是有很多高手的,设计理念上比较先进,虽然有一些功能实现的不够完善,比如View层,自动 化脚本等等,这些都有赖于未来的升级。总体来说Zend Framework是最值得期待的框架,当然,你目前要投入你的项目中使用也是完全没问题的。

【 Symfony 】

官方网站:http://www.symfony-project.org
中文网站:http://symfony-project.cn
权威指南:http://www.symfony-project.org/book
学习参考:http://sf.thecodecentral.com
测试版本:symfony-1.0.13

优点:
1. Symfony 是我了解的PHP框架中功能最强大的,而且我使用时间比较长,但是很多功能还是没有挖掘出来;它完整实现了MVC三层,封装了所有东西,包括 $_POST,$_GET 数据,异常处理,调试功能,数据检测;包含强大的缓存功能,自动加载Class(这个功能很爽),强大的i18n国家化支持;具有很强大的view层操 作,能够零碎的包含单个多个文件;非常强大的配置功能,使用yml配置能够控制所有框架和程序运行行为,强大到让人无语;能够很随意的定义各种自己的 class,并且symfony能够自动加载(auto load)这些class,能够在程序中随意调用;包含强大的多层级项目和应用管理:Project –> Application –> Module –> Action,能够满足一个项目下多个应用的需要,并且每层可以定义自己的类库,配置文件,layout;非常强大的命令行操作功能,包括建立项目、建立 应用、建立模块、刷新缓存等等;
2. Symfony绝对是开发大型复杂项目的首选,因为使用了Symfony,将大大节约开发成本,并且多人协作的时候,不会出现问题,在Project级别定义好基础Class以后,任何模块都能够重用,大大复用代码

缺点:
1. 数据库操作model采用了重量级的propel和creole,不过在我测试的版本中已经把他们移到了addon里,可用可不用
2. 缓存功能无法控制,每次开发调试总是缓存,需要执行 symfony cc, symfony rc 来清除和重建缓存;
3. 效率不是很高,特别是解析模板和读取配置文件的过程,花费时间不少;
4. 学习成本很高,并且国内没有成熟的社区和文档,连中文手册都没有,相应的要掌握所有功能,需要花费比较多的时间

评价:
Symfony绝对是企业级的框架,唯一能够貌似能够跟Java领域哪些强悍框架抗衡的东西;强 悍的东西,自然学习复杂,但是相应的对项目开发也比较有帮助,自然是推荐复杂的项目使用Symfony来处理,觉得是值得,后期的维护成本比较低,复用性 很强。相应的如果使用Symfony的应该都是比较复杂的互联网项目,那么相应的就要考虑关于数据库分布的问题,那么就需要抛弃Symfony自带的数据 库操作层,需要自己定义,当然了,Symfony支持随意的构造model层。
【 总评 】

以上数款框架,各有特色,而且都是开源项目,不过框架针对的项目不一样,一般来说 CodeIngiter 比较适合小型项目,CakePHP 和 Zend Framework 比较适合中型项目,Symfony  比较适合大型重量级项目,在项目选型的时候,要充分考虑框架的可以定制性、扩展性,因为每个项目都无法确定你是否会随着需求的变化进行改变。

相对来说,Zend Framework 和 Symfony 应对变化的能力比较强,特别是能够随意定制 model 层的Class,能够非常方便增加自己业务或者数据处理类,我是个人比较推荐在中大型项目中使用的框架。CodeIngiter 和 CakePHP 在中小型项目中同样能够发挥重大作用,快速开发和原型构建,非常适合目标不清晰的原型项目的开发。了解一个框架最好的方式就是使用它,学习它最好的方式就 是看视频。:-)

仁者见仁,智者见智,在项目挑选框架的时候,请先认真考察项目的需求和未来的变化,然后选择合适的框架,让项目开发速度和后期维护性得到一个合理的平衡,当然了,也许,自己写一个框架更适合。

泛泛的评价了几款框架,估计很多东西都没有说到点子上,大家就姑且看之,同样欢迎提出看法指正!

分类: 生活杂谈 标签:

(转)PHP面对对像

2008年5月10日 评论已被关闭

面向对象编程的概念:
不同的作者之间说法可能不一样,但是一个OOP语言必须有以下几方面:

抽象数据类型和信息封装
继承
多态

在PHP中是通过类来完成封装的:

—————————————————
<?php
class Something {
// 在OOP类中,通常第一个字符为大写
var $x;
function setX($v) {
// 方法开始为小写单词,然后使用大写字母来分隔单词,例如getValueOfArea()
$this->x=$v;
}
function getX() {
return $this->x;
}
}
?>—————————————————
  当然你可以按自已的喜好进行定义,但最好保持一种标准,这样会更有效。

  数据成员在类中使用”var”声明来定义,在给数据成员赋值之前,它们是没有类型的。一个数据成员可
以是一个整数,一个数组,一个相关数组(associative array)或者是一个对象。

  方法在类中被定义成函数形式,在方法中访问类成员变量时,你应该使用$this->name,否则对一个方
法来说,它只能是局部变量。

  使用new操作符来创建一个对象:

  $obj=new Something;

  然后你可以使用成员函数通过:

  $obj->setX(5);
  $see=$obj->getX();

  在这个例子中,setX成员函数将5赋值给对象的成员变量x(不是类的),然后getX返回它的值5。

  你可以象:$obj->x=6那样通过类引用方式来存取数据成员,这不是一个很好的OOP习惯。我强烈建议通
过方法来存取成员变量。如果你把成员变量看成是不可处理的,并且只通过对象句柄来使用方法,你将是一
个好的OOP程序员。不幸的是,PHP不支持声明私有成员变量,所以不良代码在PHP中也是允许的。

  继承在PHP中很容易实现,只要使用extend关键字。

—————————————————–
<?php

class Another extends Something {
var $y;
function setY($v) {
$this->y=$v;
}
function getY() {
return $this->y;
}
}

?>—————————————————
“Another”类的对象现在拥有了父类(Something)的全部的数据成员及方法,而且还加上了自已的数据成 员和方法。

你可以使用
$obj2=new Something;
$obj2->setX(6);
$obj2->setY(7);

PHP现在还不支持多重继承,所以你不能从两个或两个以上类派生出新的类来。

你可以在派生类中重定义一个方法,如果我们在”Another”类中重定义了getX方法,我们就不能使 用”Something”中的getX方法了。如果你在派生类中声明了一个与基派同名的数据成员,那么当你处理它时, 它将“隐藏”基类的数据成员。

你可以在你的类中定义构造函数。构造函数是一个与类名同名的方法,当你创建一个类的对象时会被调 用,例如:
—————————————————–
<?php

class Something {
var $x;

function Something($y) {
$this->x=$y;
}

function setX($v) {
$this->x=$v;
}

function getX() {
return $this->x;
}
}

?>—————————————————
  所以你可以创建一个对象,通过:

  $obj=new Something(6);

  构造函数会自动地把6赋值给数据变量x。构造函数和方法都是普通的PHP函数,所以你可以使用缺省参数。

  function Something($x=”3″,$y=”5″)

  接着:

  $obj=new Something(); // x=3 and y=5
  $obj=new Something(8); // x=8 and y=5
  $obj=new Something(8,9); // x=8 and y=9

  缺省参数使用C++的方式,所以你不能忽略Y的值,而给X一个缺省参数,参数是从左到右赋值的,如果
传入的参数少于要求的参数时,其作的将使用缺省参数。

  当一个派生类的对象被创建时,只有它的构造函数被调用,父类的构造函数没被调用,如果你想调用基
类的构造函数,你必须要在派生类的构造函数中显示调用。可以这样做是因为在派生类中所有父类的方法都
是可用的。

—————————————————–
<?php

function Another() {
$this->y=5;
$this->Something();
//显示调用基类构造函数
}

?>—————————————————
  OOP的一个很好的机制是使用抽象类。抽象类是不能实例化,只能提供给派生类一个接口。设计者通常
使用抽象类来强迫程序员从基类派生,这样可以确保新的类包含一些期待的功能。在PHP中没有标准的方法,
但是:

  如果你需要这个特性,可以通过定义基类,并在它的构造函数后加上”die” 的调用,这样就可以保证基
类是不可实例化的,现在在每一个方法(接口)后面加上”die” 语句,所以,如果一个程序员在派生类中没有
覆盖方法,将引发一个错误。而且因为PHP 是无类型的,你可能需要确认一个对象是来自于你的基类的派生
类,那么在基类中增加一个方法来实义类的身份(返回某种标识id),并且在你接收到一个对象参数时校验
这个值。当然,如果一个邪恶不好的程序员在派生类中覆盖了这个方法,这种方法就不起作用了,不过一般
问题多发现在懒惰的程序员身上,而不是邪恶的程序员。

  当然,能够让基类对程序员无法看到是很好的,只要将接口打印出来做他们的工作就可以了。

  在PHP中没有析构函数。

  重载(与覆盖不同)在PHP中不支持。在OOP中,你可以重载一个方法来实现两个或重多的方法具有相同
的名字,但是有不同数量或类型的参数(这要看语言)。PHP 是一种松散类型的语言,所以通过类型重载不
起作用,然而通过参数的个数不同来重载也不起作用。

  有时在OOP中重载构造函数非常好,这样你可以通过不同的方法创建对象(传递不同数量的参数)。在PHP
中实现它的技巧是:

—————————————————–
<?php

class Myclass {
function Myclass() {
$name=”Myclass”.func_num_args();
$this->$name();

//注意$this->name()一般是错误的,但是在这里$name是一个将被调用方法的名字
}
function Myclass1($x) {
code;
}
function Myclass2($x,$y) {
code;
}
}

?>—————————————————
  通过在类中的额外的处理,使用这个类对用户是透明的:

  $obj1=new Myclass(’1′); //将调用Myclass1

  $obj2=new Myclass(’1′,’2′); //将调用Myclass2

  有时这个非常好用。

多态
  多态是对象的一种能力,它可以在运行时刻根据传递的对象参数,决定调用哪一个对象的方法。例如,
如果你有一个figure的类,它定义了一个draw的方法。并且派生了circle和rectangle 类,在派生类中你覆
盖了draw方法,你可能还有一个函数,它希望使用一个参数x,并且可以调用$x->draw() 。如果你有多态性,
调用哪个draw方法就依赖于你传递给这个函数的对象类型。

  多态性在象PHP这样的解释语言(想象一下一个C++编译器生成这样的代码,你应该调用哪一个方法?你
也不知道你拥有的对象是什么类型的,好,这不是重点)是非常容易和自然的。所以PHP当然支持多态性。

—————————————————–
<?php

function niceDrawing($x) {

//假设这是Board类的一个方法
$x->draw();
}

$obj=new Circle(3,187);
$obj2=new Rectangle(4,5);

$board->niceDrawing($obj);
//将调用Circle的draw方法

$board->niceDrawing($obj2);
//将调用Rectangle的draw方法

?>—————————————————

用PHP进行面向对象编程
  一些”纯化论者(purists)”可能会说PHP不是一个真正的面向对象的语言,这是事实。PHP 是一个混合型
语言,你可以使用OOP,也可以使用传统的过程化编程。然而,对于大型项目,你可能想/需要在PHP 中使用
纯的OOP去声明类,而且在你的项目只用对象和类。

  随着项目越来越大,使用OOP可能会有帮助,OOP代码很容易维护,容易理解和重用。这些就是软件工程
的基础。在基于web的项目中应用这些概念就成为将来网站成功的关键。

PHP的高级OOP技术
  在看过基本的OOP概念后,我就可以向你展示更高级的技术:

序列化(Serializing)
  PHP不支持永久对象,在OOP中永久对象是可以在多个应用的引用中保持状态和功能的对象,这意味着拥
有将对象保存到一个文件或数据库中的能力,而且可以在以后装入对象。这就是所谓的序列化机制。PHP 拥
有序列化方法,它可以通过对象进行调用,序列化方法可以返回对象的字符串表示。然而,序列化只保存了
对象的成员数据而不包话方法。

  在PHP4中,如果你将对象序列化到字符串$s中,然后释放对象,接着反序列化对象到$obj,你可以继续
使用对象的方法!我不建议这样去做,因为(a)文档中没有保证这种行为在以后的版本中仍然可以使用。(b)
这个可能导致一种误解,在你把一个序列化后的版本保存到磁盘并退出脚本时。当以后运行这个脚本时,你
不能期待着在反序列化一个对象时,对象的方法也会在那里,因为字符串表示根本就不包括方法。

  总而言之,PHP 进行序列化对于保存对象的成员变量非常有用。(你也可以将相关数组和数组序列化到
一个文件中)。

例子 :

—————————————————–
<?php

$obj=new Classfoo();
$str=serialize($obj);

//保存$str到磁盘上
//几个月以后
//从磁盘中装入str

$obj2=unserialize($str)

?>—————————————————
  你恢复了成员数据,但是不包括方法(根据文档所说)。这导致了只能通过类似于使用$obj2->x来存取
成员变量(你没有别的方法!)的唯一办法,所以不要在家里试它。

  有一些办法可以解决这个问题,我把它留着,因为对这篇简洁的文章来说,他们太不好。

  我会很高兴地欢迎在PHP的后续版本中有全序列化的特性。

使用类进行数据存储
  对于PHP和OOP一件非常好的事情就是,你可以很容易地定义一个类来操作某件事情,并且无论何时你想
用的时候都可以调用相应的类。假设你有一个HTML表单,用户可以通过选择产品ID号来选择一个产品。在数
据库中有产品的信息,你想把产品显示出来,显示它的价格等等。你拥有不同类型的产品,并且同一个动作
可能对不同的产品具有不同的意思。例如,显示一个声音可能意味着播放它,但是对于其它种类的产品可能
意味着显示一个存在数据库中的图片。你可以使用OOP或PHP来减少编码并提高质量:

  定义一个产品的类,定义它应该有的方法(例如:显示),然后定义对每一种类型的产品的类,从产品
类派后出来(SoundItem类,ViewableItem类,等等),覆盖在产品类中的方法,使它们按你的想法动作。

  根据数据库中每一种产品的类型(type)字段给类命名,一个典型的产品表可能有(id, type, price,
description, 等等字段)…然后在处理脚本中,你可以从数据库中取出type值,然后实例化一个名为type
的对象:

—————————————————–
<?php

$obj=new $type();
$obj->action();

?>—————————————————
  这是PHP的一个非常好的特性,你可以不用考虑对象的类型,调用$obj的显示方法或其它的方法。使用
这个技术,你不需要修改脚本去增加一个新类型的对象,只是增加一个处理它的类。

  这个功能很强大,只要定义方法,而不去考虑所有对象的类型,在不同的类中按不同的方法实现它们,然后在主脚本中对任意对象使用它们,没有if…else,也不需要两个程序员,只有高兴。

  现在你同意编程是容易的,维护是便宜的,可重用是真的吗?

  如果你管理一组程序员,分配工作就是很简单的了,每个人可能负责一个类型的对象和处理它的类。

  可以通过这个技术实现国际化,根据用户所选的语言字段应用相应的类就可以了,等等。
拷贝和克隆
  当你创建一个$obj的对象时,你可以通过$obj2=$obj来拷贝对象,新的对象是$obj的一个拷贝(不是一
个引用),所以它具有$obj在当时的状态。有时候,你不想这样,你只是想生成一个象obj类一样的一个新
的对象,可以通过使用new语句来调用类的构造函数。在PHP中也可以通过序列化,和一个基类来实现,但所
有的其它类都要从基类派生出来。

进入危险区域
  当你序列化一个对象,你会得到某种格式的字符串,如果你感兴趣,你可以调究它,其中,字符串中有
类的名字(太好了!),你可以把它取出来,象:

—————————————————–
<?php

$herring=serialize($obj);
$vec=explode(’:’,$herring);
$nam=str_replace(”\””,”,$vec[2]);

?>—————————————————
  所以假设你创建了一个”Universe”的类,并且强制所有的类都必须从universe扩展,你可以在universe
中定义一个clone的方法,如下:
—————————————————–
<?php

class Universe {
function clone() {
$herring=serialize($this);
$vec=explode(’:’,$herring);
$nam=str_replace(”\””,”,$vec[2]);
$ret=new $nam;
return $ret;
}
}

//然后
$obj=new Something();

//从Universe扩展
$other=$obj->clone();

?>—————————————————
  你所得到的是一个新的Something类的对象,它同使用new方法,调用构造函数创建出的对象一样。我不
知道这个对你是否有用,但是Universe类可以知道派生类的名字是一个好的经验。想象是唯一的限制。

分类: 生活杂谈 标签:

PHP5面向对象编程

2008年3月22日 评论已被关闭

PHP5面向对象编程 chm格式电子书

image

点击下载

分类: 未分类 标签: ,

PHP 聊天室教程

2007年10月25日 评论已被关闭

聊天室,是 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> 标签通常都放在 <head>..</head> 的部分中,以便让浏览器可以仅早准备更新用户端的网页。下面为 meta 和 PHP 合用的例子,配置为每十五秒重新载入一次。

<meta http-equiv="Refresh" content="15; url=<? echo $PHP_SELF; ?>">

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

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

<html>
<head>
<title>聊天室</title>
</head>
<frameset rows="*,40" border=1>
<frame src="list.php" name=list scrolling=auto>
<frame src="post.php" name=post scrolling=no>
<noframes>
<body>
本聊天室需使用页框,您的浏览器无法使用
</body>
</noframes>
</frameset>
</html>

/upimg/2006-04-30/155020_06_960.3.gif

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

<?php
// 文件名: 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 的文件。

<?php
// 文件名: post.php
require( "env.inc" );
if (( $chatuser != "" ) and ( $chattext != "" )) {
$chatstr = "<font color=8080ff>" . date ( "h:i:s" ). "</font>-<font color=ff8080>" . $chatuser . "</font>: " . $chattext ;
$cmdstr = "echo \"" . $chatstr . "\" >> " . $chatfile ;
if (! file_exists ( $chatfile )) passthru ( "touch " . $chatfile );
passthru ( $cmdstr );
}
?> <html>
<body bgcolor=ffffff leftmargin=0 topmargin=0 marginheight=0 marginwidth=0>
<form action= <? echo $PHP_SELF ; ?> method=post>
<table border=0 width=100%><tr>
<td align=right>匿称:</td>
<td><input type=text name=chatuser size=8 value=" <? echo $chatuser ; ?> "></td>
<td align=right>发言:</td>
<td><input type=text name=chattext size=30 maxlength=500></td>
<td><div align=right><input type=submit value="送出"></td>
</tr></table>
</form>
</body>
</html>

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

<html>
<meta http-equiv="Refresh" content="5; url= <? echo $PHP_SELF ; ?> ">
<meta content="text/html; charset=gb2312" http-equiv=Content-Type>
<body bgcolor=ffffff leftmargin=0 topmargin=0 marginheight=0 marginwidth=0>
<?
// 文件名: list.php
require( "env.inc" );
if (! file_exists ( $chatfile )) {
echo "尚未开张</body></html>" ;
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 ]. "<br>\n" ;
}
unlink ( $uniqfile );
?>
</body>
</html>

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

if (! file_exists ( $chatfile )) {
echo "尚未开张</body></html>" ;
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 ]. "<br>\n" ;
}
unlink ( $uniqfile );

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

这样就完成了最粗糙的聊天室系统,当然还有很多改进的空间,例如统计使用人数、调用个人….等,就要 Webmaster 再精雕细琢了。

转至:http://www.itepub.net/html/kaifawendang/wangzhankaifa/PHP/phpjichu/2006/0430/8609.html

分类: 未分类 标签:

php取得在线人数

2007年10月25日 评论已被关闭

其实,要真正统计同时在并发在线的人数,是一件不太现实的事,这是因为HTTP协议是种无状态的协议。当客户端向服务器发出一个请求时,服务器会马上建立一个新的TCP/IP连接,在该会话结束后,如页面完全载入后,这个连接就关闭了。一般来说,在线人数指的定是在一定时间段内同时访问站点的人数,而不是基于HTTP协议的并发连接数。
让我们先来看看一个访客是如何访问一个网站的。他在浏览器的地址栏里输入了目标网站的地址,然后在一段时间内持续浏览该网站的网页,最后,关闭浏览器或输入新的网址——浏览结束了。对于服务器端来说,访客到来是可以知道的,访客在浏览页面也是可以知道的,可是怎么知道什么时候走的呢?由于HTTP协议是无状态的,所以无法知道。通常的做法是记下访客最后一次浏览站点页面的时间。如果该访客在一个特定的时间内没有新的动作,那么可以认为他走了。
根据上面的这个思路,我觉得最好用数据库,因为数据库要比其他方法如文本文件的效率要高。下面的例子是使用MySQL的,很容易使用其他类型的数据库系统。然后,在所有的页面中调用这个PHP文件,一方面更新数据,另一方面可以显示在线的人数。但是,有一个问题–到底在多长时间内访问的人算是并发的呢?一般来说,是半个小时,也就是1800秒,具体的要根据网站的情况来确定。这个时间越长,统计出的并发在线的人数就越多。本站的是15分钟,900秒。用访问者的IP地址表示一个访问者是个不错的方法。在拨号上网的情况下,被分配了相同IP地址的两个用户在短时间内浏览同一个网站的概率是很小的。
首先,用MySQL的工具建一个表:
CREATE TABLE ccol(
id integer not null auto_increment, #记录的ID
ip char(15) not null, #访问者的IP地址
dtstamp datetime not null, #最后访问时间
uri char(255), #访问者请求的URI
primary key (id)
);
然后,写一段PHP代码:
<?
/*
文件:ccol.php – ConCurrent OnLine statistics
目的:统计同时在线浏览的人数
作者:Hunte, hunte@phpuser.com
修改:2000-4-25
*/
$duration=1800;
require "db.php";
//包含DBSQL,详情可以参考我的另一篇文章
$ccol=new dbSQL;
$ccol->connect();
$ccol->query("DELETE FROM ccol WHERE (UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(dtstamp))>$duration");
//删除超过半小时的记录
$ccol->query("SELECT * FROM ccol WHERE ip=’$REMOTE_ADDR’");
//判断当前的IP是否在该表中存在
if ($ccol->nf())//有?
{
$ccol->next_record();//下移找到的记录数组的指针
$id=$ccol->f(‘id’);
$ccol->query("UPDATE ccol SET dtstamp=now(), uri=’$REQUEST_URI’ WHERE id=$id");
//设置最后访问时间和访问页面
}
else//没有
{
$ccol->query("INSERT INTO ccol VALUES (0, ‘$REMOTE_ADDR’, now(), ‘$REQUEST_URI’)");
}
$ccol->query("SELECT COUNT(*) AS ccol FROM ccol WHERE (UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(dtstamp))<=$duration");
//找出在半个小时内的记录,后面的WHERE子句可有可无–超出时间的已经被删除了
$ccol->next_record()
echo "在线人数:", $ccol->f(‘ccol’);
$ccol->free_result();
?>
怎么用呢?在站点的每个页面的上面调用这个程序,举例来说:
–index.php

<!–显示在线人数->
<?require ../stats/ccol.php?>

当然,这段代码还有改进的余地。例如,在每次调用是都要删除半小时前的记录,这是没有必要而且会降低效率。可以一个什么办法过更长的时间再做,比如6小时。大家自个儿想想吧,我就不说了。
这种方法只要稍做修改,就可以派上别的用处,如SESSION的管理、网站的访问统计分析等。

转:http://blog.csdn.net/yeqihong/archive/2007/08/23/1755707.aspx

这是一个文本的,你看看吧!你事先建上文件onlin.txt,
<?
$datafile = ‘online.txt’; // 数据文件,如果是linux/unix系统,需要把文件属性设置为777或者666
$onlineTime = 30; // 在线的时间差秒数,这里设置为半分钟
$timestamp = time(); // 取得当前的Unix时间戳
$dat = file($datafile); // 将数据文件读入数组
$count = count($dat); // 取得当前的数据记录数目
$onlineCount = 1; // 在线人数,起始就是1,当前的请求者自己
$insertMe = true; // 判断是否要插入当前请求者的记录,如果当前数据中没有此IP的记录就加入
for($i = 0; $i < $count; $i++) {
$dat[$i] = chop($dat[$i]); // 去处记录尾部的
list($ipadd, $requestUri, $lastRequest) = explode(‘│’, $dat[$i]); // 取得数据
if($ipadd == $REMOTE_ADDR) { // 如果IP和当前请求者的IP一致,就更新Unix时间戳
$dat[$i] = $ipadd.’│’.$requestUri.’│’.$timestamp."";
$insertMe = false;
} else {
// 如果IP和当前请求者IP不一致,那么判断是否在线
if($lastRequest < ($timestamp – $onlineTime)) {
// 不在线,删除本条数据记录
$dat[$i] = ”;
} else {
// 在线,加上尾部的
$dat[$i] .= "";
$onlineCount++; // 在线人数加1
}
}
}
// 用Javas cript输出结果
echo"$onlineCount";
// 将新的数据整合成为字符串
$newDat = join(”, $dat);
if($insertMe) {
// 判断是否需要加入当前请求者的记录
$newDat .= $REMOTE_ADDR.’│’.$REQUEST_URI.’│’.$timestamp."";
}
// 写入数据文件
$fp = fopen($datafile, ‘w’);
fwrite($fp, $newDat);
fclose($fp);
?>
转:http://ynwa.yeah.net)

 

Technorati 标签:
分类: 未分类 标签:

在wordpress中方便的添加自定义标签

2007年10月18日 评论已被关闭

wordpress使用了kses作为xhtml/html的filter(见wp-includes/kses.php),因此多数可能有危害性的标签例如script,object会被wordpress过滤。对于某些个人wordpresser来说,安全问题显然不大,反正只是自己用,即便加入javascript脚本也是出于方便考虑。为了方便广大革命群众,俺提供一个简单的扩展标签的思路:

在wp-includes/kses.php中,有这样一行定义:

PLAIN TEXT

PHP:

  1. if (!defined(‘CUSTOM_TAGS’))

  2. define(‘CUSTOM_TAGS’, false);

  3. // You can override this in your my-hacks.php file   

  4. if (!CUSTOM_TAGS) {

  5.     …….

  6. }

由此可见,只要自定义CUSTOM_TAG常量为true,就可以使用额外的标签了。那么修改步骤可以总结如下:

  • 新增一个my-hacks.php,放在wordpress根目录下,my-hacks.php中有如下定义

    PLAIN TEXT

    PHP:

    1. define(‘CUSTOM_TAGS’, true);

    2. $allowedposttags = array(…你需要增加的标签..);

  • 在wordpress后台开启my-hacks.php的支持

转至:http://www.ooso.net/index.php/archives/375

作者 volcano

分类: 未分类 标签: