【问题标题】:How to get the original path of a symbolic link in PHP?如何在 PHP 中获取符号链接的原始路径?
【发布时间】:2012-04-01 23:27:23
【问题描述】:

我的网络文件夹中有几个文件,包括这两个:

  • /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 文件?

【问题讨论】:

  • echo __DIR__; 里面的/include.inc.php 打印什么?
  • @Rocket: echo __DIR__; 打印 /anywhere/else

标签: php path symlink


【解决方案1】:

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

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

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

【讨论】:

  • 您已经在对@adam 的评论中指出了这一点;我确实使用了符号链接,因为我不想在我的硬盘上拥有同一个文件的多个版本。这是共享代码。
  • 很公平,这就是我问的原因。你仍然可以使用我的答案。在包含/mydocroot/include/somesubdir/include.inc.php -&gt; /anywhere/else/include.inc.php 之前,只需先设置或计算它。也许并不理想,但据我所知,这就是你所拥有的一切。
  • 这似乎是唯一可以完成的方法。这是我创建解决方法的方式:我在 /mydocroot/include/ 中创建了一个文件(称为 symlink.php),其中仅包含一个语句:define("ROOT", __DIR__);然后在 include.inc.php 中检查常量ROOT 是否已定义。如果是,则使用该路径。
【解决方案2】:

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

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

【讨论】:

  • 问题是它不能倒退,就像他试图做的那样。本质上,链接目录中的文件无法确定它所在的目录是在链接上下文中访问的,而不是直接通过文字文件系统访问的。至于使用符号链接,它在有限的上下文中是有意义的。在 OP 的上下文中唯一有意义的方法是文件是否在多个虚拟主机之间共享。
【解决方案3】:

我刚刚遇到了类似的问题。您可以使用$_SERVER['SCRIPT_FILENAME'] 变量来显示请求的文件,因此在您的情况下它将是/mydocroot/include/somesubdir/include.inc.php,即使somesubdir 是一个符号链接。包含一个低一级的文件而不是做

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

这样做:

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

Documentation about $_SERVER variables

【讨论】:

    【解决方案4】:

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

    $basepath = dirname(dirname($_SERVER['SCRIPT_FILENAME'])).DIRECTORY_SEPARATOR;
    

    然后您可以在包含、要求等中引用基本路径。因此,

    include "../myscript.php";
    

    会变成,

    include $basepath."myscript.php";
    

    如果你再打勾,你会得到这个:

    include "../../myscript.php";
    

    会变成,

    include $basepath."../myscript.php";
    

    您必须将 dir_name 函数嵌套两次,并为需要反引号的每个附加文件夹再嵌套一次。您必须一直返回到存在符号链接的文件夹。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      • 2015-07-18
      • 2023-03-17
      相关资源
      最近更新 更多