我正在使用 Perl 建立一个网站。我按如下方式组织我的文件:
- /index.cgi
- /perl/modules/databaseFunctions.pm
- /perl/indexCheck.cgi
- /database/database.xml
在databaseFunctions.pm内部,我有一个函数X(),可以在database.xml上读取和写入。在 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或/perl/indexCheck.cgi内部调用X()时,数据库的相对路径是不同的,但我不知道如何设置适用于索引的路径.cgi 和/perl/indexCheck.cgi。
最佳答案
我认为问题归结为“如何找出当前脚本(*.pl)的路径?”和 “如何找到当前模块(*.pm)的路径?”。
脚本
对于脚本来说,有一个非常方便的模块, FindBin
,为当前脚本的名称和路径提供 4 个变量
符号链接(symbolic link)是否已解析。通常$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/../.."
等等。
编辑
索引.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/modules/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
正是,我认为您正在寻找的东西。
关于Perl - 模块内文件的相对路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35104362/