IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

[Tableaux] Chemins relatifs, chemins absolus, adresse...JE PATAUGE! [Tutoriel]


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 14
    Par défaut [Tableaux] Chemins relatifs, chemins absolus, adresse...JE PATAUGE!
    Bonjour,

    Je débute en php , et je n'ai pas encore bien saisi les nuances dans les différentes façons de donner un chemin dans le code.
    J'étais parti sur des chemin utilisant des $_SERVER['DOCUMENT_ROOT'] comme racine, puis le chemin relatif à la racine.
    Malheureusement ça ne fonctionne pas pour donner le chemin d'une css. Donc je suis reparti sur des chemins relatifs pleins de "../../../../.." du style :
    <link rel="stylesheet" href="../css/default.css" type="text/css">
    Mais là j'avoue que c'est moi qui ne suis pas du tout convaincu. En plus cette méthode là ne fonctionne pas avec des include ou des require.
    Donc pour l'instant mon site tourne avec la première méthode pour les include et la deuxième pour les css.

    Comme je commence à peine mon site et que je ne voudrais pas partir sur une mauvaise méthode dès le début, quelqu'un pourrait-il me dire quelle est la meilleure méthode pour indiquer les chemins en php et html svp.

    Merci d'avance.

    PS : taum (membre du forum) m'a aussi parlé de $_SERVER["HTTP_HOST"] pour le chemin vers les css.

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    657
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 657
    Par défaut
    Salut,

    Comme je disais, $_SERVER['HTTP_HOST'] représente le nom d'hôte du site, par exemple www.developpez.net ici
    On peut donc l'utiliser pour forger des chemins absolus, par exemple quelque soit l'url de la page tu peux utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <link rel="stylesheet" href="http://<?= $_SERVER['HTTP_HOST'] ?>/css/default.css" type="text/css">
     
    qui générera :
    <link rel="stylesheet" href="http://www.exemple.com/css/default.css" type="text/css">
    Néanmoins je ne vois pas de méthode qui puisse marcher à la fois pour les includes et pour les CSS, étant donné que dans un cas on a besoin du chemin local, et dans l'autre de l'url

  3. #3
    Membre Expert

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Par défaut
    L'adressage d'un fichier est en effet un probleme récurrent.

    Je vais essayer de resumer les différentes possibilités :

    * L'URL du fichier : de la forme http://www.site.com/dossier/fichier.ext
    * L'adresse absolue : de la forme /dossier/fichier.ext
    * L'adresse relative : de la forme ../../fichier.ext

    Voyons maintenant les avantages et inconvenients de chaqune :
    1) L'URL
    Avantages :
    * Facile a trouver, puisque ca represente réellement l'adresse depuis le quel le fichier est accessible depuis l'exterieur.
    Inconvenients :
    * Depend de l'hebergeur (ou du moins du nom de domaine)
    * Ne fonctionne pas pour des includes ou autre, car commence par http://, donc ca ouvre une connection reseau. Or il est normal qu'on ne puisse pas faire d'include de fichiers trouvés sur le reseau (sinon on ferait tous include http://www.nasa.gov/secret/.htaccess et on récupererais tout les password ;o)
    Résumé : a ne pas utilisé, sauf pour les liens entre les pages eventuellement

    2) l'adresse absolue
    Avantages :
    * Permet d'acceder au fichier depuis n'importe ou sur le site avec une seule adresse
    Inconvenients :
    * Depend de l'hebergeur encore une fois, car certains hebergeurs ne mettent pas la racine a la racine du site, mais a la racine du serveur...
    * Certains hebergeurs ne permettent pas de recuperer le chemin depuis la racine du serveur, donc impossible de l'utiliser parfois.
    * Ne peux pas etre utilisé pour les liens entre les pages si on part de la racine du serveur

    3) l'adressage relatif (mon préféré ;o)
    Avantages :
    * Permet d'acceder a n'importe quoi n'importe ou et n'importe comment (au risque de s'y perdre ;o)
    Inconvenients :
    * Le chemin est différent pour chaque repertoire ou il est utilisé.

    Comme j'aime bien faire du code portable (independent de l'hebergeur), seul l'adressage relatif me parait etre une solution.

    Je n'ai isolé que 2 solutions pour faire du code portable :

    A) sans aucun prérequis :
    Ajouter en haut de chaque page PHP une variable qui défini son chemin par rapport a la racine du site.
    Par exemple, avec l'aborescence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    index.php
    \_dossier1
    ___a.php
    \_dossier2
    ___\_sousdossier2
    _______c.php
    ___b.php
    On aura :
    dans index.php : $path="";
    dans a.php : $path="../";
    dans b.php : $path="../";
    dans c.php : $path="../../";

    Ainsi, depuis TOUT les fichiers, on peut faire
    * un lien vers c.php avec : echo "<a href='".$path."dossier2/sousdossier2/c.php">lien</a>";
    * un include de c.php avec : include($path."dossier2/sousdossier2/c.php");

    Ainsi, on a une solution qui est un mélange d'adressage relatif et absolu puisque tout les liens dans le code contiendrons l'adressage absolu depuis la racine du site (quelque soit l'hebergeur cette fois ci)

    B) prerequis : dossier "include"
    Si l'hebergeur permet d'avoir un dossier "include" on peut mettre dedans un fichier php contenant une fonction permettant de "calculer" la variable $path qu'on mettait dans chaque fichier de la solution A.
    le fichier etant dans ce repertoire spécial, on peut, au debut de chaque fichier, faire :
    include("fonctionPath.php");
    et le fichier sera trouvé tout le temps (c'est le but de ce repertoire)

    ensuite, il n'y a plus qu'a faire une fonction qui renvoit le chemin et l'utiliser de la meme maniere que dans A :
    * echo "<a href='".getPath()."dossier2/sousdossier2/c.php">lien</a>";
    * include(getPath()."dossier2/sousdossier2/c.php");

    Pour faire cette methode, il suffit de compter le nombre de / dans l'adresse par exemple (récupérée avec $_SERVER['REQUEST_URI'])

    Voila ! je pense que j'ai rien oublié ;o)

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 012
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 012
    Par défaut
    je fais comme fladnag : chemin relatif, et dans la page en cours j'ai une variable qui mémorise le chemin à la racine du site.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 14
    Par défaut
    Merci de ces réponses claires et complètes.
    Par contre j'ai encore une petite question :
    si j'utilise des chemins relatifs dans un fichier php, ils seront relatifs au dossier du fichier courant, c'est logique. Mais est-ce que ça fonctionne quand-même quand on fait un include de ce fichier?

    Je m'explique :
    par exemple j'ai l'arborescence suivante :

    + racine
    index.php
    ......+ css
    ............default.css
    ......+ php
    ............Skeleton.php
    ............+ pages
    ..................MainPage.php

    J'utilise un chemin relatif dans MainPage pour faire un include de Skeleton.php. Ca donne donc include("../Skeleton.php").

    Ensuite je fais dans index.php un include("./php/pages/MainPage.php").

    A ce moment là, est-ce que le chemin relatif qui est dans MainPage sera relatif au dossier de MainPage (dans ce cas ça marche), ou à celui de index?

    J'espère que c'est compréhensible. Parce que moi je me comprends mais j'ai un peu de mal à expliquer ma question.

  6. #6
    Membre Expert

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Par défaut
    l'adressage relatif peut etre assez compliqué... raison de plus pour le simplifier quand c'est possible.

    Donc deja, sache qu'en principe, tu n'a jamais a utiliser la syntaxe :

    ./dossier/dossier/fichier.php

    car elle est totalement identique a :

    dossier/dossier/fichier.php

    (Eventuellement ca pourrait permettre de différencier certains cas si tu utilises des dossiers "include", mais bon, y a pas de raison d'en avoir réellement besoin.)

    Donc pour ton probleme,
    si index.php inclus MainPage.php qui inclus lui meme Skeleton.php, non, ca ne fonctionnera pas si tu définit des $path dans chaque fichiers ;o).

    En effet, lorsqu'on fait un include, on demande a php de remplacer la ligne ou on ecrit "include" dans le fichier d'origine par le contenu du fichier inclus.
    Dès lors, l'interprétation de MainPage.php et Skeleton.php se fera alors au niveau de index.php...

    Je ne l'ai pas précisé dans mon message précédent en effet, mais la variable $path ne devrait etre définie QUE dans les pages php "principales" (ie : qui sont appellées depuis leur URL) et non dans les pages secondaires (ie : les pages incluses).

    Et si tu as des pages qui peuvent etres incluses ET qui sont des pages principales (en principe c'est rare, car une page principale contient un <html> et si elle est incluse ca veux dire que la page ou elle est incluse ne contient pas d'<html>) tu as encore une solution :
    au lieu de
    tu peux ecrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (!isset($path)) $path="../../";
    comme ca tu est sur qu'une précédente définition de $path ne sera pas "écrasée" par une nouvelle venant d'un fichier inclus.

    pour ton exemple, tu aura donc :
    * index.php contenant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $path="";
    include($path.'php/MainPage.php');
    * MainPage.php contenant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // pas de définition de $path ici car on est dans un fichier inclus !
    // donc en principe, $path est déjà défini dans un fichier parent
    include($path.'php/Skeleton.php');
    * Skeleton.php contenant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // pas de définition de $path ici car on est dans un fichier inclus !
    // donc en principe, $path est déjà défini dans un fichier parent
    echo "<link href='".$path."css/default.css' ...>";
    Note : Attention toutefois, si tu utilise ce code dans tes pages :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (!isset($path)) $path="../../";
    je te conseille de faire une verification sur $path... car si ton hebergeur ne travaille pas avec les tableaux $_GET et $_POST, il suffirais d'appeller une page secondaire directement avec ".php?path=http://www.sitepirate.com/" pour obtenir de très mechants résultats ;o)
    Pour eviter ca, tu peux faire un filtre juste apres qui va stopper l'execution de la page si $path contient "://" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (strpos($path, '://') !== FALSE) die("TENTATIVE DE PIRATAGE (j't'ais vu try again ;o)");

  7. #7
    Expert confirmé
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut
    pour ce qui est des include et des require
    je n'utilise plus qu'une seule façon de faire.

    ni absolu ni relatif
    comme dit plus haut le pb du chemin absolu est qu'il faut connaître à l'avance ce chemin jusqu'à la racine du site. or lorsqu'on développe sur une machine et qu'on héberge ailleurs ce n'est pas le même.
    de plus tous les hébergeur ne donne pas le chemin absolu il faut donc le récupérer

    le chemin relatif lui pose de problème du point de référence
    ./ n'est en effet pas une référence au répertoire du fichier contenant ce ./ mais le dossier du script demandé par l'utilisateur

    donc si j'ai le fichier
    inc1.php qui contient ./toto.php
    et
    dossier1/sousdossier1/script1.php qui fait un include de inc1.php
    et
    dossier2/script2.php qui fait aussi un include de inc1.php

    tout les deux font un include de toto.php
    mais pas le même
    dans le premier cas ce sera
    dossier1/sousdossier1/toto.php
    dans le deuxième se sera :
    dossier2/toto.php

    pour résoudre définitivement ces difficulté l'idée consiste à inclure par rapport au chemin absolu du fichier qui contient l'instruction inclue ou require.

    dirname(__FILE__)."/"
    est la référence au dossier contenant l'instruction.
    il ne peut donc y avoir d'erreur ni de path absolu ni de chemin relatif.

    A+JYT

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 14
    Par défaut
    Merci Fladnag.
    En fait, ce que j'en comprend, c'est que c'est quand même un peu le bordel! Perso mon domaine de prédilection c'est le java, donc je n'ai pas eu à me tracasser avec ce genre de pb : le programme que je lance est dans le classpath, donc tout ce qui est en dessous peut-être trouvé avec dossier1.dossier2.class.
    Là où ça me gène en php c'est que je veux juste faire des new MainPage(), qui lui même fait un extends Skeleton() etc... Et si je ne fais pas des include, il veut pas parce qu'il va pas regarder dans les sous dossiers. Est-ce qu'il n'y aurait pas un moyen de lui fixer un dossier racine et de ne plus en bouger, comme ça je lui donne comme path la racine du site, et puis dans tous mes fichiers je n'ai plus aucun pb! Dans la doc de php, ils mentionnent un include_path :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
     8.55.45 set_include_path()
    Modifie la valeur de la directive de configuration include_path
     
    [ Exemples avec set_include_path ]   PHP 4 >= 4.3.0, PHP 5
     
    Description
    string  set_include_path ( string   new_include_path )
     
    set_include_path modifie la valeur de la directive de configuration include_path , pour la durée du script en cours. Elle retourne l'ancienne valeur de include_path en cas de succès, et FALSE sinon.
     
    Exemple avec set_include_path
    <?php
    // Fonctionne depuis PHP 4.3.0
    set_include_path('/inc');
     
    // Fonctionne sur toutes les versions
    ini_set('include_path', '/inc');
    ?>
     
    Ajout dans le chemin d'inclusion
     
    En utilisant la constante PATH_SEPARATOR , il est possible d'étendre le chemin d'inclusion au vu du système.
     
    Dans cet exemple, nous ajoutons /usr/lib/pear à la fin de l'actuel include_path .
    <?php
    $path = '/usr/lib/pear';
    set_include_path(get_include_path() . PATH_SEPARATOR . $path);
    ?>
     
    Voir aussi ini_set , get_include_path , restore_include_path et include .
    Est-ce que c'est l'équivalent d'un classpath qui me permettrait de donner tous mes chemins relatifs à la racine?
    Et quand ils disent "pour la durée du script en cours", ça veut dire entre 2 balises <?php ... ?>, ou bien ça fonctionnerait tant que l'utilisateur n'a pas quitté le site?

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 14
    Par défaut
    sekaijin, ce qui me gêne dans ta solution, c'est qu'on doit toujours savoir dans quel répertoire on se trouve. Quand on a des include, et des extends, dans lesquels on a encore des include, ça commence à devenir compliqué!
    Ce qui me gêne le plus c'est de devoir faire des includes pour "rien" en fait. Parce que les includes que je fais, c'est uniquement pour que le fichier connaissent la classe qui est définie dans le fichier inclus pour qu'il puisse faire un new classe(). Il n'y aurait pas un équivalent du import de java en php. Quelque chose qui serve juste à savoir que des classes existent, sans pour autant copier l'intégralité du fichier?

    PS : sympa le site perso...vraiment perso ?

  10. #10
    Membre Expert

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Par défaut
    Si tu cherche un truc pour les classes, ca existe en... PHP 5 uniquement ;o)

    il s'agit de la methode magique __autoload

    http://fr.php.net/fr/__autoload

    Un exemple d'utilisation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    function __autoload($pClassName) {
    	$aListePath=array(
    			'',
    			'ctrl/',
    			'types/',
    			'constantes/',
    			'form/',
    			'composants',
    	);
    	foreach ($aListePath as $aPath) {
    		if (file_exists($aPath.$pClassName.'.class.php')) {
    			include_once $aPath.$pClassName.'.class.php';
    		}
    	}
    	if (!class_exists($pClassName, FALSE)) {
    		die("Impossible de trouver la classe $pClassName");
    	}
    }
    Sinon, il faut utiliser la solution du dossier "include" dont je parle plus haut. Ca correspond a mettre toutes tes classes dans un seul dossier qui sera inclus dans le path (classpath en java) automatiquement. Tout les fichiers seront donc accessibles.

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 14
    Par défaut
    Merci tout le monde pour ces informations. Ca m'a été très utile.
    Maintenant je vais y réfléchir et faire mon choix mais je pense que j'ai tout ce qu'il faut pour ça.

    A+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Arborescence de ses pages php : chemins relatifs ou absolus?
    Par Marc22 dans le forum Général Conception Web
    Réponses: 6
    Dernier message: 22/07/2010, 03h09
  2. Chemins relatifs et absolus sur hébergeur
    Par faamugol dans le forum Langage
    Réponses: 2
    Dernier message: 16/12/2008, 22h40
  3. include avec chemin relatif/chemin absolu
    Par doudoustephane dans le forum Langage
    Réponses: 8
    Dernier message: 31/05/2008, 00h57
  4. chemin relatif !=chemin absolu, mais pourquoi?
    Par azamharir dans le forum MFC
    Réponses: 4
    Dernier message: 11/04/2008, 21h27
  5. Réponses: 1
    Dernier message: 28/09/2006, 14h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo