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