代码之家  ›  专栏  ›  技术社区  ›  Aaron Butacov

如何让php、symlinks和uu file_uuuu能够很好地协同工作?

  •  40
  • Aaron Butacov  · 技术社区  · 14 年前

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

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

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

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

    但是,有时我需要爬上目录树来包含配置文件:

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

    文件夹始终解析为:

    /share/www/trunk

    即使插件被执行并包含在

    /share/www/portfolio/ .

    在PHP中是否可以在 share/www/portfolio 从在符号链接中执行的脚本到 /share/www/trunk/.../plugins 目录?

    虽然这个问题只发生在我的测试服务器上,但是我希望有一个安全的可分发解决方案,所以 爬上一个额外级别不是一个选项 .

    6 回复  |  直到 8 年前
        1
  •  31
  •   pferate    14 年前

    我在你的代码中看到的问题是 __FILE__ 自动解析符号链接。

    从PHP手册 Magic Constants

    …从php 4.0.2开始, 一个文件 始终包含已解析符号链接的绝对路径…

    您可以尝试使用 $_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() 根目录的函数。根据您的设置,您可能需要它,也可能不需要它。

    编辑:使用 $服务器[“script\u文件名”] 而不是 $_SERVER["PHP_SELF"] 用于文件系统路径。

        2
  •  2
  •   Dag    13 年前

    可以使用此代码段获取未解析符号链接的路径。 如果您没有bash可用,那么可能有一个不同的命令可以使用,但是它可以在Linux环境中工作。

    我认为PHP解决符号链接是一种弊端 文件 因为没有办法获得带有符号链接的路径。否则我们可以很容易地使用realpath获得它。

    哦,好吧。

    <?php
    $output = array();
    exec('pwd', &$output);
    define('__LINK__', $output[0].substr(__FILE__, strpos(__FILE__, DIRECTORY_SEPARATOR)));
    ?>
    
        3
  •  2
  •   AndreyP    9 年前

    在某些情况下,可以更改工作目录并使用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
    
        4
  •  1
  •   jmz    14 年前

    PHP解释器在处理符号链接之前先解析它们。你可以自己用 readlink 功能。PHP解析链接是因为它更高效 *_once 函数和代码缓存,如apc、xcache等。

    您可能需要的是另一种方法来查找特定安装存储文件的位置。我建议使用 {$_SERVER['DOCUMENT_ROOT']}/wp-content/wp-load.php 假设 /share/www/portfolio 是文档根。

        5
  •  1
  •   And    8 年前

    解决这个问题的方法如下: 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
    }
    
        6
  •  0
  •   Charles    14 年前

    如果我想解决这个问题,我会分道扬镳。 __FILE__ 沿着路径位创建一个 SplFileInfo 一路走来,用 isDir isLink ,然后在知道路径与预期不同后,尝试确定如何处理路径重建,以便从正确的目录中进行提取。(如果你是程序型的,有 is_dir is_link )

    尽管如此,我认为你已经取消了这个解决方案的资格。也许这些工具足够聪明,可以为你做这件事。尝试比较 getRealPath getPath ?getrealpath明确表示它解析符号链接,而getpath没有明确表示。

    即便如此,这种嗅探在客户端站点上也可能不安全,这取决于主机是谁。我见过一些漂亮的 创造性的 共享托管文件系统设置。你可以给 php_uname 然后拉出机器的主机名,如果它不是您的dev框,就不要做额外的工作。