Comment faire pour que PHP, Symlinks et FILE fonctionnent bien ensemble?

sur localhost. J'ai la structure de répertoire suivante:

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

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

symlink est un lien symbolique vers /trunk/.../plugins/. Fondamentalement, c'est parce que j'ai besoin de tester plusieurs installations WordPress et de les configurer, mais je ne veux pas avoir à déplacer des plugins et les copier et les coller partout.

cependant, parfois j'ai besoin de parcourir l'arborescence des répertoires pour inclure un fichier de configuration:

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

Le dossier se résout toujours à:

/share/www/trunk

même lorsque le plugin est exécuté et inclus dans

/share/www/portfolio/.

Est-il possible en PHP pour inclure les fichiers dans le share/www/portfolio répertoire à partir d'un script exécutant un lien symbolique vers le /share/www/trunk/.../plugins répertoire?

bien que ce problème n'arrive que sur mon serveur de test, j'aimerais avoir une solution distribuable en toute sécurité donc grimper un niveau supplémentaire n'est pas une option.

39
demandé sur Aaron Harun 2010-07-11 07:42:49

6 réponses

le problème que je vois avec votre code est que __FILE__ résout les liens symboliques automatiquement.

dans le Manuel PHP Constantes Magiques

... Depuis PHP 4.0.2,__FILE__ contient toujours un chemin absolu avec des liens symboliques résolus ...

Vous pouvez essayer d'utiliser $_SERVER["SCRIPT_FILENAME"] à la place.

$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');
  }

Notez que j'ai ajouté realpath() fonction dans le répertoire racine. Selon votre configuration, vous pouvez ou non avoir besoin il.

EDIT: Use $_SERVER["SCRIPT_FILENAME"] au lieu de $_SERVER["PHP_SELF"] pour le chemin du système de fichiers.

29
répondu pferate 2010-07-23 00:44:06

Vous pouvez utiliser cet extrait de code pour obtenir un chemin où les liens symboliques ne sont pas résolus. Si vous n'avez pas bash disponible, il y a probablement une commande différente que vous pouvez utiliser, mais cela fonctionne sur les environnements linux.

je ne pense que c'est une faute professionnelle que php résout des liens symboliques dans FILE, puisqu'il n'y a aucun moyen d'obtenir le chemin avec des liens symboliques. Sinon, nous pourrions facilement l'obtenir en utilisant realpath.

Oh bien.

<?php
$output = array();
exec('pwd', &$output);
define('__LINK__', $output[0].substr(__FILE__, strpos(__FILE__, DIRECTORY_SEPARATOR)));
?>
2
répondu Dag 2011-12-22 14:10:08

dans certains cas, il est possible de changer le dir de travail et d'utiliser getenv ('PWD'):

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

Et changer de répertoire de travail avant d'exécuter ce code:

cd /var/www/wp-content/themes/twenty_twelve/ && php script.php
2
répondu AndreyP 2016-06-07 17:06:43

L'interpréteur PHP résout les liens symboliques avant de les traiter. Vous pouvez le faire vous-même avec l' readlink fonction. PHP résout les liens parce que C'est plus efficace pour *_once les fonctions et les caches de code comme APC,Xcache etc.

ce dont vous avez probablement besoin est une autre façon de trouver où une installation particulière stocke ses fichiers. Je recommande d'utiliser {$_SERVER['DOCUMENT_ROOT']}/wp-content/wp-load.php en supposant que /share/www/portfolio est la racine du document.

1
répondu jmz 2010-07-19 15:31:58

Voici la solution à ce problème: 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'));
  }

ou vous pouvez essayer

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
}
1
répondu And 2016-11-30 10:05:23

Si je devais essayer de résoudre ce problème, j'avais split __FILE__ le long des bits de chemin et créer un SplFileInfo pour chaque le long de la route, test isDir et isLink, puis essayer de déterminer comment gérer la reconstruction du chemin une fois qu'il est connu pour être différent que prévu de sorte que vous pouvez tirer à partir du bon répertoire. (Si vous êtes plus d'un type de procédure, il ya is_dir et is_link.)

cela étant dit, je je pense que vous avez déjà disqualifié cette solution. Peut-être que les outils sont assez intelligents pour le faire pour vous. Essayez de comparer le résultat de getRealPath getPath? getRealPath dit expressément qu'il résout les liens symboliques, tandis que getPath ne le dit pas expressément.

même alors, ce reniflement pourrait ne pas être sûr sur les sites clients, selon qui l'hôte est. J'ai vu quelques jolies création configuration du système de fichiers d'hébergement partagé. Vous pouvez ajouter une vérifier php_uname et retirez le nom d'hôte de la machine, et si ce n'est pas votre dev box, ne faites pas le travail supplémentaire.

0
répondu Charles 2010-07-11 05:09:05