你如何得到PHP,符号链接和__FILE__很好地协同工作?

在本地主机上。 我有以下目录结构:

/share/www/trunk/wp-content/plugins/otherfolders

/share/www/portfolio/wp-content/symlink

其中symlink/trunk/.../plugins/的符号链接。 基本上,这是因为我需要testing多个WordPress安装并设置它们,但我不想移动插件并将它们复制并粘贴到任何地方。

但是,有时我需要爬上目录树来包含一个configuration文件:

  $root = dirname(dirname(dirname(dirname(__FILE__)))); if (file_exists($root.'/wp-load.php')) { // WP 2.6 require_once($root.'/wp-load.php'); } 

该文件夹始终parsing为:

/share/www/trunk

即使插件正在执行并包含在内

/share/www/portfolio/

是否有可能在PHP中将文件包含在/share/www/trunk/.../plugins目录中的符号链接脚本中的share/www/portfolio目录中?

虽然这个问题只发生在我的testing服务器,我想有一个安全的可分发的解决scheme,所以爬上一个额外的水平不是一个选项

我用你的代码看到的问题是__FILE__自动parsing符号链接。

从魔术常量的PHP手册

…从PHP 4.0.2开始, __FILE__总是包含一个绝对path,parsing符号链接…

您可以尝试使用$_SERVER["SCRIPT_FILENAME"]来代替。

 $root = realpath(dirname(dirname(dirname(dirname($_SERVER["SCRIPT_FILENAME"]))))); if (file_exists($root.'/wp-load.php')) { // WP 2.6 require_once($root.'/wp-load.php'); } 

请注意,我将realpath()函数添加到根目录。 根据您的设置,您可能需要也可能不需要。

编辑:使用$_SERVER["SCRIPT_FILENAME"]而不是$_SERVER["PHP_SELF"]文件系统path。

您可以使用此代码片段获取符号链接未parsing的path。 如果你没有可用的bash,那么你可以使用不同的命令,但是它可以在linux环境下工作。

我认为这是一个弊端,PHPparsingFILE中的符号链接,因为没有办法获取符号链接的path。 否则,我们可以很容易地得到它使用realpath。

好吧。

 <?php $output = array(); exec('pwd', &$output); define('__LINK__', $output[0].substr(__FILE__, strpos(__FILE__, DIRECTORY_SEPARATOR))); ?> 

在某些情况下,可以更改工作目录并使用getenv('PWD'):

 $root = dirname(dirname(dirname(getenv('PWD')))); if (file_exists($root.'/wp-load.php')) { // WP 2.6 require_once($root.'/wp-load.php'); } 

在运行此代码之前更改工作目录:

 cd /var/www/wp-content/themes/twenty_twelve/ && php script.php 

PHP解释器在处理它们之前parsing符号链接。 你可以用readlink函数自己做这个。 PHP解决了链接,因为它对于*_once函数和像APC,Xcache等代码caching更高效。

你需要的是另一种方法来find一个特定的安装存储它的文件。 我build议使用{$_SERVER['DOCUMENT_ROOT']}/wp-content/wp-load.php假设/share/www/portfolio是文档根目录。

以下是该问题的解决scheme: https : //github.com/logical-and/symlink-detective

 $root = dirname(dirname(dirname(dirname(__FILE__)))); if (file_exists(SymlinkDetective::detectPath($root.'/wp-load.php'))) { // WP 2.6 require_once(SymlinkDetective::detectPath($root.'/wp-load.php')); } 

或者你可以尝试

 try { $root = dirname(dirname(dirname(dirname(__FILE__)))); require_once SymlinkDetective::detectPath($root.'/wp-load.php', '', false /* this would throw an exception if file doesn't exists */); } catch (Exception $e) { // nothing to do if file doesn't exists } 

如果我试图解决这个问题,我会沿path位分割__FILE__ ,并为每个path创build一个SplFileInfo ,使用isDir和isLink进行testing,然后尝试确定如何处理path的重构,比预期的,所以你可以从正确的目录拉。 (如果你更多的是程序types,那么有is_dir和is_link 。)

这就是说,我认为你已经取消了这个解决scheme的资格。 也许这些工具足够聪明,可以为你做。 尝试将getRealPath的结果与getPath进行比较? getRealPath明确表示它解决了符号链接,而getPath并没有明确的说。

即使这样,这个嗅探可能不是在客户端的安全,取决于谁是主机。 我见过一些非常有创意的共享托pipe文件系统设置。 你可以添加一个支票到php_uname,并取出机器的主机名,如果不是你的开发盒,不要做额外的工作。