web-dev-qa-db-fra.com

Comment obtenez-vous PHP, Symlinks et __File__ pour travailler 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 à /trunk/.../plugins/. Fondamentalement, c'est parce que j'ai besoin de tester plusieurs WordPress les installe et définissez-les, mais je ne veux pas avoir à déplacer les plugins autour et à les copier et à les coller partout.

Cependant, parfois, j'ai besoin de ramper dans l'arborescence de répertoire 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 résout toujours:

/share/www/trunk

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

/share/www/portfolio/.

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

Bien que ce problème ne se produise que sur mon serveur de test, je voudrais disposer d'une solution distribuable en toute sécurité, de sorte que rampage d'un niveau supplémentaire n'est pas une option .

41
Aaron Harun

Le problème que je vois avec votre code est que __FILE__ Résout automatiquement les symboles.

À partir du PHP manuel sur constantes magiques

... Depuis PHP 4.0.2, __FILE__ Contient toujours un chemin absolu avec des symboles 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é la fonction realpath() fonction du répertoire racine. Selon votre configuration, vous pouvez ou non plus besoin.

EDIT: Utilisez $_SERVER["SCRIPT_FILENAME"] Au lieu de $_SERVER["PHP_SELF"] Pour le chemin du système de fichiers.

31
pferate

Dans certains cas, il est possible de changer de Dir 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 modifier le répertoire de travail avant d'exécuter ce code:

cd /var/www/wp-content/themes/twenty_twelve/ && php script.php
2
AndreyP

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

Je pense que c'est une faute professionnelle que PHP résout les liens symboliques dans FICHIER , car il n'y a aucun moyen d'obtenir le chemin avec des liens symboliques. Sinon, nous pourrions facilement l'obtenir en utilisant realpath.

Tant pis.

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

Voici la solution à ce problème: https://github.com/logical-and/symlink-deective

$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 ça

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

Le PHP INTERPRÈTE résout les symboles de symboles avant qu'il ne les traite. Vous pouvez le faire vous-même avec la fonction readlink _. PHP résout les liens car c'est plus efficace pour *_once Fonctions et caches de code tels que APC, XCACHACH, etc.

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

1
jmz

Si j'essayais de résoudre ceci, je sortais __FILE__ le long des bits de chemin et créer un splfileinfo pour chaque chemin, testez avec ISDIR et ISLink , essayez ensuite de déterminer comment gérer Reconstruction du chemin une fois qu'il est connu d'être différent que prévu afin que vous puissiez tirer dans le bon répertoire. (Si vous êtes plus d'un type de procédure, il y a is_dir et is_link .)

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

Même dans ce cas, cette reniflication pourrait ne pas être sûre sur les sites clients, en fonction de la question de l'hôte. J'ai vu un peu créatif d'hébergement partagée des configurations de système de fichiers. Vous pouvez ajouter un chèque à php_uname et retirez le nom d'hôte de la machine et s'il ne s'agit pas de votre boîte de devir, ne faites pas le travail supplémentaire.

0
Charles