查看: 4707|回复: 0
打印 上一主题 下一主题

PHP中的批处理(二)

[复制链接]
跳转到指定楼层
1#
发表于 2008-9-5 18:16:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
台州网址导航
这个类包含三个重要的方法:add()、get_all() 和 delete()。与 mailouts 系统一样,前端使用 add(),处理引擎使用 get_all() 和 delete()。

清单 7 所示的测试脚本将一个条目添加到处理队列中。
清单 7. generic_test_add.php
  <?php
require_once 'generic.php';
ProcessingItems::add( 'printvalue', array( 'value' => 'foo' ) );
?>
在这个示例中,添加了一个对 printvalue 函数的调用,并将 value 参数设置为 foo。我使用 PHP 命令行解释器运行这个脚本,并将这个方法调用放进队列中。然后使用以下处理脚本运行这个方法。
清单 8. generic_process.php
<?php
require_once 'generic.php';
function printvalue( $args ) {  
echo 'Printing: '.$args['value']."\n";
}
foreach( ProcessingItems::get_all() as $item ) {  
call_user_func_array( $item['function'],   
array( $item['args'] ) );  
ProcessingItems::delete( $item['id'] );
}
?>

这个脚本非常简单。它获得 get_all() 返回的处理条目,然后使用 call_user_func_array(一个 PHP 内部函数)用给定的参数动态地调用这个方法。在这个示例中,调用本地的 printvalue 函数。

为了演示这种功能,我们看看在命令行上发生了什么:

% php generic_test_add.php % php generic_process.php Printing: foo%

输出并不多,但是您能够看出要点。通过这种机制,可以将任何 PHP 函数的处理推迟。

现在,如果您不喜欢将 PHP 函数名和参数放进数据库中,那么另一种方法是在 PHP 代码中建立数据库中的 “处理作业类型” 名称和实际 PHP 处理函数之间的映射。按照这种方式,如果以后决定修改 PHP 后端,那么只要 “处理作业类型” 字符串匹配,系统就仍然可以工作。

放弃数据库

最后,我演示另一种稍有不同的解决方案,它使用一个目录中的文件来存储批作业,而不是使用数据库。在这里提供这个思路并不是建议您 “采用这种方式,而不使用数据库”,这只是一种可供选择的方式,是否采用它由您决定。

显然,这个解决方案中没有模式,因为我们不使用数据库。所以先编写一个类,它包含与前面示例中相似的 add()、get_all() 和 delete() 方法。
清单 9. batch_by_file.php
<?php
define( 'BATCH_DirectorY', 'batch_items/' );
class BatchFiles{  
public static function delete( $id )  {   
  unlink( $id );   
return true;  
}  
public static function add( $function, $args )  {   
  $path = '';   
  while( true )    {        
   $path = BATCH_DIRECTORY.time();        
   if ( file_exists( $path ) == false )            
   break;   
  }   
  $fh = fopen( $path, "w" );   
  fprintf( $fh, $function."\n" );   
  foreach( $args as $k => $v )    {        
   fprintf( $fh, $k.":".$v."\n" );   
  }   
  fclose( $fh );   
  return true;  
}  
public static function get_all()  {   
  $rows = array();   
  if (is_dir(BATCH_DIRECTORY)) {        
   if ($dh = opendir(BATCH_DIRECTORY)) {            
    while (($file = readdir($dh)) !== false) {               
     $path = BATCH_DIRECTORY.$file;               
     if ( is_dir( $path ) == false ) {                    
      $item = array();                    
      $item['id'] = $path;                    
      $fh = fopen( $path, 'r' );                    
      if ( $fh ) {                        
       $item['function'] = trim(fgets( $fh ));                        
       $item['args'] = array();                        
       while( ( $line = fgets( $fh ) ) != null ) {                           
        $args = split( ':', trim($line) );                           
        $item['args'][$args[0]] = $args[1];                       
       }                       
       $rows []= $item;                        
       fclose( $fh );                  
      }               
     }            
    }            
    closedir($dh);        
   }   
  }   
  return $rows;  
}
}
?>
BatchFiles 类有三个主要方法:add()、get_all() 和 delete()。这个类不访问数据库,而是读写 batch_items 目录中的文件。

使用以下测试代码添加新的批处理条目。
清单 10. batch_by_file_test_add.php
<?php
require_once 'batch_by_file.php';
BatchFiles::add( "printvalue", array( 'value' => 'foo' ) );
?>

有一点需要注意:除了类名(BatchFiles)之外,实际上没有任何迹象能够说明作业是如何存储的。所以,以后很容易将它改为数据库风格的存储方式,而不需要修改接口。

最后是处理程序的代码。
清单 11. batch_by_file_processor.php
<?php
require_once 'batch_by_file.php';
function printvalue( $args ) {  
echo 'Printing: '.$args['value']."\n";
}
foreach( BatchFiles::get_all() as $item ) {  
call_user_func_array( $item['function'], array( $item['args'] ) );  
BatchFiles::delete( $item['id'] )
;
}
?>   

这段代码几乎与数据库版本完全相同,只是修改了文件名和类名。

结束语

正如前面提到的,服务器对线程提供了许多支持,可以进行后台批处理。在某些情况下,使用辅助线程处理小作业肯定比较容易。但是,也可以使用传统工具(cron、MySQL、标准的面向对象的 PHP 和 Pear::DB)在 PHP 应用程序中创建批作业,这很容易实现、部署和维护。
参考资料

学习

您可以参阅本文在 developerWorks 全球站点上的 英文原文 。
阅读 IBM developerWorks 的 PHP 项目资源中心,进一步了解 PHP。
PHP.net 是面向 PHP 开发人员的优秀资源。
PEAR Mail_Queue 包 是一个健壮的邮件队列实现,其中包括数据库后端。
crontab 手册 提供了 cron 配置的细节,但是不容易理解。
PHP 手册中关于 Using PHP from the command line 的一节可以帮助您了解如何从 cron 运行脚本。
随时关注 developerWorks 技术事件和 webcast。
了解世界各地即将进行的会议、展览、网络广播和其他 活动,IBM 开放源码开发人员可以通过这些活动了解最新的技术发展。
访问 developerWorks 开源技术专区,获得广泛的 how-to 信息、工具和项目更新,可以帮助您利用开放源码技术进行开发并将其与 IBM 产品结合使用。
developerWorks podcasts 中包括很多适合于软件开发人员的有趣的访谈和讨论。

获得产品和技术

查阅 PEAR -- PHP Extension and Application Repository,其中包含 Pear::DB。
使用 IBM 试用软件 改进您的下一个开放源码开发项目,这些软件可以下载或者通过 DVD 获得。

讨论

developerWorks PHP Developer Forum 为所有 PHP 开发人员提供了讨论技术问题的场所。如果您有关于 PHP 脚本、函数、语法、变量、调试和其他主题的问题,可以在这里提出。

通过参与 developerWorks blog 加入 developerWorks 社区。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖
台州维博网络(www.tzweb.com)专门运用PHP+MYSQL/ASP.NET+MSSQL技术开发网站门户平台系统等。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

网站推广
关于我们
  • 台州朗动科技(Tzweb.com)拥有多年开发网站平台系统门户手机客户端等业务的成功经验。主要从事:政企网站,系统平台,微信公众号,各类小程序,手机APP客户端,浙里办微应用,浙政钉微应用、主机域名、虚拟空间、后期维护等服务,满足不同企业公司的需求,是台州地区领先的网络技术服务商!

Hi,扫描关注我

Copyright © 2005-2026 站长论坛 All rights reserved

Powered by 站长论坛 with TZWEB Update Techonolgy Support

快速回复 返回顶部 返回列表