最近写了一个 监控在线进程的程序.
目的是为了 能实时监控执行程序是否断线,并及时重启。
用PHP写的,不算难,还成,但对于自己来讲挺有成就感的。
程序部分略省。
#将perl进程指向到一个文本中。
$psfile
PHP调用java类的两种方法
Java语言功能强大,因此在许多情况下在php中来调用Java的功能将十分有用。在php中调用Java语言有两种方法,一种是使用php中的Java扩展模块,另一种是使用minij2ee应用服务器提供的SJOP协议实现。下面我们来比较一下这两种方法各自的特点。
1.php的Java模块
php发布版中包含一个Java扩展模块,可以用来调用Java对象,例如:
<?php
$system=new Java("java.lang.System");
print "Java version=".$system->getProperty("java.version")." <br>";
?>
使用这种方法的优点是比较方便,只要用new Java()来创建一个Java对象,就可以同php类一样来调用Java对象。但是这种方法也有以下明显的缺点:
1.由于php的Java模块根据php的数据类型选择最适合的Java方法,因此无法调用Java过载的函数。
2.php的Java模块将在当前Web Server的进程中载入JVM(Java虚拟机),因此系统开销极大,影响Web Server进程的执行效率。
3.在某些操作系统和Web Server环境中,php的Java模块将使Web Server进程僵死。见http://www.php.net/bugs.php?id=6122。
由于这些原因,php的Java模块一直无法应用到实际的的软件系统中。
2.minij2ee应用服务器SJOP协议实现
在介绍minij2ee应用服务器SJOP协议实现之前,先简单介绍一下minij2ee应用服务器。minij2ee应用服务器是第一款支持php的J2EE应用服务器产品,使php能够用于开发企业级应用系统。SJOP全称是Sample Java ORB Protocol(简单Java对象请求代理协议),是一种简单高效的对象请求代理协议。比如:
<?php
$conn=minij2ee_fetch_connection();
print "Java version=".minij2ee_callstatic_javaobj($conn,"java.lang.System","getProperty","java.lang.String","java.version")." <br>";
?>
minij2ee应用服务器实现SJOP协议的主要目的是使php中能够访问EJB企业级组件,因此minij2ee提供了一个EJB-PHP编译器,可以把EJB组件编译成php的类,使php程序中能够方便的调用EJB组件,例如:
<?php
require("Cart.php"); file://Cart.php是编译Cart EJB后生成的Cart EJB的php类定义。
$home=new CartHome(); file://创建EJB的Home接口。
$objref=$home->create($cart_name); file://创建Cart EJB。
$cart=new Cart($objref);
$cart->add("some goods"); file://向购物车中添加一个物品。
?>
使用minij2ee应用服务器的php支持,就可以开发出基于php和J2EE技术的,面向对象的,稳定高效的企业级应用系统。关于更详细的PHP-J2EE技术的介绍,请访问http://www.minij2ee.com/document/document_index_6_0.html。
php 进阶:灵活地运用 cookie
cookie 是强大而方便的功能,它能提供一个范围内的全程变量,来看看 cookie 的语法:
setcookie(cookievalue,value,time,path,domain);
cookievalue 是设置的 cookie 变量,value 是将一个值设置成 cookie 的变量,time 是这个 cookie 变量作用的时间,path 是 cookie 作用的路径,domain 是 cookie 作用的域;
需要注意的是在 php 程序内设置 cookie 时一定不能在 html 这个标记的后面设置.
下面看个例子:
setcookie("cookietime","2001-5-2",time()+3600,"/","test.php");
这个 cookie 设置的意思是给日期 "2001-5-2" 设置一个 cookie 变量 $cookietime ,其作用时间为 3600 秒,这个变量在 /test.php 里生效.
这时在 test.php 里加上 echo $cookietime; 就会显示出 2001-5-2 .
如果将 cookie 里的时间置空,那么关闭浏览器后,cookie 就失效了.
cookie 有一个特殊的地方就是 cookie 设置的值并不会马上被执行,直到第二次引用时才会被执行,那么第一次引用的 cookie 值是什么呢?
就是 cookie 上一次设置的值,这儿理解起来有点费劲,没关系,举个例子就全明白了:
setcookie("cookietime",time,time()+3600,"/","test.php");
第一次引用时 $cookietime 内没有值,第二次引用时发现 $cookietime 内的 time 才显示出来,修该 time 为 2001:
setcookie("cookietime",2001,time()+3600,"/","test.php");
再执行一次,第一次引用时 $cookietime 的值为 time,第二次引用 $cookietime 的值才为 2001;那么 cookie 的这个特性有何功用呢?聪明的读者可能已经知道其用法了,就是用于通告和报警功能上的;
看个关于使用 cookie 这个特性的例子,这里程序要实现的功能是当用户下一次来浏览网站时,所有这个用户没看过的新信息后面都添加一个 (new),用 cookie 来完成这个功能再简单不过了,至少在我看来还没有任何其它方法能比使用 cookie 来完成这个功能更简单的了.
存储信息自然需要时间值,只要数据库有存储与每条信息相关的时间值加上 cookie 就能完成这个看上去还不错的功能:
test.php:
$time=date(Y-m-d H:i:s);
setcookie("cookietime",$time,time()+3600000,"/","test.php");
......
......
//从数据库取出时间值
最新php3层结构开发技术
P> php作为一种流行的web开发语言,以其编写简单,功能强大的特性已经
被广泛的应用。但是,同时php语言的应用范围却又局限在一些诸如BBS,社区,
投票站等简单的系统。造成这种情况的原因是php缺少一种开发大型应用系统的机
制。将业务逻辑代码直接编写在页面中在开发阶段固然方便,但结果缺使整个系
统的可维护性和可扩展性变得极差。常常碰到这样的情况,当用户需要对系统功
能做一个改动时,将需要修改许多相关的php程序。
当然,如果有一个好的设计会使情况变得好一些,通过函数或类将业务
逻辑封装起来将使情况有所改观。但是,php中对类的支持是有限的,php的仅实
现了对属性和方法的封装,而对于C++/Java里使用的面向对象的一些高级均未支
持。总的来说,php开发中存在的问题也正是C/S结构存在的问题,所以C/S结构渐
渐演化成现在的3层结构或n层结构,引入了中间层的概念。
目前流行的J2EE技术正是这样一种3层结构的应用开发模式,JSP作为前
台表示层,EJB作为中间业务逻辑层,数据库为信息层。通过将表示层和业务逻辑
层的隔离,使系统有了良好的伸缩性,可维护性和可扩展性。因此,J2EE技术适
合于需求多变,功能复杂的企业级应用系统的开发。php同样需要这样一种结构,
使php能够应用到更广阔的领域中去。
现在,我们可以使用minij2ee应用服务器来实现这样的目的。minij2ee
应用服务器是目前唯一支持php的J2EE应用服务器产品。php使用基于minij2ee的3
层开发模式,就可以将业务逻辑封装在EJB中,而使用php来快速定制前台界面。
以在线商店应用系统为例( http://www.minij2ee.com/petstore/ ),EJB封装
了货物管理,账号管理,订单处理等核心业务逻辑,而php用来定制商店的界面,
如产品的陈列方式,柜台的样式等等。由于核心业务逻辑封装于EJB中,因此在线
商店的前端界面可以根据客户的需求任意定制而无需改动EJB程序。另外,由于
J2EE技术的灵活性和可扩展性,即使对于业务逻辑的扩展也将变得如果plug&play
一样方便,只需编写新的EJB整合到原有的系统中即可。
对于市场巨大的中小企业软件系统领域来说,需要的不是庞大昂贵的系
统,而是需要够用且实用,高性价比的软件。是用php+minij2ee再加上高效稳定
的Linux系统和MySQL数据库,正是解决这个问题的良好方案。
构建网站:用户的登入认证
前面已经介绍了几个 php 的功能技巧,从现在开始就来充分利用组合这些技巧来构建一个强大的网站,以后会陆续地介绍一些高级和基本的技巧如何在网站中应用.
建立一个好的网站,用户登认证功能是必不可少的,同样的在这儿我只是介绍思路和做法,并不会添鸭式地一步一步的列出步骤.
首先需要一个可用来记录用户资料的数据库,其内容应当至少包括姓名和密码,自然根据需要可在数据库增加相应的字段.
为了使数据库有资料,必须要有个注册程序,通过注册用户可将资料存进数据库,注册程序的实现非常地简单,仅仅是发出存入数据库的指令,在这里就不再描述了,这里要提出的是,出于对用户资料安全的考虑,最好为用户的密码加密,还有数据库不应出现相同的姓名,否则会乱套.
下面介绍的重点是用户登入和登出的实现,用户登入的功能用 session 和 cookie 都能完成,我在这儿要介绍的是如何用 cookie 来完成这个功能的.
其实用户登入的整个过程理解起来很简单,程序将用户输入的姓名和密码与数据库存储的资料进行对比,数据库有此用户的资料就通过,没有则拒绝该用户通过.
来看看登入程序 login.php 的工作流程:
用户提交资料到 login,php,login.php 就会经过如下处理:
$passwd=md5($passwd);
$result=mysql_query("select * from user where name=$name and passwd=$passwd");
之所以密码要经过 md5 处理,是因为数据库存储的是经过 md5 加密过的密码,判断有无此用户存在,不存在或密码错误则给出些告警给该用户,存在此用户的资料的话,就可以将该用户的资料设置为 cookie 值,如下:
setcookie("cookiename",$name,time()+18000,"","/");
setcookie("cookiepasswd",$passwd,time()+18000,"","/");
如果担心用户因忘记登出而造成安全问题的话,就把时间设置去除:
setcookie("cookiename",$name,"","/");
setcookie("cookiepasswd",$passwd,"","/");
这样当用户关闭浏览器时,cookie 的设置就失效了,也就是说用户下一次来的时候,必须重新登入!虽然有了这个关闭浏览器就让 cookie 失效的安全功能,但还是需要一个用户登出的功能以策安全,登出功能也就是让记载用户资料的 cookie 失效的功能,完成这个功能很简单,只需要将时间置为 -1,并把 cookie 变量置空就行了:
logout.php:
setcookie(cookiename,"",time()-1,/,"");
setcookie(cookiepasswd,"",time()-1,/,"");
$cookiename="";
$cookiepasswd="";
这样一个完整的用户认证功能就完成了.
php 进阶:写一个用户在线显示的程序
在开始这篇文章时,作者假设读者已能够写出一个用户的登入认证程序.
----------------------------------------------------------
记数器可完成访问 web 页的总次数,但却不能得知一个时段中访问量的动态记载,下面就来介绍如何写一个各个时段动态显示访问量的方法.
要记载访问量,首先就要在 mysql 内建立一个数据库,姑且给这个数据库取名为 line,同时建立一个名为 line 的数据表,表内的字段分别为"用户名(name varchar(20)),时间(time datetime)".当然读者也可根据需要增加数据表的字段.
建立好数据库后,就可以开始设计程序了,现在先理清一下思路,要想显示访问量,当然数据库就必须要有记录,我已假设读者有能力写一个用户登入程序了,所以向数据库添加纪录可在登入程序假设为 login.php 里添加:
先给现在时间付值:$time=date(Y-m-d H:i:s);
mysql_select_db(line);
mysql_query("insert into line (name,time) values($name,$time)");
好了,现在每一位登入的用户在数据库里都有了一个记录,下面就来完成用户在线显示的程序 line.php:
<?
mysql_connect("local","","");
mysql_select_db(line);
$result=mysql_query("select * from line");
$num=mysql_numrows($result);
if (!empty($num)) {
echo "<table><tr><td>";
echo "现在在线人数为:$num";
echo "</td></tr>";
for($i=0;$i<$num;$i++){
$name=mysql_result($result,$i,"name");
echo "<tr><td>用户:$name</td></tr>";
}
}
?>
上面这段程序已能显示所有在线的用户人数及各用户名,当然这个程序还很不完善.如果其中一个用户登出离开后,数据库就不应该有此用户的记录所以,还得在登出程序假设为 logout.php 内加上删除功能:
mysql_select_db(line);
mysql_query("delete from line where name=$name");
这时一个基本的用户在线功能已经完成,接下来继续在 line.php 内增加代码使功能更加完善,首先我们得规定用户在多长时间没继续浏览 line.php 时就认为该用户已经离开,这里给定一个时间限制为 5 分钟,也就是说程序将显示从现在开始的前 5 分钟的用户情况,所以必须 line.php 内设置一个现在时间告知程序从这个时间开始执行,然后实现程序执行时把数据库内记录的时间减去现在时间大于 5 分钟的所有记录删除,这样任何用户在执行 line.php 时,都能看到 5 分钟内的所有在线的用户,完成这个功能需要以下这个数据库语句:
php 进阶:活用数组来完成强大的功能
数组在 php 里的运用至少比 C 来的简单,在一般的 php 程序里很少用到数组这个概念,用的较多的是判断,循环和 cookie,但是掌握数组的运用技巧却是很重要,因为它能够使程序的功能更加自动化,让客户在功能强大但操作性能差和功能小巧玲珑但操作性非常方便的程序里选择,我想客户会选择后者.
在介绍数组运用之前,我得在这声明,我在这只是介绍运用数组的思路,即在什么情况下可以运用数组来简化完成任务,其中举的例子也只是提供一个思路,不会面面俱到.
什么时候使用数组,一般在碰到大范围变量传送和处理的情况下考虑用数组来完成.
我用数组完成任务的一个实例:
有一次我为客户写了一个后台管理程序,程序完成后,客户很满意,但过了不久客户就来找我了,并对我说:"我发现里面有很多垃圾信息,我不想保留它们,在删除时,我遇到麻烦了,我不得不每次点删除去删除每一条信息你能不能帮我设计一个一次过把全部垃圾删除的功能...";当然我接受了这个任务,因为客户就是上帝.
在开始加入这个功能进管理程序的时候,我考虑用数组来完成它,于是就写了一个流程图:
查找垃圾信息唯一识别字 id -->数组-->对应数组内的 id 删除数据库记录
好了由这个流程图,就可以开始设计程序了,为了使用数组成功传递变量,我使用了提交表挡的 checkbox,具体的写法:
echo "<input type=checkbox name=delete[$id] value=y>";
这样我就将垃圾信息的 id 与数组下标对应的空间附值,这样就可以对数据库进行实质操作了,下面来看看数组被传到删除功能块时是如何完成任务的;
//首先查找数据库所有记录的 id:
.....
for ($i=0;$i<$num;$i++) {
$id=mysql_result($result,$i,"id");
//判断数组
if (!empty($delete[$id])) {
//执行删除命令
mysql_query("delete from table where id=$id");
}
}
......
一个自动化的删除功能完成了,用数组还可完成很多不同的任务如:随机更新图片,对比等等...
活用数组可以完成一些看上去很难完成的任务
基于 PHP 的聊天室(三)
现在我们有了需要通过$REMOTE_ADDR变量来交叉引用的文件,这样我们可以区分出想要发贴的用户是否已经被扁或没有被扁。很简单:
<?php
for ($counter=0;$counter<sizeof($banned_array);$counter++) {
if ($banned_array[$counter] == $REMOTE_ADDR) {
print("<font color="red" face="arial" align="center">".
"You have been banned from this chat</font>");
exit;
}
}
?>
exit命令将立即停止脚本的执行。在开始对传递过来的变量执行处理之前,插入对被扁用户的检查,这样被扁用户就不能使用聊天室了。
比较好的解决在某些情况下动态IP地址的问题的一个意见就是,检查IP地址块的所属范围。一个简单的函数可以容易地实现它。
<?php
function makeMask($ip) {
// remember to escape the . so PHP doesnt think its a concatenation
$ip_array = explode(".", $ip);
$ip_mask = "$ip_array[0].$ip_array[1].$ip_array[2]";
return $ip_mask;
}
?>
然后我们把循环中的if替换成
<?php
for ($counter=0;$counter<sizeof($banned_array);$counter++) {
if (makeMask($REMOTE_ADDR) == makeMask($banned_array[$counter])) {
print("<font color="red" face="arial" align="center">".
"You have been banned from this chat</font>");
exit;
}
}
?>
我们有了针对动态IP地址的保护措施。
最后我们需要一种方法最先得到惹麻烦的IP。我的实现是将$name和$REMOTE_ADDR记录到一个名为
iplist.html的文件中。对于一个分离的,秘密的URL,我可以在浏览消息的同时监控IP地址。这可以增加一些意外的好处,就是能够发现假冒者--在这些地方最常犯的“罪”。
iplist.html与messages.html的创建方法基本上一样。首先将当前的值从iplist.html中取出来,我们剥离掉头信息,脚标和旧的IP记录,然后创建一个新的记录,新的头信息,新的脚标。为了让布局更清楚,我使用了表格。
基于 PHP 的聊天室(一)
从前有一个相当流行的web聊天室,叫做Star Trekker 聊天室。我能够来到这个聊天室要感谢我的一个朋友,并且即使Star Trekker的聊友们几乎与我不是同一个圈中的,但是我发现对于他们的大部分人来说,都很友好和有意思。但是当Star Trekker关闭之后,这不得不谢谢运行在后台的Perl了,是它吞掉了服务器的资源,所以这些快乐和友善的人们不得不离开,无处可去了。我有幸在那段时间开张了自已的仿Star
Trekker的聊天室,并且开始设法与许多原来的Trekker的那些无家可归的聊友进行联系。出于对Perl所引起的资源消耗问题的警惕,当一个朋友向我推荐PHP时,我非常的高兴。
这个经过精心设计的web聊天室使用了从表单传递过来的变量,并且把它们处理为HTML ,然后将其写入文件。把表单和信息文件放在一个框架中,你可以看到它与一个叫BeSeen的聊天室很象。当然它的好处在于,
我们的聊天室比起它的BeSeen堂兄弟来说要聪明一些。
<form action="chat.php3" method="post">
Name : <input type="text" name="name"><br>
Message : <input type="text" name="message"><br>
<input type="submit" value="Send">
</form>
上面就是基本的用于输入的表单。你可能想把它弄得更美观一些,但是不管出于什么目的,这个就是你要处理的。它发送两个变量给chat.php3,分别叫做$name和$message。
不过,在处理那些变量之前,我们需要从消息文件中把当前的内容取出来,否则在一个时间里我们只能看到一条消息了。几乎没有一个方法可以管理对话。只有象我一样对自已的消息文件的结构很熟悉,我就知道每一条消息都以一个回车符结束。这就是说,可以使用file()函数来将消息文件读到一个数组中去。
消息文件有12行。在12行中,第1行为头信息,第2行到11行为旧的消息,第12行包含了我的脚标。
我最感兴趣的是得到一个能够包含所有那些旧消息的字符串。
<?php
// 把文件读到一个数组中
$message_array = file("messages.html");
// 编辑字符串
for ($counter = 1; $counter < 10; $counter++) {
$old_messages .= $message_array[$counter];
}
?>
在处理字符串的时候,我将for循环的$counter初始化为1而不是0。这是因为我知道$message_array 数组的第0个元素包含的是我的头信息,我不需要它循环结束条件为$counter < 10,意思是只有数组中1到9的元素被读到字符串中。对于剩下的两个元素,第11个包含我的脚标,第10个包含的是最旧的消息。这两个我都想删除,因为在任何时刻我只让屏幕显示10条消息。修改$counter < 10 表达式,可以允许你改变所包含消息的数量。
PHP 域名查询代码
<?php
// 网络技术主管座右铭:三人行,其必有我师焉。http://www.ctohome.com
// 这个代码可以是说是非常的SMART,我改动了小小部分使它更容易用。
$moreinfolist = array( // 储存WHOIS查询主机的连接方法
at => www.ripe.net/cgi-bin/whois?query=,
au => www.aunic.net/cgi-bin/whois.aunic?,
bm => www.bermudanic.bm/cgi-bin/BermudaNIC/rwhois_query_get.pl?query_text=,
ch => www.switch.ch/cgi-bin/domain/search_domain?keyword=,
com=> www.networksolutions.com/cgi-bin/whois/whois/?STRING=,
cz => www.ripe.net/cgi-bin/whois?query=,
de => www.ripe.net/cgi-bin/whois?query=,
dk => www.ripe.net/cgi-bin/whois?query=,
edu=> www.networksolutions.com/cgi-bin/whois/whois/?STRING=,
es => www.nic.es/whois/index.php?type=Dominios&key=,
fi => www.ripe.net/cgi-bin/whois?query=,
fo => www.ripe.net/cgi-bin/whois?query=,
fr => harmonic.nic.fr/cgi-bin/HarmoNIC.pl?Annu_Suffixe=&Annu_Action=Rechercher&Annu_Automaton_State=17&Annu_Motif=,
gl => www.ripe.net/cgi-bin/whois?query=,
gm => www.ripe.net/cgi-bin/whois?query=,
gov=> www.nic.gov/cgi-bin/whois?s=nic.gov,
gr => www.ripe.net/cgi-bin/whois?query=,
hu => www.ripe.net/cgi-bin/whois?query=,
id => whois.idnic.net.id/cgi-bin/whois-cgi?user=,
ie => www.ripe.net/cgi-bin/whois?query=,
il => www.ripe.net/cgi-bin/whois?query=,
is => www.ripe.net/cgi-bin/whois?query=,
it => www.ripe.net/cgi-bin/whois?query=,
jp => www.nic.ad.jp/cgi-bin/whois_gw?lang=/e&type=DOM&rule=ex&key=,
lb => www.aub.edu.lb/cgi-bin/lbdr.pl?cn=,
li => www.switch.ch/cgi-bin/domain/search_domain?keyword=,
lt => www.ripe.net/cgi-bin/whois?query=,
lv => www.ripe.net/cgi-bin/whois?query=,
mc => www.ripe.net/cgi-bin/whois?query=,
构建网站:用递归函数写个论坛
论坛的实现方法较为复杂,只要把它分析一下,问题就迎刃而解了,先看看论坛的实现,有人发贴,然后有人跟贴,这个关系形成了一种父子的关联关系,一般写个实用论坛,只要解决了这个子父关系,论坛即已成形.
来看看完成论坛的方法,首先得用数据库来记载这种子父的关系,一般的方法是用无重复的 id 号来完成的,记载父贴的 id 号字段一般用 "parentid" 来记载,子贴存储时记载父贴的 id 号,而父贴的 parentid 则一率为 0,看看数据库的记载形式:
父1:id:1 | parentid:0
子1:id:2 | parentid:1
子子1:id:3 | parentid:2
父2:id:4 | parentid:0
子2:id:5 | parentid:4
子2:id:6 | parentid:4
......
如此数据库记载的子父关系已确立,接着来分析 php 是如何来实现这种父子关系的确立并加入到数据库的,首先用户想发言时,他的贴为一个父贴,因此 php 可将 parentid 设置为 0,当有用户跟贴时,php 将该用户所跟的父贴的 id 号附值给 parentid,这样 php 就完成了,子父关系的确立.
实现了子父关系的确立和存储,接下来就是把这种关系显示出来,这儿就需要用到递归函数来实现了,看下面的代码:
.....
$result=mysql_query("select * from table where parentid=0");
$num=mysql_numrows($result);
if (!empty($num)) {
for ($i=0;$i<$num;$i++) {
$parentid=mysql_result($result,$i,"id");
function showchild($parentid) {
//加入 ul 控制层进
$result=mysql_query("select * from table where parentid=$parentid");
$numb=mysql_numrows($result);
if (!empty($numb)) {
for ($i=0;$i<$numb;$i++) {
....
$parentid=mysql_result($result,$i,"id");
....
showchild($parentid);
}
....
....
}
....
....
}
showchild($parentid);
....
....
}
....
....
}
上面这段代码就是利用递归函数来实现论坛的方法,当然这个论坛是极其原始的,在不同部分加上功能代码,就能够使这个论坛逐渐强大起来,有兴趣的读者不妨自己动手试试.
基于 PHP 的聊天室(二)
现在我们终于有了写新文件所需的所有东西了:
<?php
// 打开文件,并且将文件长度截为0
$open_file = fopen("messages.html", "w");
// 写入文件的头信息
fputs($open_file, $header);
// 新的一行
// (使用stripSlashes,因为我们不想让所有的转义字符出现在消息文件中)
fputs($open_file, stripslashes($new_message));
// 旧的行
fputs($open_file, $old_messages);
// 脚标
fputs($open_file, $footer);
// 关闭文件
fclose($open_file);
?>
摘自:http://www.9headbird.com/detail.php3?id=8970