
Perl: variable scope issue with CGI & DBI modules我遇到了一个以前从未遇到过的变量范围问题。我正在使用Perl的CGI模块和对DBI的do()方法的调用。这是代码结构,简化了一点:
#1占位符变量的求值方式好像是未初始化的。其他两个占位符变量起作用。 问题:为什么%in哈希在do()的上下文中不可用,除非我将其包装在双引号中(#2占位符)或将值重新分配给新变量(#3占位符)? 我认为这与CGI模块的ReadParse()函数如何将范围分配给%in哈希有关,但是我不知道Perl的作用域是否足以理解为什么%in在顶级可用,而在我自己的工作范围内不可用()声明。 如果有人确实了解范围问题,是否有更好的方法来解决?用双引号将所有%in引用包装起来似乎有些混乱。为每个查询参数创建新变量是不现实的。 明确地说,我的问题是关于变量范围界定问题。我意识到,不建议使用ReadParse()使用CGI来获取查询参数。 我正在使用Perl 5.8.8,CGI 3.20和DBI 1.52。预先感谢任何阅读此书的人。 @Pi和@Bob,感谢您的建议。预先声明%in的范围无效(并且我始终使用strict)。结果与之前相同:在数据库中,col1为null,而cols 2和3设置为期望值。 供参考,这里是ReadParse函数(见下文)。这是CGI.pm的一部分的标准功能。以我的理解,我不是为了设置作用域而初始化哈希中的%(不是满足严格条件),因为在我看来该函数可以处理该问题:
我想我的问题是在do()上下文中获取%in哈希的最佳方法是什么?再次感谢!我希望这是为我的原始问题提供更多信息的正确方法。 @丹:我听说有关&ReadParse语法。我通常使用CGI :: ReadParse(),但在这种情况下,我认为最好坚持使用CGI.pm文档的确切方式。
它实际上并不像您在使用文档中所述的那样: 如果必须使用它,那么CGI :: ReadParse();似乎更明智,语法也更简洁。虽然我看不到它在这种情况下有什么大的不同,但是那是一个绑定变量,所以谁知道该怎么做;) 您是否有特定原因无法使用更常见的$ cgi-> param('foo')语法?它稍微干净一点,并且以相当可预测的方式隐藏了您的命名空间。 我不知道出了什么问题,但是我可以告诉您一些不是的事情:
尝试声明
看看是否有帮助。如果失败,则 从您给出的示例来看,这不是范围问题,或者所有参数都不起作用。
看起来DBI(或DBD,不确定在何处使用绑定参数)没有兑现领带魔术。 使用SQLite和DBI 1.53进行的简单测试表明它可以正常工作:
想要共享您正在使用的数据库吗?
您正在使用哪个版本的DBI?从DBI changelog看,似乎1.00之前的版本不支持attribute参数。我怀疑"未初始化的" 那里的东西很破。 Perl的作用域相对简单,除非您做些愚蠢的事情,否则您不太可能会偶然发现类似的事情。如建议的那样,打开严格的编译指示(以及警告。实际上,无论如何您都应同时使用两者)。 在不能够看到%in是如何定义的情况下很难说出是怎么回事(这与看上去讨厌的ReadParse调用有关吗?为什么用前导&,btw调用它?该语法已被认为是无效的)并消失了很长时间)。我建议发布更多代码,以便我们了解发生了什么。 首先,这不在做的上下文/范围内。它仍然处于主要或全局范围内。除非以与Perl中的子例程或不同"类"相关的某种方式输入{},否则您不会离开上下文。在()内,您不会超出范围。 您提供给我们的样本是未初始化的哈希,并且正如Pi所建议的那样,使用strict肯定会阻止这些事件的发生。 您能给我们一个更具代表性的代码示例吗?您在哪里设置%IN以及如何设置? 根据DBI文档:当前,绑定绑定变量不起作用。 DBI的内幕非常复杂,不幸的是,经过一些回转才能有效地引起问题。我同意其他人所说的摆脱丑陋的cgi-lib风格代码的说法。如果没有很好的框架(去Catalyst),做CGI就很不愉快了,更不用说十年来已经过时的东西。 我刚刚从http://www.carcomplaints.com/test/test.pl.txt尝试了您的测试密码,它可以立即在我的计算机上运行,??没有问题。我得到了三个预期值。我没有将其作为CGI运行,而是使用:
我在控制台上写了一个变量(
但是,如果您不进行此操作,则tt将插入一个空字符串和两个NULL。这是因为您将值插值到字符串中。这将创建一个值为
由于这开始看起来像是
它应该打印 好的,试试这个:
这可能会有所帮助,因为它实际上使用的是您声明的变量,因此可以控制的范围(另外,它还会让您 尝试这个 %in = ReadParse(); 但我对此表示怀疑。您是否要获取查询参数或其他内容? |