几年来我一直在使用apache mod_cgi。现在,我转到mod_perl,发现了一些问题,尤其是子例程。到目前为止,我从未使用过myourlocal; CGI脚本可以正常工作。在阅读了文档甚至此处以前发布的一些问题之后,我或多或少地了解了myourlocal的工作方式。我担心的是下一个请求之间将共享哪些信息(如果我理解正确,那是我在运行mod_perl而不是mod_cgi时必须关注的主要问题)。

  • 在不声明任何特殊内容(例如our)的情况下,在标量中使用my还是仅在标量中使用,有什么区别?都不都是全局性的吗?
  • 如果我不声明标量为私有(private),将在下一个请求中共享它?甚至在同一台服务器上的另一个Perl脚本的另一个请求中?
  • 如何在子例程中将标量值共享给该子例程之外,但不能在同一文件或同一请求之外共享?
  • 如果我在文件的同一级别或同一子例程中的my内的标量中使用if,然后在使用相同标量的位置创建另一个if;在if或每个if之间共享的标量意味着不同的块吗? whilefor怎么样?它们是先前声明为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 中该变量的同义词。
  • 变量是包变量或词法变量;无法将变量声明为私有(private)变量。除非每次编写脚本都使用一个在较宽范围内声明的变量的子例程来创建如上所述的无效闭包,否则在每次执行脚本时都将创建并销毁词汇变量(用my声明),否则该变量将是持久的,但是不会做你想要的。用our声明的变量将在脚本调用期间保留其值,而用local声明的变量将在脚本终止时销毁。 ourlocal变量都是包变量,并且对相同变量名的所有引用都引用相同的变量。
  • 要声明在脚本的任何一次调用中任何地方都可以始终访问的变量,可以使用local变量或初始化的our变量。在文件范围内,local $global在很大程度上等效于mod_perl脚本的our $global = undef。如果您使用our变量指向数据结构,请记住在脚本末尾使用undef $global销毁它。
  • my变量对于声明它们的块而言是唯一的,并且在其中可见,无论是ifwhile还是for内的块,甚至只是裸{ ... }块作用域。始终将my变量用于临时工作变量,这些临时工作变量仅在一个块内使用,并且无法从其他任何地方访问。

  • 我希望这有帮助

    关于perl - 从CGI移到mod_perl。了解我的,我们的,本地的,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13024239/

    10-15 23:26