我正在使用Perl构建一个网站。我按如下方式组织了我的文件:
在 databaseFunctions.pm 里面我有一个在database.xml上读写的函数X()。在X()中,我指定了数据库的相对路径如下:
sub X{
my $db_path='../../database/database.xml';
my $parser=XML::LibXML->new();
my $doc=$parser->parse_file($db_path);
....
....
}
问题在于:
我必须从index.cgi和indexCheck.cgi调用X()但是我得到一个错误,出现以下错误:
Could not create file parser context for file "../../database/database.xml": No such file or directory at perl/modules/databaseFunctions.pm line 21.
我认为问题在于,当我在index.cgi中调用X()或在/perl/indexCheck.cgi内调用数据库的相对路径时,我不知道如何设置有效的路径对于index.cgi和/perl/indexCheck.cgi。
答案 0 :(得分:2)
我认为问题归结为"如何找出当前脚本(* .pl)的路径?"和 "如何找出当前模块的路径(* .pm)?"。
对于脚本,有一个非常方便的模块FindBin
,它为当前脚本的名称和路径提供了4个变量。
符号链接是否已解决。通常$FindBin::Bin
是您正在寻找的。它是当前脚本的路径。
我经常使用它来增强@INC
路径,以便我的脚本找到其他(自己的)模块,如下所示:
use FindBin;
use lib "$FindBin::Bin/my_mod_path";
use MyModule;
在这种情况下,在当前脚本路径下方的目录MyModule.pm
中搜索my_mod_path
。非常方便。
该模块是核心发行版的一部分,即不需要进一步安装。
FindBin
可能无法安全地从模块内部使用,因为它取决于谁(脚本或模块)创建第一个use FindBin;
。
因此,如果您不想关心订单,请不要在模块中use FindBin;
,只能在脚本中使用。
对于模块,有一些技巧。使用perl函数caller()
。
根据调用的上下文,它返回实际调用它的文件的$filename
。
因此,在模块中,您可以安全地使用以下内容来获取模块的路径:
use File::Basename;
my $path_of_this_module = File::Basename::dirname( eval { ( caller() )[1] } );
根据该路径,您可以相对于它进行导航,以便找到您需要的其他文件,例如"$path_of_this_module/../.."
等等。
的index.cgi:
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/perl/modules";
use databaseFunctions;
databaseFunctions::X( "called from index.cgi\n" );
的perl / indexCheck.cgi:
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/modules";
use databaseFunctions;
databaseFunctions::X( "called from indexCheck.cgi\n" );
的perl /模块/ databaseFunctions.pm:
package databaseFunctions;
use File::Basename;
my $path_of_this_module = File::Basename::dirname( eval { ( caller() )[1] } );
sub X {
my $arg = shift;
my $db_path="$path_of_this_module/../../database/database.xml";
open(my $fh, '>>', $db_path) or die "cannot open $db_path: $!\n";
print $fh $arg;
close($fh);
}
1;
当我现在调用./index.cgi然后调用./perl/indexCheck.cgi时,我得到以下内容:
数据库/ database.xml:
called from index.cgi
called from indexCheck.cgi
确切地说,我认为你在寻找。