CGI的问题

CGI的问题

until (sysopen OUTPUT, UPLOAD_DIR.$filename, O_CREAT|O_EXCL){
    $filename =~ s/(\d*)(\.\w+)$/($1||0) + 1 . $2/e ;
    $1 >= MAX_OPEN_TRIES and error($q, "Unable to save your file.") ;
}


请问这些代码是什么意思啊?
运行时出错:如果$filename = aa的话,错误信息为: Argument "aa" isn't numeric in numeric ge (>=)

代码是不是有问题啊?这是CGI_Programming_with_Perl.chm这本书里面的一段代码,全部代码如下:
#!/usr/bin/perl -wT


use strict ;
use CGI ;
use Fcntl qw(:DEFAULT :flock) ;

use constant UPLOAD_DIR      => "/usr/local/apache2/data/uploads" ;
use constant BUFFER_SIZE     => 10*1048 ;
use constant MAX_FILE_SIZE   => 1048 ;
use constant MAX_DIR_SIZE    => 100*1048 ;
use constant MAX_OPEN_TRIES  => 100 ;

$CGI::DISABLE_UPLOADS = 0 ;
$CGI::POST_MAX        = MAX_FILE_SIZE ;

my $q = new CGI ;
$q->cgi_error and error($q, "Error transferring file:" . $q->cgi_error) ;

my $file         = $q->param("file")      || error($q, "No file received.") ;
my $filename     = $q->param("filename")  || error($q, "No filename entered.") ;
my $fh           = $q->upload($file) ;
my $buffer       = "" ;

print $filename ;

if (dir_size(UPLOAD_DIR) + $ENV{CONTENT_LENGTH} > MAX_DIR_SIZE){
    error ($q, "Upload directory is full.") ;
}

# Allow letters, digits, periods, underscores, dashes

# Convert anything else to an underscore

$filename =~ s/[^\w.-]/_/g ;
if ($filename =~ /^(\w[\w.-]*)/){
    $filename = $1 ;
}else{
    error($q, "Invalid file name; files must start with a letter or number.") ;
}

# Open output file, making sure the name is unique

until (sysopen OUTPUT, UPLOAD_DIR.$filename, O_CREAT|O_EXCL){
    $filename =~ s/(\d*)(\.\w+)$/($1||0) + 1 . $2/e ;
    $1 >= MAX_OPEN_TRIES and error($q, "Unable to save your file.") ;
}

# This is necessary for non-Unix systems; does nothing on Unix

binmode $fh ;
binmode OUTPUT ;

# Write contents to output file

while (read($fh, $buffer, BUFFER_SIZE)){
    print OUTPUT $buffer ;
}

close OUTPUT ;

sub dir_size{
    my $dir = shift ;
    my $dir_size = 0 ;
    
    # Loop through files and sum the sizes; doesn't descend down subdirs

    opendir DIR, $dir or die "Unable to open $dir: $!" ;
    while(readdir DIR){
        $dir_size += -s "$dir/$_" ;
    }
    return $dir_size ;
}

sub error{
    my ($q, $reason) = @_ ;
    
    print $q->header("text/html"),
          $q->start_html("error"),
          $q->h1("Error"),
          $q->p("Your upload was not processed because the following error", "occured: "),
          $q->p($q->i($reason)),
          $q->end_html ;
    
    exit ;
}
这看不懂吗?
错误不是说很清楚了?
aa 和MAX_OPEN_TRIES 怎么比较?
首先perl会将字符串aa转化为数字0, 所以aa >= MAX_OPEN_TRIES 结果为假
这只是一个warning,真正有错的在其他地方
楼主,你还是先系统的学习下 Perl 吧


QUOTE:
原帖由 churchmice 于 2009-1-10 18:02 发表
这看不懂吗?
错误不是说很清楚了?
aa 和MAX_OPEN_TRIES 怎么比较?
首先perl会将字符串aa转化为数字0, 所以aa >= MAX_OPEN_TRIES 结果为假
这只是一个warning,真正有错的在其他地方

真正出问题的地方是

[Copy to clipboard] [ - ]
CODE:
$filename =~ s/(\d*)(\.\w+)$/($1||0) + 1 . $2/e ;

由于 $filename 为 'aa',那么这个 regexp 匹配会失败,此时 $1 为上一个成功匹配的 regexp 中抓取(capture)的值,也即

[Copy to clipboard] [ - ]
CODE:
if ($filename =~ /^(\w[\w.-]*)/){

其值为 'aa'。

把出问题的那句换成

[Copy to clipboard] [ - ]
CODE:
$filename =~ s/(\d*)\.?(\w+)$/($1||0) + 1 . $2/e ;

应该就 OK 了

当然,这样改了以后,若传近来的 filename 不是 digits.ext 这种形式,就会被当作一个单纯的 ext



QUOTE:
原帖由 MMMIX 于 2009-1-10 20:01 发表
楼主,你还是先系统的学习下 Perl 吧

这个也得有环境才行, 我几年前就唠叨说学perl,结果看了几个星期也没看懂什么,后来就放弃了,现在突然项目用到这个,结果一边用一边学,呵呵感觉一周用到的,学到的,比以前N年看到的都多,呵呵。不过还得感谢这里的大虾们的帮助。


QUOTE:
原帖由 huanghaojie 于 2009-1-10 20:14 发表

这个也得有环境才行,

要什么环境?有计算机就行了。

QUOTE:
我几年前就唠叨说学perl,结果看了几个星期也没看懂什么,后来就放弃了,

这个属于你自己的问题,关环境什么事情?


QUOTE:
原帖由 MMMIX 于 2009-1-10 20:01 发表
楼主,你还是先系统的学习下 Perl 吧

我正在学习,我在读CGI_Programming_with_Perl.chm这本书,到这段代码时,发觉不太理解,这才来这里寻求帮助的。

我不太理解until那一段,能否详细解释一下?
这是一个上传文件的程序,应该不是限定文件名为数字。
但这是书中的原始的代码,运行却有问题,不仅仅是有warning,文件实际不能被成功上传,烦请指教。谢谢。


QUOTE:
原帖由 空想家de白日梦 于 2009-1-10 21:37 发表

我正在学习,我在读CGI_Programming_with_Perl.chm这本书,到这段代码时,发觉不太理解,这才来这里寻求帮助的。

我是说,你先系统学习下 Perl,然后再去看 CGI Programming with Perl

QUOTE:
我不太理解until那一段,能否详细解释一下?

直接说你什么地方不理解吧?

其实那里面都是 Perl 的基本语法,除了 s///e  这个稍微不常见以外;而且就算是 s///e 查查文档也很容易就可以弄明白。


QUOTE:
原帖由 huanghaojie 于 2009-1-10 20:14 发表

这个也得有环境才行, 我几年前就唠叨说学perl,结果看了几个星期也没看懂什么,后来就放弃了,现在突然项目用到这个,结果一边用一边学,呵呵感觉一周用到的,学到的,比以前N年看到的都多,呵呵。不过还得感 ...

机会只给有准备的人。
真搞不懂,一搞技术的,预先多储备点儿知识有什么坏处?

平时多学点儿东西,用的时候尽量用自己已经掌握的技能,这样工程质量比较靠谱。
如果你家的房子都是一帮刚刚接触建筑的泥瓦匠修的、一边修一边学、一周学会的比过去 N 年看到的都多,
这样的房子你敢住么?


QUOTE:
原帖由 huanghaojie 于 2009-1-11 00:39 发表


呵呵,会者不难,难者不会,

没错。所以我才建议楼主先系统学习 Perl 的。

QUOTE:
MMMIX  你不能把每个人的perl的水平都看成你那水平,

要是我真这么想的话就不会在这出现了。

QUOTE:
呵呵,你的perl水平很牛了,

这个就是你想当然了。