PHP 中的批处理的实现

2019-04-11 01:14:56刘景俊



这个类包含三个重要的方法:add()、get_all() 和 delete()。与 mailouts 系统一样,前端使用 add(),处理引擎使用 get_all() 和 delete()。

清单 7 所示的测试脚本将一个条目添加到处理队列中。

清单 7. generic_test_add.php
    <?phprequire_once 'generic.php';ProcessingItems::add( 'printvalue', array( 'value' => 'foo' ) );?>


在这个示例中,添加了一个对 printvalue 函数的调用,并将 value 参数设置为 foo。我使用 PHP 命令行解释器运行这个脚本,并将这个方法调用放进队列中。然后使用以下处理脚本运行这个方法。

清单 8. generic_process.php
    <?phprequire_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
    <?phpdefine( '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;  }}?>
相关文章 大家在看