【问题标题】:Web page file upload is always corrupted网页文件上传总是损坏
【发布时间】:2017-05-23 22:38:43
【问题描述】:

我正在尝试将文件上传添加到现有网页。

每次我上传我都会得到一个损坏的文件。

我确保在文件句柄上设置了binmode。我还在表单中将输入 enctype 设置为 multipart/formdata

我的代码如下

$article{upload_file_name} = $cgi->param( 'upFile' );
$article{upload_file}      = $cgi->upload( 'upFile' );

if ( $article{upload_file_name} ne "" or $article{upload_file_name} ne null ) {

    open( UPLOADS, ">$uploads_dir/$article{upload_file_name}" )
            or die "Could not open $uploads_dir/$article{upload_file_name}";

    binmode UPLOADS;

    while ( <$article{upload_file}> ) {
        print UPLOADS;
    }

    close UPLOADS;
}

我也试过了

$article{upload_file} = $cgi->param( 'upFile' );

if ( $article{upload_file} ne "" or $article{upload_file} ne null ) {

    open( UPLOADS, ">$uploads_dir/$article{upload_file}" )
            or die "Could not open $uploads_dir/$article{upload_file}";
    binmode UPLOADS;

    while ( <$article{upload_file}> ) {
        print UPLOADS;
    }

    close UPLOADS;
}

【问题讨论】:

  • 一方面,您需要在脚本顶部添加use strict;use warnings 'all';; Perl 中没有null,所以$article{upload_file_name} ne null 检查文件名是否等于文本“null”。
  • 您是否在某处定义了名称为null 的子例程或常量?你的f($article{upload_file_name} ne "" or $article{upload_file_name} ne null) 应该是一个语法错误,除非你没有use strict。 Perl 中没有null。您想要undef,但您无法通过ne 查询undef。事实上,做if ($article{upload_file_name}) { ... } 就足够了,因为只要有一些不是空的或undef 的值就会为真。
  • undefdefined
  • 见我评论的第二部分。您只需要检查 $article{upload_file_name} 是否是 truthy 值。 0undef 和空字符串"" 为假。 Perl 中的其他一切都是正确的。
  • 好的,感谢您提供有关 null 的信息,我没有意识到它不是通用的。然而,这不是错误的原因,因为我有一个损坏的文件,它显然符合我的声明。我确实对 null 进行了更改,并将更新我的 Q。cgi->upload 和 cgi->param 之间有区别吗?

标签: perl file-upload cgi filehandle


【解决方案1】:
<$article{upload_file}>

没有做你认为它正在做的事情。菱形运算符 (&lt;&gt;) 用于代表 Perl 的 readline 函数,但它还有第二个含义,它与 Perl 的 glob 函数做同样的事情。而在 Perl 的解析规则中,&lt;$hash{key}&gt; 总是被视为glob

perldoc -f perlop 解释:

如果尖括号中的内容既不是文件句柄,也不是包含文件句柄名称、typeglob 或 typeglob 引用的简单标量变量,则将其解释为要通配的文件名模式,以及文件名列表或下一个文件名根据上下文返回列表中的。这种区别仅由句法基础决定。这意味着 始终是间接句柄的 readline(),但 始终是 glob()。这是因为 $x 是一个简单的标量变量,但 $hash{key} 不是——它是一个哈希元素。甚至 (注意多余的空格)也被视为 glob("$x"),而不是 readline($x)。

至少有两种解决方法:

  1. 使用明确的readline 调用:

    while (readline($article{upload_file}))
    
  2. 将文件句柄分配给一个简单的标量

    my $upload_fh = $article{upload_file};
    ...
    while (<$upload_fh>)
    

【讨论】:

  • 谢谢,原来如此。当我遇到一个奇怪的错误时,我开始怀疑哈希有什么问题。 my %hash(action =&gt;$cgi-&gt;param('action')); 返回的是“Action”而不是“”。但是,当我像这样设置哈希时...my %hash; $hash{action} = $cgi-&gt;param('action'); 我得到了预期的结果。就在我们讨论这个话题时,这与您指出的全局场景有关吗?
  • @gflynn94:请不要将 Stack Overflow 视为论坛。它是一个更像维基百科的问答概要。仅当您认为它们可能对世界其他地方有用时,您才应该在此处添加文字,并且您应该将提交的内容写成永久的公共文件。
  • @mob:我会选择$article{upload_file}-&gt;readline,因为IO::File 自 Perl v5.14 以来已按需加载。
  • @Borodin 我在问一个关于同一主题的一般性问题。我认为这是可以接受的,因为我不知道全局场景。其次,如果没有人回答这个问题,我认为不会伤害任何人。我将问题标记为已回答。谢谢大家的反馈。
  • @gflynn94:您的声明 my %hash(action =&gt;$cgi-&gt;param('action')); 甚至无法编译。如果您还有其他问题,请照此发布。
猜你喜欢
  • 2020-09-27
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
  • 1970-01-01
  • 2014-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多