【问题标题】:Can't locate object method "***" via package "Apache2::RequestRec"无法通过包“Apache2::RequestRec”定位对象方法“***”
【发布时间】:2012-06-08 14:30:16
【问题描述】:

我正在尝试让 mod_perl 在我的 apache 安装上工作,以便使用 perlhandler。

我首先尝试在我的域的子目录中使用此虚拟主机

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName ***.fr.cr

    DocumentRoot /var/www/aw
    <Directory /var/www/aw/>
            AllowOverride None
            Order allow,deny
            allow from all
    </Directory>

    PerlModule test2::Rules2
    alias /perl2/ /usr/lib/perl5/test2/
    <Location /perl2/>
            Order allow,deny
            allow from all
            SetHandler perl-script
            PerlHandler test2::Rules2
    </Location>

    ErrorLog ${APACHE_LOG_DIR}/aw.error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/aw.access.log combined
</VirtualHost>

在这里,当我转到 *.fr.cr/perl2/

时它工作正常

但是,当我尝试使用这个虚拟主机直接对我的域的根目录执行此操作时:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName ***.fr.cr

    DocumentRoot /var/www/aw
    <Directory /var/www/aw/>
            AllowOverride None
            Order allow,deny
            allow from all
    </Directory>

    PerlModule aw::main
    alias / /usr/lib/perl5/aw/
    <Location />
            Order allow,deny
            allow from all
            SetHandler perl-script
            PerlHandler aw::main
    </Location>

    ErrorLog ${APACHE_LOG_DIR}/aw.error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/aw.access.log combined
</VirtualHost>

我收到错误 500,apache 日志有这一行:

Can't locate object method "content_type" via package "Apache2::RequestRec" at /usr/lib/perl5/aw/main.pm line 6.\n

奇怪的是我用 2 个代码测试了

一个缺少“print”包,一个缺少“content_type”包,第一个有“content_type”,但错误在代码后面。

我想我的虚拟主机缺少一些东西,因为它在一种情况下有效,而在另一种情况下却不能使用相同的代码。

谢谢!

编辑:代码: 不工作:

package aw::main;
use Apache2::Const qw(:common);

sub handler {
    my $r = shift;
    $r->content_type("text/plain");
    $r->print("mod_perl rules!\n");
    return OK;
}
1;

和工作:

package test2::Rules2;
use Apache2::Const qw(:common);

sub handler {
my $r = shift;
$r->content_type("text/plain");
$r->print("mod_perl rules!\n");
return OK;
}
1;

【问题讨论】:

  • 最可能的结论是 aw::main 中存在一个不在 test2::Rules2 中的错误。
  • 我复制/粘贴了代码。我会尝试复制文件并重命名它
  • 那我是对的。首先,您的package 声明是错误的。
  • 什么意思?我正在编辑我的帖子以添加代码
  • 尝试添加use Apache2::RequestRec;?不应该,但值得一试。

标签: perl apache mod-perl vhosts


【解决方案1】:

我一直在为同样的问题苦苦挣扎,我想我已经找到了答案:

当您在 Perl 中调用对象方法时,例如myinstance->themethod(arg1) 然后 themethod 获取类(包)的名称作为第一个参数,第一个参数作为第二个参数。如果您将方法称为静态方法,例如class::method(arg1) 那么子程序获得的第一个参数就是第一个参数。像这样:

#!/usr/bin/perl

print "Calling as an object method:\n";
fish->chips('lettuce');
print "Calling as a static method:\n";
fish::chips('lettuce');

{package fish;

sub chips {
  my $x=shift;
  my $y=shift;

  print "\$x is $x and \$y is $y\n";
  }
}

然后输出是:

Calling as an object method:
$x is fish and $y is lettuce
Calling as a static method:
$x is lettuce and $y is 

mod_perl 将您的处理程序作为对象方法调用。它将包名称作为第一个参数。如果您添加shift 并在shift 第二个参数之前丢弃第一个参数,那么您的$r 可能就是您要查找的请求对象。

再次查看我的 Apache conf 文件后,我意识到我将处理程序指令指定为 PerlResponseHandler Fish-&gt;chips 而不是 PerlResponseHandler Fish::chips。 mod_perl 在找到我想使用的处理程序时遇到了一些麻烦。当我指定 Fish 并将处理程序命名为 sub handler {... 时,mod_perl 找不到它。同样,当我指定处理程序名称时,如Fish::handler(或者,我重命名它)Fish::chips,那么 Apache 将在名为 Fish 的目录中查找名为 chips.pm 的文件。

我不知道这是否是 mod_perl 解析或解析处理程序名称的方式中的实际错误,但至少它是非常脆弱的行为。除非我在这里遗漏了什么,如果我遗漏了,我希望有人能指出来。

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多