CGI.pm:子程序之间丢失的全局哈希中的文件句柄?

时间:2013-08-03 05:05:25

标签: perl upload cgi

我想将文件句柄存储到全局哈希并在子例程中读取()它而不显示CGI对象,但我发现它不起作用(导致零大小的输出文件)。

以下是简化的perl代码:

#!/usr/local/bin/perl

use CGI;
use vars qw(%in);

&init_hash;
$fname = &process_uploaded_file if($in{'upfile'});
$fsize = -s $fname;

print "Content-Type: text/plain\r\n\r\n";
print "in{'upfile'}=",$in{'upfile'},"\r\n";
print "in{'desc'}=",$in{'desc'},"\r\n";
print "fname=",$fname,"\r\n";
print "fsize=",$fsize,"\r\n";

sub init_hash{
    my $q = new CGI;
    $in{'desc'} = $q->param('desc');
    $in{'upfile'} = $q->param('upfile');
    $in{'upfh'} = $q->upload('upfile') if($in{'upfile'});
}

sub process_uploaded_file{
    my $fname = time.'.bin';
    open(OUT,'>',$fname) || die('open file failed');
    while(my $read = read($in{'upfh'}, my $buff, 4096)){
        print OUT $buff;
    }
    close(OUT);
    eval { close($in{'upfh'}); };
    return $fname;
}

编辑:我应该提供perl和cgi.pm版本。 Perl版本:这是为MSWin32-x86-multi-thread构建的perl 5,版本12,subversion 2(v5.12.2) (有8个已注册的补丁,有关详细信息,请参阅perl -V) $ CGI :: VERSION = '3.50';

1 个答案:

答案 0 :(得分:2)

您的代码存在很多错误。

首先是您的问题:您正在尝试优化未达到优化的位置。并且在您实际访问它们之前删除CGI对象的临时文件。当您延长CGI对象的生命周期时,您的代码应该可以工作,例如将其添加到%in哈希。


  • 始终use strict; use warnings;。没有任何借口。
  • 使用our声明全局变量。 vars编译指示是一个历史工件。但请不要使用全局变量,因为它们在这里是不必要的。
  • 除非您能告诉我完全这样做,否则不要调用&foo之类的函数。在你掌握这些知识之前:foo()
  • 使用CGI对象的header方法编写标题:$q->header('text/plain')
  • \n可能不是您认为的那样。如果当前已应用binmode STDOUT PerlIO层,请执行:crlf。虽然相当于\r\n,但可以更清楚地写\015\012来证明您关心实际字节。
  • 你知道,你可以将变量插入到字符串中。您还可以通过设置print来指定要在每个$\之后追加的字符串:

    {
      local $\ = "\015\012";
      print "in{'upfile'}=$in{'upfile'}";
      print "in{'desc'}=$in{'desc'}";
      print "fname=$fname";
      print "fsize=$fsize";
    }
    
  • 不要使用bareword文件句柄。您应open OUT, "<", $fname
  • 而不是open my $outfh, "<", $fname
  • 你为什么在close中放置一个eval?我不明白这应该是die