[PHP] Construction lien relatif

  • Auteur de la discussion marsien
  • Date de début

marsien

Grand Maître
Salut à tous,

Je me pose des questions pour construire un lien relatif "variable" pointant vers un même fichier depuis différentes pages ne se situant pas au même niveau de l'arborescence de mon site. Et pour le moment, je n'ai encore pas trouver de réponses satisfaisantes.

2 ex auxquels je suis confronté :
■ex 1 : j'ai plusieurs pages dans lesquelles je fais un include() d'un script php. Dans le fichier inclus, je dois ouvrir un fichier précis (toujours le même). Comment je dois écrire le lien dans fopen() pour pointer vers ce dernier fichier, sachant que mon script est inclus dans des pages pouvant se trouver à différents niveaux de l'arborescence de mon site ? Un simple lien relatif avec des éventuels ../ n'est pas évident à mettre en place, car je dois à chaque fois analyser la position de la page contenant le script... Je ne peux pas mettre de lien absolu (question de portablité du script). Que faire ?
■ex 2 : j'ai un script qui est appelé depuis une url à l'intérieur de mes pages. Mes pages peuvent toujours se trouver à différents niveaux de l'arborescence. Dans le script appelé, je fait une redirection vers une autre page, pouvant elle aussi se trouver à différents niveaux de l'arborescence. Comment écrire le lien relatif (toujours pas absolu, question de portabilité) ?

Merci d'avance pour vos idées ou vos pistes. J'avais pensé mettre un lien relatif depuis la racine de mon site (en démarrant le lien par un "/"). Problème : la racine pour fopen() n'est pas celle du site... D'où une erreur ! Je pense qu'une des solution pourrait être de passer par realpath(), mais je ne vois pas trop comment construire le lien ?...

:)
 

marsien

Grand Maître
J'ai pu retrouver la racine de mon site dans l'arborescence du serveur de la manière suivante :

Code:
$racine = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['SCRIPT_FILENAME']);

Il ne me reste plus qu'à la compléter par le chemin complet vers mon fichier à ouvrir avec fopen();

Ca répond donc à ma première question, mais je me demande s'il n'y a pas une méthode plus simple et robuste pour y répondre...
 

marsien

Grand Maître
Je relance au cas où je n'aurais pas été clair dans mes précédents messages

Prenons un exemple concret. J'ai :
■un fichier script.php contenu dans le dossier php, dossier à la racine du site
■un fichier inclus.php, lui aussi dans le dossier php. Ce fichier est inclus dans le fichier script.php
■un fichier mapage1.php situé à la racine du site. Le fichier script.php est inclus dans ce fichier
■un fichier mapage2.php situé dans le dossier pages, dossier à la racine du site. Le fichier script.php est inclus dans ce fichier

Sous une forme schématique :
[fixed]|-
PHP:
|    |-inclus.php
|    |-script.php
|-[pages]
|    |-mapage2.php
|-mapage1.php[/fixed]

Donc dans les fichiers [b]mapage1.php[/b] et [b]mapage2.php[/b], pour l'inclusion du fichier [b]script.php[/b], j'ai respectivement :
[cpp]include('php/script.php'); // mapage1.php
include('../php/script.php'); // mapage2.php[/cpp]
Jusque là, pas de souci, vu que la position relative de [b]script.php[/b] est fixe par rapport à [b]mapage1.php[/b] et ma [b]page2.php[/b].

Mais le problème se pose pour l'inclusion de [b]inclus.php[/b] dans [b]script.php[/b]. En effet son lien d'inclusion dépend non pas de sa position par rapport à [b]script.php[/b], mais de sa position par rapport au fichier dans lequel [b]script.php[/b] est inclus. Donc, le lien d'inclusion de [b]inclus.php[/b] dans [b]script.php[/b] est variable :
[cpp]include('php/inclus.php'); // pour le cas où script.php est inclus dans mapage1.php
include('../php/inclus.php'); // pour le cas où script.php est inclus dans mapage2.php[/cpp]
D'où ma question : comment coder en PHP ce lien variable relatif à l'inclusion de [b]inclus.php[/b] dans [b]script.php[/b]

La question est valable pour include() (et pourrait être contourné en faisant toutes les inclusion dans les fichiers [b]mapageX.php[/b]). Mais le problème reste entier dans le cas de fopen() par ex.

Donc si vous avez des solutions ou des idées pour pouvoir créer automatiquement le lien pointant vers fopen/iclude/require([b]inclus.php[/b]) dans [b]script.php[/b] en fonction de la position de [b]mapageX.php[/b] par rapport à [b]script.php[/b]...

Merci d'avance de votre aide.
 

boub popsyteam

Grand Maître
Tu as jeté un ti coup d'oeil sur $_SERVER['PATH_TRANSLATED'] ?
 

marsien

Grand Maître
Je ne connaissais pas effectivement. Mais elle n'existe pas chez Free, qui héberge mon site... Donc ça ne résout pas mon problème :/

Merci de ton aide, et si tu as d'autres idées... :)
 

boub popsyteam

Grand Maître
A prioris ça existe chez free en hebergement payant ...

Et en mettant le chemin absolu et non relatif ?

 

marsien

Grand Maître
La technique du chemin absolu, je l'ai testé (voir mon 2 ème message de ce topic). Mais ça me génère des erreurs de fichier non trouvés avec include();...

Du coup je me suis penché sur un autre angle d'attaque : prendre comme point de repère fixe la racine du site et construire tous mes liens relatifs à partir d'elle.

Dans l'ordre :
■1. évaluer la position dans l'arborescence du fichier actuel
■2. construire les retours à la racine, c'est-à-dire calculer le nombre de ../ nécessaire pour revenir du fichier actuel à la racine
■3. ajouter ce nombre de ../ en début des liens pointant vers mes fichiers à inclure (include();) ou ouvrir (fopen();)

Donc voilà la fonction (basique pour le moment, mais fonctionnelle et suffisante pour mes besoins actuels) :
[cpp]function racine() // calcule la position relative du fichier actuel par rapport à la racine et crée le nombre de remontées(../) nécessaires pour y revenir
{
$nbSlashes = substr_count($_SERVER['SCRIPT_NAME'], '/'); // on compte le nombre total de slashes contenu dans le lien relatif du fichier courant
$nbSlashes --; // on ne compte pas le slash de la racine (placé au début du lien relatif)
$remontee = ''; // on iniitialise la remontée dans l'arborescence
for($i = 0; $i < $nbSlashes; $i++)
{
$remontee .= '../';
}
return $remontee;
}[/cpp]
Et par rapport à mes exemples donnés dans un de mes précédents posts, on écrit les liens à inclure ou ouvrir dans le fichier script.php de la façon suivante :
[cpp]include(racine().'php/inclus.php');[/cpp]

Voilà :)

Améliorations à apporter : ce script oblige à remonter à la racine à chaque fois. Et donc à réécrire toute l'arborescence du fichier de destination (à inclure ou ouvrir). On pourrait donc passer en paramètre le niveau dans l'arborescence du fichier à inclure/ouvrir et le soustraire à $nbSlashes. C'est surtout intéressant si tout ce passe en permanence dans un sous-niveau de l'arborescence.
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 134
Messages
6 718 077
Membres
1 586 394
Dernier membre
Manoushk
Partager cette page
Haut