在Perl中传递哈希引用

时间:2011-12-26 11:20:13

标签: perl hash reference subroutine

我试图在Perl 5.8.8中传递哈希引用,我知道这应该是一件非常简单的事情。我在代码中遍布哈希值,但由于某种原因,它在这个子例程中不起作用:

sub build_results_hash {
    my %results;
    my $search = $_[0];
    my $json = $_[1];
    my $json_passed = $_[2];

    my $dbh = db_connect(-db=>'ghgs');

    my $db_search = html_db_input($search,$dbh);
    %results = db_hoh(-query=>"SELECT listing_id,MATCH(search) AGAINST($db_search) as relevance FROM search WHERE MATCH(search) AGAINST($db_search) LIMIT 1000",-key=>"listing_id",-dbh=>$dbh);

    if(($json_passed == 1) and ($json ne '[]'))
    {
        narrow_results_hash(\%results,$search,$dbh,$json);
    }

    db_x($dbh);

    return \%results;
}

sub db_hoh {
    # ...
    return %hoh;
}

db_hoh只返回散列哈希值。问题是我致电narrow_results_hash并通过%results;这是行不通的。但是,如果我删除围绕该方法调用的if语句,则哈希传递正常!我不确定会导致这种行为的原因。以下是我收到哈希的方法:

sub narrow_results_hash
{
    use JSON::XS;
    my $params = shift;
    my %results = %$params;
    # ...
    print join(',',keys %results), "\n";
    # ...
}

如果我删除ifnarrow_results_hash电话周围的build_results_hash声明,则会打印:“107,99,34”。但是,如果调用周围存在if语句,则会打印“HASH(0x7fd61fbf0580)”。

2 个答案:

答案 0 :(得分:2)

我对评论的评论太多了。

对于您的实际问题,我们需要了解一些能够帮助您的事情。

  1. db_hoh返回什么,对哈希的引用或键值对列表。
  2. 你怎么说,“不行”?是不是没有工作?它是否完成了一些操作,但会给你一个意想不到的结果?
  3. 此外,我对您的代码有一些风格的评论。我认为你来自C世界,我是对的吗?

    1. 解包@_作为列表分配更清晰
    2. 声明%results可以等到填充
    3. 除非我误解,否则您不需要使用$json_passed,而是可以测试$json是否已定义
    4. narrow子广告中,您可以避免创建$params
    5. 以下是更新后的代码:

      sub build_results_hash {
          my ($search, $json) = @_; 
      
          my $dbh = db_connect(-db=>'ghgs');
      
          my $db_search = html_db_input($search,$dbh);
          my %results = db_hoh(
            -query=>"SELECT listing_id,MATCH(search) AGAINST($db_search) as relevance FROM search WHERE MATCH(search) AGAINST($db_search) LIMIT 1000",
            -key=>"listing_id",
            -dbh=>$dbh
          );
      
          if((defined $json) and ($json ne '[]'))
          {
              narrow_results_hash(\%results,$search,$dbh,$json);
          }
      
          db_x($dbh);
      
          return \%results;
      }
      
      sub narrow_results_hash
      {
          use JSON::XS; #unless you expect this import to be local it looks funny here
          my %results = %{ shift() };
          # ...
      }
      

      最后,也可能最重要的是,除非html_db_input正在清除存储在$db_search中的输入,否则您将面临SQL injection次攻击。看起来你有自己的数据库访问库,但如果你使用DBI,我会做类似的事情:

      my $dbh = ...; # connect to db
      my $sth = $dbh->prepare('SELECT listing_id,MATCH(search) AGAINST(?) as relevance FROM search WHERE MATCH(search) AGAINST(?) LIMIT 1000');
      $sth->execute($db_search,$db_search);
      my $results = $sth->fetchall_hashref('listing_id');
      

      这可以防止$db_search的内容更改您的SQL语句。

答案 1 :(得分:1)

db_hoh可能返回哈希引用而不是哈希。尝试使用标量作为结果变量。

my %results;

变为

my $results;

依旧......