Zil*_*llo 6 perl scope mod-perl mod-perl2
几年来我一直在使用apache mod_cgi.现在我转向mod_perl,我发现了一些问题,特别是子程序.直到现在我从未使用my,our也没有local; 并且CGI脚本没有问题.阅读文档后,甚至在此处发布的一些先前的问题,我或多或少了解如何my,our并且local工作.我担心的是下一个请求之间将共享哪些信息(如果我理解正确的话,这是我在运行mod_perl而不是mod_cgi时必须具备的主要问题).
our在标量中使用还是只是在没有声明任何特殊内容的标量之间有什么区别my?不是全球性的吗?my的标内的if在文件的同一级别或同一子程序,在那之后我创建另一个if地方我用同样的标量; 两个if或每个之间共享的标量是否if意味着不同的块?什么while和for,是他们对先前声明为不同的块my标或只适用于子程序和文件?Bor*_*din 17
mod_perl的工作原理是将每个Perl脚本包装在handler基于脚本名称和路径的包内调用的子例程中.这个handler子例程不是启动一个新进程来运行每个脚本,而是由许多持久性Perl theads中的一个调用.
通常,这些知识可以帮助我们理解mod_cgi中环境的变化,但是由于你从未添加use strict到程序中并熟悉声明变量的工作方式,所以你需要做很多工作!
该mod_perl的环境对造成非明显的安全漏洞的可能性,你现在应该开始use strict对每一个脚本,并声明所有的变量.use Carp还将帮助您了解错误日志.
声明的变量名称our是具有相同名称的包变量的词法范围同义词,可以在不通过包含包名称来完全限定名称的情况下使用该变量.例如,通常声明的变量our $var将提供对$main::var标量的访问(如果没有前面的package声明)而没有指定main::.但是,这些undef以mod_cgi值开始生命的变量现在将保留其先前执行任何给定mod_perl线程的值,并且为了保持一致性,始终在声明点初始化它们是最安全的.另请注意,默认包名称不再main是因为包装了mod_perl是的,所以你不能再使用main::前缀来访问包变量,找到包的实际名称并明确地使用它是不明智的,因为它将是一个非常长的名称,并且如果你移动或重命名你的脚本将会改变.
甲my变量是一个独立于包符号表的存在,并且通常它的寿命是封闭文件的运行时间(在文件范围声明的变量)或子程序.如果在脚本的文件范围内声明和使用它们,或者完全在一个子例程中,它们在mod_perl中是安全的,但如果混合范围并声明my $globalat文件范围然后尝试在子例程中使用它,则可能会受到攻击.原因并不简单,但它是由mod_perl将脚本包装在handler子例程中引起的,因此您有嵌套的子例程声明.内部子例程将倾向于仅采用第一个实例化$global并忽略后来调用创建的任何其他实例handler.如果您需要一个全局变量,您应该声明它our并在该声明中初始化它,如上所述.
甲local变量是非常像一个our在其形成的同义词到封装变量的变量.但是,它会暂时保存该变量的当前值,并提供一个新副本以供使用,直到文件或块作用域结束.由于它在其范围内自动创建和删除,因此它可以替代mod_perl脚本中的my变量,特别是在使用指向数据结构的指针时,例如,类的实例.声明会正确创建对象但是,由于mod_perl的持久性,它将留在内存中,直到线程的下一次执行删除它为另一个执行腾出空间.CGIour $cgi = CGI->new
至于你的问题:
使用变量而不声明它会导致编译时错误,如果use strict它应该存在的话.否则,它是当前包命名空间中该变量的同义词.
变量是包变量或词法变量; 没有办法将变量声明为私有变量.my每次执行脚本时都会创建和销毁词法变量(声明为),除非你通过编写一个使用在更宽范围内声明的变量的子例程创建了一个无效的闭包,当变量将是持久的但是赢了做你想做的事.声明的变量our将在脚本调用之间保留其值,而声明的变量将local在脚本终止时被销毁.两者our和local变量都是包变量,对同一变量名的所有引用都引用相同的变量.
要声明在脚本的任何一次调用中始终可访问的变量,您可以使用local变量或初始化our变量.在文件范围local $global在很大程度上等同于our $global = undef为mod_perl的脚本.如果您使用our变量指向数据结构,请记住在脚本末尾使用它来销毁它undef $global.
my变量对于声明它们的块是唯一的,并且在它们内部是可见的,无论它是一个块if,while还是for,甚至只是一个裸{ ... }块范围.始终将my变量用于临时工作变量,这些变量仅在块中使用,并且可以从其他任何地方访问.
我希望这有帮助
编辑:这是关于Perl变量范围的一般信息.有关具体mod_perl问题,请参阅Borodin的帖子.
声明的变量my是词法.换句话说,它们仅存在于当前范围内.您应该my默认声明所有变量; 当你特别想要不同的功能时,只做别的事.
使用词法范围的变量是(几乎)任何语言中良好代码设计的基本部分.把use strict;和use warnings;在所有脚本都需要你遵循这一好的做法.
our是一种声明全局变量的方法; 底层结果与使用未声明的全局变量非常相似.但是,它有两个不同之处:
use strict;.our可以通过您在当前范围内的所有包中声明的名称访问.相反,未声明的变量只能通过当前包中的简单名称访问.除此之外,你只能将其称为$package::variable.有关更多详细信息,请参阅文档our.
local不会创建词法变量; 相反,它是一种在当前范围内为全局变量赋予临时值的方法.它主要与Perl的特殊内置(标点符号)变量一起使用:
{
local $/; #make the record separator undefined in this scope only.
my $file = <FILE>; #read in an entire file at once.
}
Run Code Online (Sandbox Code Playgroud)
您可以随时使用my变量,local只使用上面显示的特殊情况.