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




(6)

在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目录?

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


Answers

我在代码中看到的问题是__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"]作为文件系统路径。


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

我确实认为php解决了FILE中的符号链接是一种弊端,因为无法通过符号链接获取路径。 否则我们可以使用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解释器在处理符号链接之前解析符号链接。 您可以使用readlink功能readlink完成此readlink 。 PHP解析链接,因为它对*_once函数和代码缓存(如APC,Xcache等)更有效。

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


如果我试图解决这个问题,我会沿着路径位分割__FILE__并为每个路径创建一个SplFileInfo ,使用isDirisLink测试,然后尝试确定一旦知道不同路径的重建路径超出预期,所以你可以从正确的目录拉。 (如果你更像是一个程序类型,那就是is_diris_link 。)

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

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


它应该包含在$_SERVER['REMOTE_ADDR']变量中。







php linux symlink