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
Où 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.
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.
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)));
?>
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
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.
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
}
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.