在perl中重新加载页面时如何显示文本文件中的随机数据?

How to display random data from text file when reload page in perl?

我有一个名为“poduct_data.txt”的文本数据文件

id  |  name  | top
------------------
id01--  name01--    top

id02--  name02--    
id03--  name03--    
id04--  name04--    top

id05--  name05--    top

id06--  name06--    
id07--  name07--    top

id08--  name08--    
id09--  name09--    
id10--  name10--    top

这里有 3 列,分别是 id、name 和 top。 “我的任务是:

  1. 从这个文本文件中找到最上面的列数据并且
  2. 重新加载页面时按前三位数据随机显示。" 像:name01 name04 name 05

如果重新加载页面则随机显示另外3个数据 可能是:name07 name05 name10

每次重新加载页面显示与顶部数据不同的 3 个数据

1 完成并显示如下:name01 name10 name04 name07 name 05

但在 2 中遇到问题。

我的工作文件在下面:

库文件:ProductLib.pm

    package ProductLib;
    use strict;
    use File::Basename;
    use FileHandle;
    use Encode;
    use CGI;
    use POSIX;
    use Date::Parse;
    
    sub new {
        my $class   = shift;
        my ($ProgramName, $ProgramPath, undef)  = fileparse([=11=]);
        my $self    = {
                    'program_name'      => $ProgramName,        
                    'program_path'      => $ProgramPath,        
                    'data_dir'          => 'data',
                    'product_data_file' => 'product_data.txt',
                    'template_dir'      => 'templates',
                    'template'          => {},
                    'cgi'               => new CGI(),
                    @_,
                };
    
        $Data::Dumper::Sortkeys = 1;
        $Data::Dumper::Indent = 1;
        $Data::Dumper::Terse = 1;
    
        return bless $self, $class;
    }
    sub SearchRandomProduct{
        my $self        = shift;
        my $TargetTop       = shift;
        my $ProductHash = $self->GetProductData();
    
        my $TargetProduct   = {};
        foreach my $ProductId (sort {$a cmp $b} (keys %{$ProductHash})){
    
            my $ProductData     = $ProductHash->{$ProductId};
            my $ProductTop      = $ProductData->{'top'};
    
            next if(defined $TargetTop && $ProductTop ne $TargetTop);
    
            $TargetProduct->{$ProductId}    = $ProductData;
        }
        return $TargetProduct;
    }
    sub GetProductData{
        my $self        = shift;
        my $FilePath    = sprintf('%s/%s',
                                $self->{'data_dir'},
                                $self->{'product_data_file'}
                            );
        my $FileData    = ${$self->GetFileData($FilePath)};
    
        my $ProductHash = {};
        my @LineData    = split("\n", $FileData);
    
        foreach my $LineData (@LineData){
            next if($LineData eq '' || $LineData =~ /^#/);
    
            my @DataArray       = split("\t", $LineData, 3);
            my $ProductId       = $DataArray[0];
            my $ProductName     = $DataArray[1];
            my $ProductTop      = $DataArray[2];
    
            $ProductHash->{$ProductId}  = {
                    'id'        => $ProductId,
                    'name'      => $ProductName,
                    'top'       => $ProductTop,
                };
        }
        return $ProductHash;
    }
    sub SetTemplateParameter{
        my $self    = shift;
        my $TemplateData    = shift; 
        my $ProductData     = shift;
        $TemplateData   = ${$TemplateData} if(ref($TemplateData) eq 'SCALAR');
        $TemplateData =~ s/$\{(.*?)\}/$ProductData->{}/ges;
        return $TemplateData;
    }
sub GetFileData{

    my $self        = shift;

    my $FilePath    = shift;

    my $FileData    = '';
    if(-e "${FilePath}"){

        my $FileHandle  = new FileHandle;
        sysopen($FileHandle, "${FilePath}", O_RDONLY);
            $FileData = join'',<$FileHandle>;
        close($FileHandle);
    }
    return $FileData;
}
    1;

cgi 文件:product_random_list.cgi

#!/usr/bin/perl

use FindBin;
use lib "$FindBin::Bin/lib";
use strict;
use CGI;
use ProductLib;
use Data::Dumper;

 my $ProductFormat  = ' <a class="card">
                            <div class="card-body">
                                    <strong>${name}</strong>
                            </div>
                        </a>';
my $q           = new CGI;
my $ProductLib  = new ProductLib();

my $TargetMode      = $q->param('mode') || 'init';
my $TargetTop       = $q->param('top');

my $ProductList = {};

if($TargetMode eq 'init'){
    $ProductList    = $ProductLib->SearchRandomProduct($TargetTop);
}

my $ProductHtml = '';
foreach my $ProductId ( 
    sort {
        $ProductList->{$a}->{'id'} cmp $ProductList->{$b}->{'id'}
    }
(keys %{$ProductList})){
    my $ProductData = $ProductList->{$ProductId};
    $ProductHtml    .= ${$ProductLib->SetTemplateParameter($ProductFormat, $ProductData)};
}

print "Content-Type: text/plain; charset=utf8\n\n";
print $ProductHtml;
exit;

索引文件:index.html

<!DOCTYPE html>
<html>
<body>

<section>
    <div class="container-fluid">
        <div class="card-deck sMb">
                <!--#include virtual="/ssi/product_random_list.cgi?top=top" -->
        </div>
    </div>
</section>

</body>
</html>

请帮我在上面的索引页面重新加载页面时按三个顶部数据随机显示它们...

display them randomly by three top data when reload page.

您可以 select 产品列表中的三个随机项目,例如使用 List::Util::shuffle()。示例:

use strict;
use warnings;
use List::Util qw(shuffle);
my $ProductList = {
    id01 => {id => 'id01', name => 'name01', top => 'top'},
    id10 => {id => 'id10', name => 'name10', top => 'top'},
    id04 => {id => 'id04', name => 'name04', top => 'top'},
    id07 => {id => 'id07', name => 'name07', top => 'top'},
    id05 => {id => 'id05', name => 'name05', top => 'top'},
};
my @ids = keys %$ProductList;
my @idx = shuffle 0..$#ids;
my @randidx = @ids[@idx[0..2]];

Every time reload page show different 3 data from top data

为了识别页面是否重新加载,您可以使用会话变量。有关详细信息,请参阅 CGI::Session