用PHP构建一个简易监视引擎(三)

 更新时间:2016年11月25日 16:13  点击:1674

五. 示例ServiceLogger进程

  下面是一个示例ServiceLogger进程。当一个服务停用时,它负责把一个电子邮件发送给一个待命人员:

class EmailMe_ServiceLogger implements ServiceLogger {
 public function log_service_event(ServiceCheck$service)
 {
  if($service->current_status ==ServiceCheck::FAILURE) {
   $message = "Problem with{$service->description()}rn";
   mail('oncall@example.com', 'Service Event',$message);
   if($service->consecutive_failures() > 5) {
    mail('oncall_backup@example.com', 'Service Event', $message);
   }
  }
 }
 public function log_current_status(ServiceCheck$service){
  return;
 }
}

  假如连续失败五次,那么该进程还把一个消息发送到一个备份地址。注重,它并没有实现一个有意义的log_current_status()方法。

  无论何时象如下这样改变一个服务的状态,你都应该实现一个写向PHP错误日志的ServiceLogger进程:

class ErrorLog_ServiceLogger implements ServiceLogger {
 public function log_service_event(ServiceCheck$service)
 {
  if($service->current_status() !==$service->previous_status()) {
   if($service->current_status() ===ServiceCheck::FAILURE) {
    $status = 'DOWN';
   }
   else {
    $status = 'UP';
   }
   error_log("{$service->description()} changed status to $status");
  }
 }
 public function log_current_status(ServiceCheck$service)
 {
  error_log("{$service->description()}: $status");
 }
}

  该log_current_status()方法意味着,假如进程发送一个SIGUSR1信号,它将把其完整的当前状态复制到你的PHP错误日志中。
  
  该引擎使用如下的一个配置文件:

<config>
 <loggers>
  <logger>
   <id>errorlog</id>
   <class>ErrorLog_ServiceLogger</class>
  </logger>
  <logger>
   <id>emailme</id>
   <class>EmailMe_ServiceLogger</class>
  </logger>
 </loggers>
 <services>
  <service>
   <class>HTTP_ServiceCheck</class>
   <params>
    <description>OmniTI HTTP Check</description>
    <url>http://www.omniti.com</url>
    <timeout>30</timeout>
    <frequency>900</frequency>
   </params>
   <loggers>
    <logger>errorlog</logger>
    <logger>emailme</logger>

分页显示详解


1、前言

分页显示是一种非经常见的浏览和显示大量数据的方法,属于web编程中最常处理的事件之一。对于web编程的老手来说,编写这种代码实在是和呼吸一样自然,但是对于初学者来说,经常对这个问题摸不着头绪,因此特地撰写此文对这个问题进行具体的讲解,力求让看完这篇文章的朋友在看完以后对于分页显示的原理和实现方法有所了解。本文适合初学者阅读,所有示例代码均使用php编写。

2、原理

所谓分页显示,也就是将数据库中的结果集人为的分成一段一段的来显示,这里需要两个初始的参数:

每页多少条记录($PageSize)?
当前是第几页($CurrentPageID)?

现在只要再给我一个结果集,我就可以显示某段特定的结果出来。
至于其他的参数,比如:上一页($PreviousPageID)、下一页($NextPageID)、总页数($numPages)等等,都可以根据前边这几个东西得到。
以mysql数据库为例,假如要从表内截取某段内容,sql语句可以用:select * from table limit offset, rows。看看下面一组sql语句,尝试一下发现其中的规率。

前10条记录:select * from table limit 0,10
第11至20条记录:select * from table limit 10,10
第21至30条记录:select * from table limit 20,10
……

这一组sql语句其实就是当$PageSize=10的时候取表内每一页数据的sql语句,我们可以总结出这样一个模板:

select * from table limit ($CurrentPageID - 1) * $PageSize, $PageSize

拿这个模板代入对应的值和上边那一组sql语句对照一下看看是不是那么回事。搞定了最重要的如何获取数据的问题以后,剩下的就仅仅是传递参数,构造合适的sql语句然后使用php从数据库内获取数据并显示了。以下我将用具体代码加以说明。

3、简单代码
请具体阅读以下代码,自己调试运行一次,最好把它修改一次,加上自己的功能,比如搜索等等。

<?php
// 建立数据库连接
$link = mysql_connect("localhost", "mysql_user", "mysql_password")
or die("Could not connect: " . mysql_error());
// 获取当前页数
if( isset($_GET['page']) ){
$page = intval( $_GET['page'] );
}
else{
$page = 1;
}
// 每页数量
$PageSize = 10;
// 获取总数据量
$sql = "select count(*) as amount from table";
$result = mysql_query($sql);
$row = mysql_fetch_row($result);
$amount = $row['amount'];
// 记算总共有多少页
if( $amount ){
if( $amount < $page_size ){ $page_count = 1; } //假如总数据量小于$PageSize,那么只有一页
if( $amount % $page_size ){ //取总数据量除以每页数的余数
$page_count = (int)($amount / $page_size) 1; //假如有余数,则页数等于总数据量除以每页数的结果取整再加一
}else{
$page_count = $amount / $page_size; //假如没有余数,则页数等于总数据量除以每页数的结果
}

在开发PHP应用中假如不想自己开发新的加密算法,还可以利用PHP提供的crypt()函数来完成单向加密功能。

  了解crypt()

  只要有一点使用非Windows平台经验的读者都可能对crypt()相当熟悉,这一函数完成被称作单向加密的功能,它可以加密一些明码,但不能反过来将密码重新转换为原来的明码。crypt()函数定义如下。

  string crypt (string input_string [, string salt])

  其中,input_string参数是需要加密的明文字符串,第二个可选的salt是一个位字串,能够影响加密的暗码,进一步排除被破解的可能性。缺省情况下,PHP使用一个2个字符的DES干扰串,假如系统使用的是MD5(参考下一节内容),PHP则会使用一个12个字符的干扰串。可以通过执行下面的命令发现系统将要使用的干扰串的长度。

  print "My system salt size is: ". CRYPT_SALT_LENGTH;

  crypt()支持4种加密算法,表19.1显示了其支持的算法和相应的salt参数的长度。

  表crypt()支持四种加密算法

算法 Salt长度
CRYPT_STD_DES 2-character (Default)
CRYPT_EXT_DES 9-character
CRYPT_MD5 12-character beginning with $1$
CRYPT_BLOWFISH 16-character beginning with $2$

  从表面上看,crypt()的函数似乎没有什么用处,但该函数的确被广泛用来保证系统密码的完整性。因为,单向加密的口令即使落入第三方的手里,由于不能被还原为明文,也没有什么大用处。

  用crypt()实现用户身份验证

  上一部分简单介绍了crypt()函数的功能,下面利用其来实现用户的身份验证,其所要实现的目标同19.2.3节所介绍的一致。

1 <!--check_user_crypt.php:使用crypt() 函数验证用户---------------->
2 <?php
3 $user_name=$_POST["user_name"];
4 require_once("sys_conf.inc"); //系统配置文件,包含数据库配置信息
5
6 //连接数据库
7 $link_id=mysql_connect($DBHOST,$DBUSER,$DBPWD);
8 mysql_select_db($DBNAME); //选择数据库my_chat
9
10 //查询是否存在登录用户信息
11 $str="select name,password from user where name ='$user_name'";
12 $result=mysql_query($str,$link_id); //执行查询
13 @$rows=mysql_num_rows($result); //取得查询结果的记录笔数
14 $user_name=$_SESSION["user_name"];
15 $password=$_POST["password"];

导航的实现

  虽然表格列出了目录中的一些图像,但用户还需要一种查看表格中未出现的图片的方法。要真正实现分页器的导行,则需要一套标准的链接:首页、上一页、下一页和尾页。

  清单 3. 分页器导航

// Append navigation
$output = '<h4>Showing items ' . $limit_start . '-' .
min($limit_start $limit_step - 1, count($images)) .
' of ' . count($images) . '<br />';

$prev_start = max(0, $limit_start - $limit_step);
if ( $limit_start > 0 ) {
 $output .= get_table_link('<<', 0, $limit_step);
 $output .= ' | ' . get_table_link('Prev',
 $prev_start, $limit_step);
} else {
 $output .= '<< | Prev';
}

// Append next button
$next_start = min($limit_start $limit_step, count($images));
if ( $limit_start $limit_step < count($images) ) {
 $output .= ' | ' . get_table_link('Next',$next_start, $limit_step);
 $output .= ' | ' . get_table_link('>>',(count($images) - $limit_step), $limit_step);
} else {
 $output .= ' | Next | >>';
}

$output .= '</h4>';

  最后还要编写 get_image_link() 和 get_table_link() 函数,让用户将缩略图展开成完整的图像(参见清单 4)。注重,脚本 index.php(以及后面要创建的 expand.php)只在这两个函数中调用。这样就很轻易改变链接的功能。事实上在下面与 Sajax 进行集成时,只有这两个函数需要修改。

  清单 4. get_image_link、get_table_link 实现

function get_table_link ( $title, $start, $step ) {
 $link = "index.php?start=$start&step=$step";
 return '<a href="' . $link . '">' . $title .'</a>';
}

function get_image_link ( $title, $index ) {
 $link = "expand.php?index=$index";
 return '<a href="' . $link . '">' . $title . '</a>';
}

  放大图片

  现在有了一个可用的分页器为用户提供一些缩略图。相册的第二项功能是答应用户单击缩略图来查看全图。get_image_link() 函数调用了 expand.php 脚本,我们现在就来编写它。该脚本传递用户希望展开的文件的索引,因此必须在此列出目录并获得适当的文件名。随后的操作就很简单了,只需创建病输出 image 标记即可。

  清单 5. get_image 函数

function get_image ( $index ) {
 $images = get_image_list ( 'images' );

 // Generate navigation

 $output .= '<img src="images/' . $images[$index] . '" />';
 return $output;
}

想象使用一个简单HTML文件来把一个请求发送到一个服务器端脚本,收到一个基于该请求的定制XML文件,然后把它显示给用户而几乎不需要刷新浏览器!本文作者将同你一起探讨怎样在普通Web应用程序中联合PHP和AJAX技术来创建实时的数据传输而不需要进行浏览器刷新。

  尽管本文所使用的是PHP语言,但是请记住任何服务器端语言都会正常工作。为了理解本文,我假定你基本理解JavaScript和PHP或一类似服务器端语言。

  本文示例使用AJAX来把一请求从一个RSS馈送发送到一定制的PHP对象。该PHP对象复制一份在本地服务器上的该馈送并返回这一路径。该请求对象收到这一路径,分析它,并且把数据以HTML形式显示给用户。这听起来涉及很多步骤,其实它仅由4个小文件组成。之所以使用了4个小文件,是为了平衡它们各自特定的力量而使整个系统的处理极富效率性。

  我想,有些读者可能会问,为什么你要创建在本地服务器上的馈送的一个副本而不是简单分析最原始的馈送。原因是,这样以来可以答应绕过XML HTTP Request对象所强加的跨域限制。后面,我还会解释怎样创建这个定制的PHP对象;但是首先,让我们从表单创建开始。

  创建发出请求的表单
 
  你要做的第一事情是,在你的HTML的head标签之间包括你可能想使用的JavaScript和任何CSS文件。我包括了一个式样表来实现该聚合器的最后布局并用一个JavaScript文件来发出请求和进行馈送分析:

<link href="css/layout.css" rel="stylesheet" type="text/css" />
<script src="js/request.js"></script>

  下一步,创建一个表单,它针对你所选择的一个RSS馈送发出请求。我创建的表单只包括一个输入字段和一个提交该请求的按钮。该请求的查询是一个字符串,它由馈送输入值和一个将在服务器端被校验的口令字组成;作为一个示例,我使用了下面形式:

"password=mypassword

  该代码在每次页面加载之时发出一次请求;因此,假如页面被刷新,现有的在该输入域中的馈送串将在页面加载时被请求。下面是一个表单数据的示例,连同一些div标签用来显示已分析的馈送的特定结点:

<body onload="javascript:makeRequest('request.php?request=' document.feedForm.feed.value '"password=mypassword');">
<form name="feedForm" method="post" action="javascript:makeRequest('request.php?request=' document.feedForm.feed.value '"password=mypassword');">
Enter a feed: <input type="text" name="feed" id="feed" size="20">
<input type="submit" name="submit" value="Add Feed">
</form>
<div id="logo"></div>
<hr/>
<div id="copy"></div>
<div id="details"></div>
</body>


  我所创建的这三个div标签是logo,copy和details,其中每一个都在布局样式表中有一个与之相关联的样式。当我们分析馈送时将会用到它们,但是我们首先需要能够存取我们所请求的馈送。这可以使用我前面所提到的PHP对象来完成。

[!--infotagslink--]

相关文章

  • 源码分析系列之json_encode()如何转化一个对象

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

    PHP去除html、css样式、js格式的方法很多,但发现,它们基本都有一个弊端:空格往往清除不了 经过不断的研究,最终找到了一个理想的去除html包括空格css样式、js 的PHP函数。...2013-08-02
  • index.php怎么打开?如何打开index.php?

    index.php怎么打开?初学者可能不知道如何打开index.php,不会的同学可以参考一下本篇教程 打开编辑:右键->打开方式->经文本方式打开打开运行:首先你要有个支持运行PH...2017-07-06
  • PHP中func_get_args(),func_get_arg(),func_num_args()的区别

    复制代码 代码如下:<?php function jb51(){ print_r(func_get_args()); echo "<br>"; echo func_get_arg(1); echo "<br>"; echo func_num_args(); } jb51("www","j...2013-10-04
  • JavaScript模版引擎的基本实现方法浅析

    这篇文章主要介绍了JavaScript模版引擎的基本实现方法,讲解利用function对象来一步步编写简单的模板,需要的朋友可以参考下...2016-02-18
  • PHP编程 SSO详细介绍及简单实例

    这篇文章主要介绍了PHP编程 SSO详细介绍及简单实例的相关资料,这里介绍了三种模式跨子域单点登陆、完全跨单点域登陆、站群共享身份认证,需要的朋友可以参考下...2017-01-25
  • PHP实现创建以太坊钱包转账等功能

    这篇文章主要介绍了PHP实现创建以太坊钱包转账等功能,对以太坊感兴趣的同学,可以参考下...2021-04-20
  • php微信公众账号开发之五个坑(二)

    这篇文章主要为大家详细介绍了php微信公众账号开发之五个坑,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2016-10-02
  • ThinkPHP使用心得分享-ThinkPHP + Ajax 实现2级联动下拉菜单

    首先是数据库的设计。分类表叫cate.我做的是分类数据的二级联动,数据需要的字段有:id,name(中文名),pid(父id). 父id的设置: 若数据没有上一级,则父id为0,若有上级,则父id为上一级的id。数据库有内容后,就可以开始写代码,进...2014-05-31
  • PHP如何通过date() 函数格式化显示时间

    这篇文章主要介绍了PHP如何通过date() 函数格式化显示时间,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-11-13
  • 模板引擎smarty工作原理以及使用示例

    模板引擎是用于把模板文件和数据内容合并在一起的程序,便于网站开发有利于代码分离和维护,了解一个模板最好知道其工作原理,以便于实现一通万通。模板文件一般是HTML xml js等类型文件,如果不用模板引擎若要把数据显示在...2014-05-31
  • PHP+jQuery+Ajax实现多图片上传效果

    今天我给大家分享的是在不刷新页面的前提下,使用PHP+jQuery+Ajax实现多图片上传的效果。用户只需要点击选择要上传的图片,然后图片自动上传到服务器上并展示在页面上。...2015-03-15
  • golang与php实现计算两个经纬度之间距离的方法

    这篇文章主要介绍了golang与php实现计算两个经纬度之间距离的方法,结合实例形式对比分析了Go语言与php进行经纬度计算的相关数学运算技巧,需要的朋友可以参考下...2016-07-29
  • PHP如何使用cURL实现Get和Post请求

    这篇文章主要介绍了PHP如何使用cURL实现Get和Post请求,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-07-11
  • 谈谈PHP中相对路径的问题与绝对路径的使用

    经常看到有人踩在了PHP路径的坑上面了,感觉有必要来说说PHP中相对路径的一些坑,以及PHP中绝对路径的使用,下面一起来看看。 ...2016-08-24
  • thinkPHP中多维数组的遍历方法

    这篇文章主要介绍了thinkPHP中多维数组的遍历方法,以简单实例形式分析了thinkPHP中foreach语句的使用技巧,需要的朋友可以参考下...2016-01-12
  • PHP正则表达式过滤html标签属性(DEMO)

    这篇文章主要介绍了PHP正则表达式过滤html标签属性的相关内容,实用性非常,感兴趣的朋友参考下吧...2016-05-06
  • php构造方法中析构方法在继承中的表现

    这篇文章主要为大家详细介绍了php构造方法中析构方法在继承中的表现,感兴趣的小伙伴们可以参考一下...2016-04-15
  • jQuery+PHP+MySQL实现无限级联下拉框效果

    这篇文章主要介绍了jQuery+PHP+MySQL实现无限级联效果的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2016-02-21
  • php图片添加文字水印实现代码

    这篇文章主要为大家详细介绍了php图片添加文字水印实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2016-03-17