2010-05-01 89 views
2

用户使用表单输入产品代码,价格和名称。然后脚本将其添加到数据库或从数据库中删除它。如果用户试图删除不在数据库中的产品,则会收到错误消息。成功添加或删除后,他们也会收到一条消息。但是,当我测试它时,我只是得到一个空白页面。 Perl不会提出任何警告,语法错误或任何东西;说一切都很好,但我仍然只是空白页。为什么我从我的Perl CGI脚本中得到一个空白页面?

脚本:

#!/usr/bin/perl 
#c09ex5.cgi - saves data to and removes data from a database 
print "Content-type: text/html\n\n"; 
use CGI qw(:standard); 
use SDBM_File; 
use Fcntl; 
use strict; 

#declare variables 
my ($code, $name, $price, $button, $codes, $names, $prices); 


#assign values to variables 
$code = param('Code'); 
$name = param('Name'); 
$price = param('Price'); 
$button = param('Button'); 

($code, $name, $price) = format_input(); 
($codes, $names, $prices) = ($code, $name, $price); 

if ($button eq "Save") { 
     add(); 
} 
elsif ($button eq "Delete") { 
     remove(); 
} 
exit; 


sub format_input { 
     $codes =~ s/^ +//; 
     $codes =~ s/ +$//; 
     $codes =~ tr/a-z/A-Z/; 
     $codes =~ tr/ //d; 
     $names =~ s/^ +//; 
     $names =~ s/ +$//; 
     $names =~ tr/ //d; 
     $names = uc($names); 
     $prices =~ s/^ +//; 
     $prices =~ s/ +$//;  
     $prices =~ tr/ //d; 
     $prices =~ tr/$//d; 
    } 


sub add { 
    #declare variable 
    my %candles; 

#open database, format and add record, close database 
    tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666) 
      or die "Error opening candlelist. $!, stopped"; 

    format_vars(); 
    $candles{$codes} = "$names,$prices"; 
    untie(%candles); 

#create web page  
     print "<HTML>\n"; 
     print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n"; 
     print "<BODY>\n"; 
     print "<FONT SIZE=4>Thank you, the following product has been added.<BR>\n"; 
     print "Candle: $codes $names $prices</FONT>\n"; 
     print "</BODY></HTML>\n"; 
     } #end add 


sub remove { 
    #declare variables 
    my (%candles, $msg); 

tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0) 
      or die "Error opening candlelist. $!, stopped"; 

    format_vars(); 

    #determine if the product is listed 
    if (exists($candles{$codes})) { 
      delete($candles{$codes}); 
      $msg = "The candle $codes $names $prices has been removed."; 
     } 
    else { 
    $msg = "The product you entered is not in the database"; 
    } 
    #close database 
    untie(%candles); 

#create web page 
print "<HTML>\n"; 
print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n"; 
print "<BODY>\n"; 
print "<H1>Candles Unlimited</H1>\n"; 
print "$msg\n"; 
print "</BODY></HTML>\n"; 
} 
+1

http://perldoc.perl.org/perldebtut! .html – Ether 2010-05-01 22:55:46

回答

1

在命令行中与运行它:

perl something.cgi Button=Save 

...给我一个错误:

Undefined subroutine &main::format_vars called at something.pl line 55. 

如果我改变的两个引用format_vars()到“format_input()”,我得到我认为是正确的输出。

+0

修正了这个问题,但我仍然只是得到一个空白页。 – Jason 2010-05-01 21:47:21

+0

尝试添加一个打印“$ button \ n”;得到参数后,第19行左右。确保你得到你期望的输入。请记住,eq检查区分大小写,所以如果按钮=“保存”,它将不起作用。在输出上做一个查看源,它有多远?你可以通过命令行运行它吗? – SqlACID 2010-05-01 22:33:44

+0

如果我添加打印按钮行,它会出现保存,因为它应该。除此之外,尽管它仍然只是一个空白页面,页面源代码甚至不显示任何内容,只是空白,根本没有代码。 – Jason 2010-05-01 23:03:46

1

您不打印除Content-Type标题外的任何输出,除非调用addremove。问题在于,如果没有按钮被点击,你忘记了显示一个表单(大概是包含按钮的表单)。

编辑:复制您的发布代码,并做了一些清理,然后调用它的URL http://localhost/~me/foo.cgi?Code=1;Name=2;Price=3;Button=Savehttp://localhost/~me/foo.cgi?Code=1;Name=2;Price=3;Button=Delete,我得到正确的HTML输出。用于此代码的清理版本:

#!/usr/bin/perl 

use strict; 
use warnings; 

print "Content-type: text/html\n\n"; 
use CGI qw(:standard); 
use SDBM_File; 
use Fcntl; 
use strict; 

#declare variables 
my ($code, $name, $price, $button, $codes, $names, $prices); 


#assign values to variables 
$code = param('Code'); 
$name = param('Name'); 
$price = param('Price'); 
$button = param('Button'); 

($code, $name, $price) = format_input(); 
($codes, $names, $prices) = ($code, $name, $price); 

if ($button eq "Save") { 
    add(); 
} 
elsif ($button eq "Delete") { 
    remove(); 
} 
exit; 


sub format_input { 
    $codes =~ s/^ +//; 
    $codes =~ s/ +$//; 
    $codes =~ tr/a-z/A-Z/; 
    $codes =~ tr/ //d; 
    $names =~ s/^ +//; 
    $names =~ s/ +$//; 
    $names =~ tr/ //d; 
    $names = uc($names); 
    $prices =~ s/^ +//; 
    $prices =~ s/ +$//; 
    $prices =~ tr/ //d; 
    $prices =~ tr/$//d; 
    } 

sub add { 
# #declare variable 
# my %candles; 
# 
# #open database, format and add record, close database 
#  tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666) 
#   or die "Error opening candlelist. $!, stopped"; 
# 
#  format_vars(); 
#  $candles{$codes} = "$names,$prices"; 
#  untie(%candles); 

#create web page  
print "<HTML>\n"; 
print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n"; 
print "<BODY>\n"; 
print "<FONT SIZE=4>Thank you, the following product has been added.<BR>\n"; 
print "Candle: $codes $names $prices</FONT>\n"; 
print "</BODY></HTML>\n"; 
} #end add 


sub remove { 
# #declare variables 
# my (%candles, $msg); 
# 
# tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0) 
#   or die "Error opening candlelist. $!, stopped"; 
# 
#  format_vars(); 
# 
#  #determine if the product is listed 
#  if (exists($candles{$codes})) { 
#   delete($candles{$codes}); 
#   $msg = "The candle $codes $names $prices has been removed."; 
#  } 
#  else { 
#  $msg = "The product you entered is not in the database"; 
#  } 
#  #close database 
#  untie(%candles); 

    #create web page 
    print "<HTML>\n"; 
    print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n"; 
    print "<BODY>\n"; 
    print "<H1>Candles Unlimited</H1>\n"; 
# print "$msg\n"; 
    print "<p>Called remove</p>"; 
    print "</BODY></HTML>\n"; 
    } 

需要注意的是,启用warnings,这喷出了大量的“未初始化值”警告,因为你得到$code VS $codes$name VS $names,和$price vs $prices以不好的方式彼此混淆。 (提示:您指定($code, $name, $price) = format_input();,但format_input不返回三个值。)

我怀疑,正如您在先前的评论中所建议的那样,您遇到了大小写敏感问题。我第一次尝试测试这个失败,因为我在URL中使用了“button = Save”而不是“Button = Save”。根据约定,HTTP请求参数名称通常全部为小写字母,并且有充分的理由,因为它有助于避免此类问题。

其他乱评:

  • 可以同时声明变量,你第一次给它们,例如,my $code = param('Code');。这通常被认为是更好的/首选的做法,因为尽可能晚地做出声明有助于最大限度地减少变量的范围。

  • format_input,它是多余既s/^ +//; s/ +$//;tr/ //d;,作为tr还将删除开头和结尾的空格。

  • 获取参数值时,如果参数为空/缺少,或者检查是否为空/缺少并向用户显示错误,则应提供缺省值。

  • 如果$button丢失或无效,您应该在elsif ($button eq "Delete")之后有最终的else子句,以显示错误。是的,我知道这个脚本是从一个特定的表单调用的,所以它应该总是有一个有效的$button,但是绕过表单并直接向脚本提交任何一组值(有效或无效)是微不足道的,所以您仍然需要验证并验证服务器端的所有内容,因为您不知道它实际来自哪里或客户端是否正确验证了它。

+0

这没有任何意义。我可以添加一个打印按钮行,并验证按钮值是否越过,这意味着添加或删除IS被调用,并且我仍然会得到一个空白页。一旦按下按钮,表单就会调用脚本,而不是相反。 – Jason 2010-05-02 16:26:33

0

这就是我如何运行脚本,它确实产生了正确的结果。确保您在网站的任何位置都安装了适当的PERL模块。

注:我使用的托管服务(BlueHost的)要求我通过#调出我的Perl模块的/ usr/bin中/ perlml

#!/usr/bin/perlml 

    use strict; 
    use warnings; 

    print "Content-type: text/html\n\n"; 
    use CGI qw(:standard); 
    use SDBM_File; 
    use Fcntl; 
    use strict; 

    #declare variables 
    my ($code, $name, $price, $button, $codes, $names, $prices); 


    #assign values to variables 
    $code = param('Code'); 
    $name = param('Name'); 
    $price = param('Price'); 
    $button = param('Button'); 

    ($codes, $names, $prices) = format_input(); 
    ($codes, $names, $prices) = ($code, $name, $price); 

    if ($button eq "Save") { 
    add(); 
    } 
    elsif ($button eq "Delete") { 
    remove(); 
    } 
    exit; 


    sub format_input { 
    $codes =~ s/^ +//; 
    $codes =~ s/ +$//; 
    $codes =~ tr/a-z/A-Z/; 
    $codes =~ tr/ //d; 
    $names =~ s/^ +//; 
    $names =~ s/ +$//; 
    $names =~ tr/ //d; 
    $names = uc($names); 
    $prices =~ s/^ +//; 
    $prices =~ s/ +$//; 
    $prices =~ tr/ //d; 
    $prices =~ tr/$//d; 
    } 

    sub add { 
    #declare variable 
    my %candles; 

    #open database, format and add record, close database 
    tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666) 
    or die "Error opening candlelist. $!, stopped"; 

    format_input(); 
    $candles{$code} = "$name,$price"; 
    untie(%candles); 

    #create web page  
    print "<HTML>\n"; 
    print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n"; 
    print "<BODY>\n"; 
    print "<FONT SIZE=4>Thank you, the following product has been added.<BR>\n"; 
    print "Candle: $codes, $names, $prices</FONT>\n"; 
    print "</BODY></HTML>\n"; 
    } #end add 

    sub remove { 
    #declare variables 
    my (%candles, $msg); 

    tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0) 
    or die "Error opening candlelist. $!, stopped"; 
    format_input(); 

    #determine if the product is listed 
    if (exists($candles{$code})) { 
    delete($candles{$code}); 
    $msg = "The candle $code, $name, $price has been removed."; 
    } 
    else { 
    $msg = "The product you entered is not in the database"; 
    } 
    #close database 
    untie(%candles); 

    #create web page 
    print "<HTML>\n"; 
    print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n"; 
    print "<BODY>\n"; 
    print "<H1>Candles Unlimited</H1>\n"; 
    print "$msg\n"; 
    print "</BODY></HTML>\n"; 
    } 
相关问题