Как вы получаете PHP, Symlinks и __FILE__ для совместной работы? - PullRequest
40 голосов
/ 11 июля 2010

На локальном хосте.У меня есть следующая структура каталогов:

/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 ]

31 голосов
/ 22 июля 2010

Проблема, которую я вижу с вашим кодом, заключается в том, что __FILE__ автоматически разрешает символические ссылки.

Из руководства по 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"] в качестве пути к файловой системе.

2 голосов
/ 30 ноября 2016

Вот решение этой проблемы: 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
}
2 голосов
/ 07 июня 2016

В некоторых случаях возможно изменить рабочий каталог и использовать 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
2 голосов
/ 22 декабря 2011

Вы можете использовать этот фрагмент кода, чтобы получить путь, по которому символические ссылки не разрешаются.Если у вас нет bash, возможно, есть другая команда, которую вы можете использовать, но она работает в среде linux.

Я думаю, что это халатность, когда php разрешает символические ссылки в FILE ,так как нет способа получить путь с символическими ссылками.В противном случае мы могли бы легко получить это используя realpath.

Ну да ладно.

<?php
$output = array();
exec('pwd', &$output);
define('__LINK__', $output[0].substr(__FILE__, strpos(__FILE__, DIRECTORY_SEPARATOR)));
?>
1 голос
/ 19 июля 2010

Интерпретатор PHP разрешает символические ссылки перед их обработкой. Вы можете сделать это самостоятельно с помощью функции readlink. PHP разрешает ссылки, потому что он более эффективен для *_once функций и кэшей кода, таких как APC, Xcache и т.д.

Что вам, вероятно, нужно, это еще один способ найти, где конкретная установка хранит свои файлы. Я бы рекомендовал использовать {$_SERVER['DOCUMENT_ROOT']}/wp-content/wp-load.php при условии, что /share/www/portfolio является корнем документа.

0 голосов
/ 11 июля 2010

Если бы я пытался решить эту проблему, я бы разделил __FILE__ вдоль битов пути и создал SplFileInfo для каждого пути, протестировав с isDir и isLink , затем попытайтесь определить, как обрабатывать восстановление пути, если известно, что он отличается от ожидаемого, чтобы вы могли извлечь из нужного каталога. (Если вы более процедурного типа, есть is_dir и is_link .)

При этом, я думаю, вы уже дисквалифицировали это решение. Может быть, инструменты достаточно умны, чтобы сделать это для вас. Попробуйте сравнить результат getRealPath с getPath ? getRealPath прямо говорит, что разрешает символические ссылки, в то время как getPath прямо не говорит этого.

Даже тогда этот анализ может быть небезопасным на клиентских сайтах, в зависимости от того, кто является хостом. Я видел несколько симпатичных креативных общих файловых систем хостинга. Вы можете добавить проверку к php_uname и вытащить имя хоста машины, и если это не ваше устройство разработки, не выполняйте дополнительную работу.

...