mod_perl的工作原理是将每个 Perl 脚本包装handler
在一个基于脚本名称和路径的包内调用的子例程中。这个子例程不是启动一个新进程来运行每个脚本,而是handler
由许多持久的 Perl 线程中的一个调用。
通常,这些知识将有助于理解mod_cgi中的环境变化,但是由于您从未添加use strict
到程序中并且熟悉声明变量的工作原理,因此您还有很多工作要做!
mod_perl环境有可能导致不明显的安全漏洞,您现在应该开始处理use strict
每个脚本并声明每个变量。use Carp
还将帮助您了解错误日志。
声明的变量名our
是同名包变量的词法范围同义词,可以在不完全限定名称的情况下通过包含包名来使用。例如,通常用 声明的变量our $var
将提供对$main::var
标量的访问(如果之前没有package
声明)而无需指定main::
. undef
然而,这些以in mod_cgi值开始生命的变量现在将保留它们在任何给定mod_perl线程的先前执行中的值,并且为了保持一致性,始终在声明点初始化它们是最安全的。另请注意,默认包名称不再main
是因为包装了mod_perl确实如此,因此您不能再使用main::
前缀访问包变量,并且找到包的实际名称并明确使用它是不明智的,因为它将是一个非常长的名称,并且会在您移动或重命名脚本时发生变化。
my
变量是独立于包符号表而存在的变量,通常它的生命周期是封闭文件(对于在文件范围内声明的变量)或子例程的运行时间。如果在脚本的文件范围内或完全在一个子例程中声明和使用它们,它们在mod_perl中是安全的,但如果您混合范围并my $global
在文件范围内声明 a 然后尝试在子例程中使用它,您可能会被刺痛。原因并不简单,而是由于mod_perl将您的脚本包装在一个handler
子例程中,因此您有嵌套的子例程声明。内部子例程将倾向于只采用第一个实例化$global
并忽略由以后调用创建的任何其他handler
. 如果您需要一个全局变量,您应该使用它声明它our
并在该声明中初始化它,如上所述。
变量与local
变量非常相似our
,因为它是包变量的同义词。但是,它会临时保存该变量的当前值并提供一个新副本以供使用,直到文件或块范围结束。由于它在其范围内自动创建和删除,它可以成为mod_perlmy
脚本中变量的有用替代方案,特别是在您使用指向数据结构(例如类的实例)的指针的情况下。声明将正确创建对象,但由于mod_perl 的持久性,会将其留在内存中,直到线程的下一次执行将其删除以腾出空间给另一个对象。CGI
our $cgi = CGI->new
至于你的问题:
使用变量而不声明它会导致编译时错误,如果use strict
它应该是适当的。否则,它是当前包命名空间中该变量的同义词。
变量要么是包变量,要么是词法变量;没有办法将变量声明为私有的。my
每次执行脚本时都会创建和销毁词法变量(用不要做你想做的事。声明为 with 的变量our
将在调用脚本时保留其值,而声明为 with的变量将local
在脚本终止时销毁。our
和变量都是local
包变量,所有对同一个变量名的引用都指向同一个变量。
要声明一个在脚本的任何一次调用中随处可访问的变量,您可以使用local
变量或初始化our
变量。在文件范围内local $global
很大程度上等同our $global = undef
于mod_perl脚本。如果您使用our
变量指向数据结构,请记住在脚本末尾使用undef $global
.
my
变量在声明它们的块中是唯一的,并且在其内可见,无论该块是if
、while
或内的块for
,甚至只是一个裸{ ... }
块范围。始终将my
变量用于临时工作变量,这些变量仅在块内使用且无法从其他地方访问。
我希望这有帮助