你如何让PHP,Symlinks和__FILE__很好地协同工作?

时间:2010-07-11 03:42:49

标签: php linux symlink

在localhost上。我有以下目录结构:

/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 个答案:

答案 0 :(得分:31)

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

来自Magic Constants

上的PHP手册
  

...自PHP 4.0.2起,__FILE__总是包含已解析符号链接的绝对路径...

您可以尝试使用$_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"]作为文件系统路径。

答案 1 :(得分:2)

您可以使用此代码段来获取未解析符号链接的路径。 如果你没有可用的bash,你可以使用不同的命令,但它适用于linux环境。

我认为php解决了 FILE 中的符号链接是一种弊端,因为无法通过符号链接获取路径。否则我们可以使用realpath轻松获得它。

哦,好吧。

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

答案 2 :(得分:2)

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

$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

答案 3 :(得分:2)

以下是该问题的解决方案: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
}

答案 4 :(得分:1)

PHP解释器在处理符号链接之前解析符号链接。您可以使用readlink功能自行完成此操作。 PHP解析链接,因为它对*_once函数和代码缓存(如APC,Xcache等)更有效。

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

答案 5 :(得分:0)

如果我尝试解决此问题,我会沿着路径位分割__FILE__,并为每个路径创建SplFileInfo,使用isDir和{{3}进行测试然后尝试确定如何知道路径的重建,一旦知道它与预期的不同,这样你就可以从正确的目录中拉出来。 (如果您更多的是程序类型,则有isLinkis_dir。)

话虽如此,我认为你已经取消了这个解决方案的资格。也许这些工具足够聪明,可以为您完成。尝试将is_link的结果与getRealPath进行比较? getRealPath明确表示它解析了符号链接,而getPath没有明确说明。

即使这样,这种嗅探在客户端站点上可能也不安全,具体取决于主机是谁。我见过一些漂亮的创意共享托管文件系统设置。您可以将检查添加到getPath并提取机器的主机名,如果它不是您的开发箱,则不要做额外的工作。