Perl 在传递给子例程时引用和引用哈希值?

发布于 2024-11-28 06:55:21 字数 1809 浏览 5 评论 0原文

我已经为这个问题苦苦思索了大约 5 个小时,我真的很沮丧,需要一些帮助。

我正在编写一个 Perl 脚本,该脚本从 MySQL 表中提取作业,然后执行各种数据库管理任务。当前任务是“创建数据库”。该脚本成功创建了数据库,但是当我为 PHP 开发人员生成配置文件时,它崩溃了。

我认为这是引用和取消引用变量的问题,但我不太确定到底发生了什么。我认为在这个函数调用之后,发生了一些事情 $$结果{'数据库名称'}。这就是我获取结果的方式: $result = $select->fetchrow_hashref()

这是我的函数调用和函数实现:

函数调用(第 127 行):

generateConfig($$result{'databaseName'}, $newPassword, "php");

函数实现:

sub generateConfig {
    my($inName) = $_[0];
    my($inPass) = $_[1];
    my($inExt)  = $_[2];

    my($goodData) = 1;
    my($select)   = $dbh->prepare("SELECT id FROM $databasesTableName WHERE name = '$inName'");
    my($path)     = $documentRoot.$inName."_config.".$inExt;
    $select->execute();

    if ($select->rows < 1 ) {
            $goodData = 0;
    }

    while ( $result = $select->fetchrow_hashref() )
    {
            my($insert) = $dbh->do("INSERT INTO $configTableName(databaseId, username, password, path)".
                                   "VALUES('$$result{'id'}', '$inName', '$inPass', '$path')");

    }

    return 1;
    }

错误:

Use of uninitialized value in concatenation (.) or string at ./dbcreator.pl line 142.
Use of uninitialized value in concatenation (.) or string at ./dbcreator.pl line 154.

第 142 行:

        $update = $dbh->do("UPDATE ${tablename}
                        SET ${jobStatus}='${newStatus}' 
                        WHERE id = '$$result{'id'}'");

第154行:

 print "Successfully created $$result{'databaseName'}\n";

我认为问题来自函数调用的原因是因为如果我注释掉函数调用,一切都会很好!

如果有人能帮助我了解发生了什么,那就太好了。

谢谢,

ps如果您发现在数据库中以纯文本形式存储密码存在安全问题,那么在正常工作后将得到解决。 =P

迪伦

I've been banging my head over this issue for about 5 hours now, I'm really frustrated and need some assistance.

I'm writing a Perl script that pulls jobs out of a MySQL table and then preforms various database admin tasks. The current task is "creating databases". The script successfully creates the database(s), but when I got to generating the config file for PHP developers it blows up.

I believe it is an issue with referencing and dereferencing variables, but I'm not quite sure what exactly is happening. I think after this function call, something happens to
$$result{'databaseName'}. This is how I get result: $result = $select->fetchrow_hashref()

Here is my function call, and the function implementation:

Function call (line 127):

generateConfig($result{'databaseName'}, $newPassword, "php");

Function implementation:

sub generateConfig {
    my($inName) = $_[0];
    my($inPass) = $_[1];
    my($inExt)  = $_[2];

    my($goodData) = 1;
    my($select)   = $dbh->prepare("SELECT id FROM $databasesTableName WHERE name = '$inName'");
    my($path)     = $documentRoot.$inName."_config.".$inExt;
    $select->execute();

    if ($select->rows < 1 ) {
            $goodData = 0;
    }

    while ( $result = $select->fetchrow_hashref() )
    {
            my($insert) = $dbh->do("INSERT INTO $configTableName(databaseId, username, password, path)".
                                   "VALUES('$result{'id'}', '$inName', '$inPass', '$path')");

    }

    return 1;
    }

Errors:

Use of uninitialized value in concatenation (.) or string at ./dbcreator.pl line 142.
Use of uninitialized value in concatenation (.) or string at ./dbcreator.pl line 154.

Line 142:

        $update = $dbh->do("UPDATE ${tablename}
                        SET ${jobStatus}='${newStatus}' 
                        WHERE id = '$result{'id'}'");

Line 154:

 print "Successfully created $result{'databaseName'}\n";

The reason I think the problem comes from the function call is because if I comment out the function call, everything works great!

If anyone could help me understand what's going on, that would be great.

Thanks,

p.s. If you notice a security issue with the whole storing passwords as plain text in a database, that's going to be addressed after this is working correctly. =P

Dylan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

诗酒趁年少 2024-12-05 06:55:21

您不想存储对从 fetchrow_hashref 返回的 $result 的引用,因为每个后续调用都会覆盖该引用。

没关系,当您调用generate_config 时,您没有使用引用,因为您是按值传递数据。

您在generate_config和调用函数中使用相同的$result变量吗?您应该在generate_config 中使用您自己的“my $result”。

      while ( my $result = $select->fetchrow_hashref() )
      #       ^^  #add my

这就是您所包含的当前代码片段可以说的全部内容。

一些清理:

  1. 当调用generate_config时,您是按值传递,而不是按引用传递。这很好。
  2. 您收到 undef 警告,这意味着您正在使用“use strict;”运行。好的!
  3. 在函数中通过 my.create 词法 $result
  4. 虽然 $$hashr{key} 是有效代码,但 $hashr->{key} 是首选。
  5. 您正在使用 dbh->prepare,不妨使用占位符。

    子generateConfig {
      my($inName, inPass, $inExt) = @_;
    
      我的 $goodData = 1;
      我的 $select = $dbh->prepare("从 $databasesTableName WHERE name = 中选择 id ?");
      我的 $insert = $dbh->prepare("
                        插入 $configTableName(
                          数据库ID
                          ,用户名
                          ,密码
                        ,小路) 
                        值(?,?,?,?)”);
      我的 $path = $documentRoot 。 $inName . “_配置”。 。 $inExt;
      $select->执行( $inName );
    
      if ($select->行 < 1 ) {
            $好数据= 0;
      }
    
      而(我的 $result = $select->fetchrow_hashref() )
      {
        插入->执行( $结果->{id}, $inName, $inPass, $path );
      }
    
     返回1;
    

    }

You do not want to store a reference to the $result returned from fetchrow_hashref, as each subsequent call will overwrite that reference.

That's ok, you're not using the reference when you are calling generate_config, as you are passing data in by value.

Are you using the same $result variable in generate_config and in the calling function? You should be using your own 'my $result' in generate_config.

      while ( my $result = $select->fetchrow_hashref() )
      #       ^^  #add my

That's all that can be said with the current snippets of code you've included.

Some cleanup:

  1. When calling generate_config you are passing by value, not by reference. This is fine.
  2. you are getting an undef warning, this means you are running with 'use strict;'. Good!
  3. create lexical $result within the function, via my.
  4. While $$hashr{key} is valid code, $hashr->{key} is preferred.
  5. you're using dbh->prepare, might as well use placeholders.

    sub generateConfig {
      my($inName, inPass, $inExt) = @_;
    
      my $goodData = 1;
      my $select   = $dbh->prepare("SELECT id FROM $databasesTableName WHERE name = ?");
      my $insert   = $dbh->prepare("
                        INSERT INTO $configTableName(
                          databaseID
                          ,username
                          ,password
                        ,path) 
                        VALUES( ?, ?, ?, ?)" );
      my $path     = $documentRoot . $inName . "_config." . $inExt;
      $select->execute( $inName );
    
      if ($select->rows < 1 ) {
            $goodData = 0;
      }
    
      while ( my $result = $select->fetchrow_hashref() )
      {
        insert->execute( $result->{id}, $inName, $inPass, $path );
      }
    
     return 1;
    

    }

旧伤慢歌 2024-12-05 06:55:21

编辑:阅读您的评论后,

我认为这两个错误都与您使用 $$result 有关。如果 $resultfetchrow_hashref 的返回值,如:

$result = $select->fetchrow_hashref()

那么引用其值的正确方法应该是:

 print "Successfully created " . $result{'databaseName'} . "\n";

and:

    $update = $dbh->do("UPDATE ${tablename}
                    SET ${jobStatus}='${newStatus}' 
                    WHERE id = '$result{'id'}'");

旧答案:

在函数 generateConfig 中,您可以使用以下语法传递引用:(

generateConfig(\$result{'databaseName'},$newPassword, "php");

$$ 用于取消对字符串的引用;\ 为您提供对对象的引用它适用于)。

然后,在 print 语句本身中,我会尝试:

 print "Successfully created $result->{'databaseName'}->{columnName}\n";

确实,fetchrow_hashref 返回一个哈希值(而不是字符串)。

这应该可以解决一个问题。

此外,您正在使用名为 $dbh 的变量,但没有显示它的设置位置。它是一个全局变量,以便您可以在 generateConfig 中使用它吗?执行generateConfig时是否已初始化?

EDIT: after reading your comment

I think that both errors have to do with your using $$result. If $result is the return value of fetchrow_hashref, like in:

$result = $select->fetchrow_hashref()

then the correct way to refer to its values should be:

 print "Successfully created " . $result{'databaseName'} . "\n";

and:

    $update = $dbh->do("UPDATE ${tablename}
                    SET ${jobStatus}='${newStatus}' 
                    WHERE id = '$result{'id'}'");

OLD ANSWER:

In function generateConfig, you can pass a reference in using this syntax:

generateConfig(\$result{'databaseName'},$newPassword, "php");

($$ is used to dereference a reference to a string; \ gives you a reference to the object it is applied to).

Then, in the print statement itself, I would try:

 print "Successfully created $result->{'databaseName'}->{columnName}\n";

indeed, fetchrow_hashref returns a hash (not a string).

This should fix one problem.

Furthermore, you are using the variable named $dbh but you don't show where it is set. Is it a global variable so that you can use it in generateConfig? Has it been initialized when generateConfig is executed?

放手` 2024-12-05 06:55:21

当我从 Oracle 结果集中运行 hetchrow_hashref 时,这让我抓狂。
结果列名总是以大写形式返回。
因此,一旦我开始以大写形式引用列,问题就消失了:
插入->执行( $结果->{ID}, $inName, $inPass, $path );

This was driving me crazy when I was running hetchrow_hashref from Oracle result set.
Turened out the column names are always returned in upper case.
So once I started referencing the colum in upper case, problem went away:
insert->execute( $result->{ID}, $inName, $inPass, $path );

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文