web-dev-qa-db-ja.com

PHP、Symlinks、__ FILE__を連携させるにはどうすればよいですか?

ローカルホスト上。次のディレクトリ構造があります。

/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ディレクトリにファイルを含めることは可能ですか?

この問題はテストサーバーでのみ発生しますが、安全に配布できるソリューションを用意したいので、追加のレベルをクロールすることはオプションではありませんです。

41
Aaron Harun

私のコードで見られる問題は、___FILE___がシンボリックリンクを自動的に解決することです。

PHP Manual on Magic Constants から

... 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"]_をファイルシステムパスに使用します。

31
pferate

場合によっては、作業ディレクトリを変更して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
AndreyP

このコードスニペットを使用して、シンボリックリンクが解決されないパスを取得できます。 bashが利用できない場合は、おそらく別のコマンドを使用できますが、これはLinux環境で動作します。

Phpが[〜#〜] file [〜#〜]のシンボリックリンクを解決するのは不正行為だと思います。シンボリックリンクでパスを取得する方法がないためです。それ以外の場合は、realpathを使用して簡単に取得できます。

しかたがない。

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

これがその問題の解決策です: 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
And

PHPインタプリタは、シンボリックリンクを処理する前にそれらを解決します。これは、readlink関数を使用して自分で行うことができます。PHP *_once関数およびAPC、Xcacheなどのコードキャッシュに効率的.

おそらく必要なのは、特定のインストールがファイルを保存する場所を見つける別の方法です。 {$_SERVER['DOCUMENT_ROOT']}/wp-content/wp-load.phpをドキュメントルートとして、/share/www/portfolioを使用することをお勧めします。

1
jmz

私がこれを解決しようとした場合、私は分割します__FILE__パスのビットに沿って、それぞれに SplFileInfo を作成し、 isDir および isLink でテストしてから、処理方法を決定しますパスが予想とは異なることがわかったら、パスを再構築して、正しいディレクトリからプルできるようにします。 (手続き型の場合は、 is_diris_link があります。)

そうは言っても、あなたはすでにこのソリューションを失格にしたと思います。多分ツールはあなたのためにそれをするのに十分スマートです。 getRealPath の結果を getPath と比較してみてください。 getRealPathはシンボリックリンクを解決することを明示的に言っていますが、getPathはそれを明示的に言っていません。

それでも、ホストが誰であるかによっては、このスニッフィングはクライアントサイトでは安全ではない可能性があります。私はいくつかのきれいなクリエイティブ共有ホスティングファイルシステムの設定を見てきました。 php_uname にチェックを追加して、マシンのホスト名を引き出すことができます。それが開発ボックスでない場合は、余分な作業を行わないでください。

0
Charles