为什么我不能插值 $cgi->param($key)?

Why can't I interpolate the $cgi->param($key)?

提问人:Marcos Camargo 提问时间:7/29/2023 最后编辑:Marcos Camargo 更新时间:7/30/2023 访问量:70

问:

我正在调试这个脚本,CGI 参数的值显示如下:

username
CGI=HASH(0x55887d94d850)->param{username} <--- Why is that? It should show the value.
password
CGI=HASH(0x55887d94d850)->param{password} <---

应该打印参数的值,而不是我得到这个 HASH 的东西。为什么?

这是脚本:

#!/usr/bin/perl -w                                                                                                           
use strict;                                                                                                                  
use warnings;                                                                                                                
use CGI("-utf8");                                                                                                            
use CGI::Session;                                                                                                            
use CGI::Carp qw(fatalsToBrowser);
sub BEGIN {
  unshift (@INC, '/var/application/module/');
};                                                                                                                           
use Auth;

### Header                                                                                                                   
########################                                                                                                     
my $cgi = CGI->new();

##########                                                                                                                   
if ( $ENV{REQUEST_METHOD} eq "POST" ) {
  my %form;
  my $session_dir="/var/tmp";
  my ($admin_user,$admin_password) = ("admin","arun123");

  print "Content-type: text/html; charset=utf-8\n\n";
  print "<!DOCTYPE html>\n";
  print "<html>\n";
  foreach my $key ($cgi->param()) {
    $form{$key} = $cgi->param($key);
    #print "<h3>$key $cgi->param{$key}</h3>\n";                                                                              
    print "<h3>$key</h3>\n";
    print "<h3>$cgi->param($key)</h3>\n";
  };
  print "</html>\n";
  exit;

当我使用 Variable 方法时,结果是正确的:

password arun123
username admin

  my %vars = $cgi->Vars();
  my $args;
  for my $key (keys %vars) {
    my $var = $vars{$key};
    chomp $var;
    $var =~ s/^\s+//;
    $var =~ s/\s+$//;
    $args->{$key} = $var;
    print "<h3>$key $var</h3>\n";
  };

谢谢!

Perl CGI

评论


答:

-1赞 glratt 7/29/2023 #1

我相信你正确地完成了作业

    $form{$key} = $cgi->param($key);

,调用 $cgi->param 作为带有参数$key的函数,但您的打印

    print "<h3>$cgi->param{$key}</h3>\n";

似乎将 $cgi-param 视为哈希值 - 也许

    print "<h3>$cgi->param($key)</h3>\n";

是你所追求的?

评论

0赞 Marcos Camargo 7/29/2023
打印 “<h3>$cgi->param($key)</h3>\n”;产生 CGI=HASH(0x558aa6e62850)->param(用户名)
0赞 brian d foy 7/30/2023
不能插值方法调用。看看我自己的答案。
3赞 clamp 7/30/2023 #2
print "<h3>$cgi->param{$key}</h3>\n"; 

将变量插值到字符串中,但不计算 Perl 代码。$cgi$key

尝试

print "<h3>".$cgi->param($key)."</h3>\n"; 
4赞 brian d foy 7/30/2023 #3

@clamp已经解释了你的特定输出,但故事还有更多。

Perl 在双引号上下文 (perldata) 中插入一些序列。

  • 各种基数中的字符编号,如 、 、 等。\012\x0a\x{23CE}
  • 预定义的字符转义,例如 .\n
  • 以 或 开头的变量名,包括 用于单元素访问的下标(如果是 和 切片)。请注意,切片不是其中的一部分。$@$@%

在您的情况下,您正在尝试包含方法调用的结果。Perl 不会插值这些变量,这就是为什么它会迭代并作为两个独立的标量变量。$cgi$key

有一些方法可以解决这个问题。首先,考虑 或 ,我觉得它更适合复杂sprintfprintf

printf "<h3>%s</h3>\n", $cgi->param($key);

第二,正如@clamp所指出的,

print "<h3>" . $cgi->param($key) . "</h3>\n";

第三,由于你可以取消引用一个数组来插值它的内容,而Perl允许你在大括号内放置一个匿名数组构造函数:

print "<h3>@{[$cgi->param($key)]}</h3>\n";

最后,您可以改用各种模板系统。这样,您的 HTML 就不会分散在整个程序中。