如何在PHP中获取符号链接的原始路径?

如何在PHP中获取符号链接的原始路径?,php,path,symlink,Php,Path,Symlink,我的web文件夹中有几个文件,包括以下两个: /mydocroot/include/somesubdir/include.inc.php /mydocroot/include/settings.inc.php 其中somesubdir是指向我磁盘上另一个目录的符号链接,指向名为/anywhere/else的路径 在include.inc.php中,这样写的内容如下: <?php require_once "../settings.inc.php"; ?> 在我看来,这应

我的web文件夹中有几个文件,包括以下两个:

  • /mydocroot/include/somesubdir/include.inc.php
  • /mydocroot/include/settings.inc.php
其中somesubdir是指向我磁盘上另一个目录的符号链接,指向名为/anywhere/else的路径

include.inc.php中,这样写的内容如下:

<?php

require_once "../settings.inc.php";

?>

在我看来,这应该包括/mydocroot/include/settings.php。。。但是猜猜会发生什么:PHP尝试包含/anywhere/settings.inc.PHP,而不是/mydocroot/include/settings.inc.PHP

看起来PHP自动解析符号链接


如何避免这种情况并包含我的settings.inc.php文件?

最直接的解决方案是始终使用绝对路径。有多种方法可以做到这一点,从每次需要时硬编码路径,到在脚本顶部硬编码一次并引用路径,再到动态计算路径并在脚本顶部设置一次

第三个选项是大多数现成的CMS用来运行而不完全了解文件结构的选项

为什么以这种方式使用符号链接目录?

您可以使用来检查文件是否为符号链接。如果是,则使用获取绝对目标


但是,在十年的php开发中,我从来没有理由使用符号链接。正如Jason所建议的,我总是定义或推导一次绝对路径,然后在整个应用程序中使用它使所有文件路径成为绝对路径。

我只是遇到了一个类似的问题。您可以通过使用显示请求文件的
$\u服务器['SCRIPT\u FILENAME']
变量来实现,因此在您的示例中,它将是
/mydocroot/include/somesubdir/include.php
,即使
somesubdir
是一个符号链接。包含一个较低级别的文件,而不是

require_once "../settings.inc.php";
这样做:

require_once dirname(dirname($_SERVER['SCRIPT_FILENAME'])).DIRECTORY_SEPARATOR."settings.inc.php"

解决方案是创建一个basepath变量。最好的方法是在脚本顶部包含以下内容,然后引用它

$basepath = dirname(dirname($_SERVER['SCRIPT_FILENAME'])).DIRECTORY_SEPARATOR;
然后,您可以在include、requires等中引用基本路径。因此

include "../myscript.php";
会变成,

include $basepath."myscript.php";
include $basepath."../myscript.php";
如果您继续前进,您将看到:

include "../../myscript.php";
会变成,

include $basepath."myscript.php";
include $basepath."../myscript.php";
您必须嵌套dir_name函数两次,再加上需要反向勾选的每个额外文件夹一次。您必须一直返回到存在符号链接的文件夹


我认为这个问题是PHP的一个主要设计缺陷。我想不出有哪一个实例需要访问相对于实际文件的反勾选文件。在所有情况下,包括虚拟主机,只有沿着链接路径回归才有意义,而不是目标路径。

什么是
echo\uuuuuu DIR\uuu
inside
/include.inc.php
print?@Rocket:
echo\uuuu DIR\uuuu打印
/anywhere/else
。问题是它无法按他尝试的方式反向工作。本质上,链接目录中的文件无法确定它所在的目录是在链接上下文中访问的,而不是直接通过文本文件系统访问的。至于使用符号链接,它在有限的上下文中是有意义的。在OP的上下文中,唯一有意义的方法是在多个虚拟主机之间共享文件;我确实使用了符号链接,因为我不想在硬盘上有同一文件的多个版本。这是共享代码。很公平,这就是我问的原因。你仍然可以用我的答案。在包含
/mydocroot/include/somesubdir/include.inc.php->/anywhere/else/include.inc.php
之前,先设置或计算它。也许不太理想,但据我所知,这就是你所拥有的一切。这似乎是实现这一目标的唯一途径。这就是我创建解决方法的方式:我在/mydocroot/include/中创建了一个文件(称为symlink.php),其中只包含一条语句:
define(“ROOT”),\uuuuuu DIR\uuuuu
然后在include.inc.php中检查是否定义了常量
ROOT
。如果是,则使用该路径。