Page 1 sur 1

Include et chemin absolu

Posté : 09 févr. 2007, 07:40
par Theri le Vorace
Voilà, je viens de passer 2h, j'ai les yeux qui piquent et mon code ne marche toujours pas..

Avant de me tirer une balle, je prie la communauté de bien vouloir m'expliquer ce qui m'arrive..

J'ai 2 fichiers : include.php et include2.php
Je veux inclure include2.php à partir du premier avec un chemin absolu (pour pouvoir plus tard me balader dans mon arborescence et que mon menu en include() pointe bien vers les liens qui m'intéressent, je ne peux pas faire du relatif)

De plus, feignasse et disposant d'une arborescence différente selon mon serveur local et mon distant, je détecte automatiquement le serveur.

La fonction include du manuel php
Configurer le php.ini

include.php

Code : Tout sélectionner

<?php ## <Head> // Reconnaissance automatique de la racine du site : Locale/Distante $racine_site = $_SERVER['HTTP_HOST']; if($racine_site == "localhost"){$racine_site = "http://localhost/sitelocal/";} else{$racine_site = "http://sitedistant/";} // Creation de la constante RACINE_SITE define ('RACINE_SITE', $racine_site); include "http://localhost/sitelocal/include2.php"; $fichier = RACINE_SITE."include2.php"; include $fichier; //Fonction test() commentée car sinon plantage : "Call to undefined function" // test(); $fichier = "include2.php"; include $fichier; // Fonction test() non commentée car pas de plantage, affiche "test" test(); ?>
include2.php

Code : Tout sélectionner

<?php echo "test sans fonction<br>"; function test() { echo "test<br>"; } ?>
Bref, c'est pas qu'il ne trouve pas le fichier ou que l'url est mauvaise, c'est juste qu'il semble ne pas interpréter la fonction quand le chemin est absolu (puisqu'il affiche bien un "test sans fonction" par appel du fichier !).
test sans fonction
test sans fonction
test sans fonction
test
J'ai vérifié, mon fichier php.ini a bien comme valeur :
allow_url_fopen = On

Pas contre, rien dans mon php.ini concernant "allow_url_include"

Alors, qui se dévoue pour m'aider ? :P

Posté : 09 févr. 2007, 09:55
par Dominic
remarques en passant
- une fonction est destinée à traiter des données passées en paramètres
dans ton cas je ne vois pas bien l'objectif car il n'y a pas de paramètres

- la réponse est dans ta question concernant le message d'erreur

/Fonction test() commentée car sinon plantage : "Call to undefined function"
// test();

tu a écrit Fonction test() au lieu de function test()

Posté : 09 févr. 2007, 16:15
par Theri le Vorace
Merci de ta réponse Dominic

Disons qu'à la base je voudrais faire ça avec une fonction un peu plus développée (mais pas encore finie) avec des paramètres
<?php

session_start();
$titre = "";
$refresh = $javascript = false;
$vitesse_refresh = 0;
$tab_scripts = array();

// function Creer_Haut_Page($titre, $refresh, $vitesse_refresh, $javascript, $tab_scripts)
// [$titre] correspond au <title>
// [$refresh] est la presence ou non d'un autorefresh de la page toutes les [$vitesse_refresh] secondes
// [$javascript] est la presence ou non de scripts javascripts dont la liste est dans [$tab_scripts]

function Creer_Haut_Page($titre, $refresh, $vitesse_refresh, $javascript, $tab_scripts)
{
echo "<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='fr' >";
echo "<head>";
echo "<title>Arachnapack : $titre</title>";
echo "<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' />";
echo "<link rel='stylesheet' media='screen' type='text/css' title='Essai' href='css/essai.css' />";

if($refresh)
{
echo "<META HTTP-EQUIV='Refresh' CONTENT='$vitesse_refresh'> \n";
}
if($javascript)
{
echo"<SCRIPT src='../javascripts/validation_form.js'></SCRIPT>";
}

echo "</head>";
echo "<body>";
}
Seulement ça plante parce que bien qu'il charge le fichier , il ne "charge" pas la fonction... J'ai donc créé un include "bidon" pour tester avec le chemin absolu.

Pour le premier fichier, tu n'as pas compris, même si tu as bien lu.
Ce "fonction" était là juste pour vous signaler qu'à cet endroit, si j'appelle test, comme elle n'est pas chargée elle plante, MEME si le "echo 'test sans fonction'" est bien appliqué !!

Par contre, avec un include en chemin relatif, le fichier est lu ET la fonction interprétée (chargée).

C'est ça qui m'étonne, pour moi :
- le fichier est trouvé ;
- le code qui n'est pas dans les fonctions est appliqué ;
- le code qui est dans les fonctions N'EST PAS appliqué !!!

J'aurai jamais cru ça possible.. Restart PC, serveur, ... Rien à faire !
Note : je bosse en PHP5

Posté : 09 févr. 2007, 16:32
par Dominic
je pense à un truc tout bête
dans ton fichier contenant le chemin absolu il y a fatalement
2 slashes // ce qui fait que ce qui suit est pris comme commentaire et donc ignoré
a tout hasard mets des \devant pour voir
Si c'est ça le pb tu es à l'amende d'une tournée générale

Posté : 09 févr. 2007, 16:51
par Theri le Vorace
Oui, ta solution m'a semblé très logique et intéressante, mais je viens de regarder la doc include et eux ne se gênent pas avec ça..
Note : puisque le echo "test sans fonction" est bien appliqué, le problème ne vient pas de cela..

Allez, la tournée sans doute au prochain post ! :P

Posté : 09 févr. 2007, 17:02
par Dominic
juste une petite dernière après je jettes l'éponge
c'est bien l'adresse qui est directement inscrite dans le fichier include
si c'est le cas dans ton include
tu mets $fichier="httt://etc.."
et la 1ère ligne de ta function GLOBALS $fichier;

alors tournée ou pas ?

Posté : 09 févr. 2007, 17:11
par Theri le Vorace
Ben.. pas de tournée pour l'instant.

J'ai beau relire, je ne comprend pas ce que tu veux me faire faire..

Pour info, je viens de tester en ligne et cela ne dépend pas de ma configuration, ou alors Free et moi on a le même problème...

edit : je viens de lire un peu sur les variables globales. Mais là, puisque la variable $fichier qui contient mon URL est dans le script où elle est définie, elle n'a pas besoin d'être GLOBALE, locale suffit, non ?

Merci en tout cas de ton aide pour ce problème !

Je pensais que include() et require() ne géraient pas le HTTP://
comme vu sur certains sites, mais puisque ce n'est plus le cas maintenant ça devrait le faire ! :(

Vous avez ce genre de comportement aussi chez vous ? Et/ou un moyen de contourner ce problème ?

Posté : 09 févr. 2007, 21:21
par titerm
un chemin absolu, c'est un chemin qui par de la racine soit /

la racine, elle peut etre celle du disque ou celle de ton serveur http.

si tu fais include ('/pathtokkchose') tu fais référence a la racine de ton disque dur.
Si tu fais include ('http://pathtokkchose') tu fais référence a la racine du serveur http.

Ceci étant dis, quand tu fais includes ss le http, tu le fais en local, et donc le php n'est pas interprété, tu peux donc lire du php et définir des fonctions.

Si tu fais des includes en utilisant http, tu fais évaluer le script include par ton serveur web. Tu inclus donc uniquement le résultat de l'évaluation et en aucun cas, tu ne pourras définir une fonction.

Donc si tu veux faire des includes en absolu afin de définir des fonctions, ne met pas de http devant.

Posté : 09 févr. 2007, 21:28
par Theri le Vorace
Cas 1 : si tu fais include ('/pathtokkchose') tu fais référence a la racine de ton disque dur.

Ceci étant dis, quand tu fais includes ss le http, tu le fais en local, et donc le php n'est pas interprété, (ben si justement, non ?) tu peux donc lire du php et définir des fonctions.

Cas 2 : Si tu fais include ('http://pathtokkchose') tu fais référence a la racine du serveur http.
Si tu fais des includes en utilisant http, tu fais évaluer le script include par ton serveur web. Tu inclus donc uniquement le résultat de l'évaluation et en aucun cas, tu ne pourras définir une fonction.

Donc si tu veux faire des includes en absolu afin de définir des fonctions, ne met pas de http devant.
Bon, je vais essayer en partant de /, le problème, c'est que mon 'menu.php' est situe au même niveau qu''index.php', par conséquent dès que je descend dans un sous-dossier (/outils) pour afficher une page dans laquelle j'inclus le menu.php de la racine, les liens se font vers un hypothétique index.php5 du sous-dossier et pas de la racine ! :S

Posté : 10 févr. 2007, 15:16
par titerm
Ceci étant dis, quand tu fais includes ss le http, tu le fais en local, et donc le php n'est pas interprété, (ben si justement, non ?) tu peux donc lire du php et définir des fonctions.
Je ne suis peut etre pas clair...
Il n'est pas interprété mais inclu comme si le contenu de l'include avait été dans le fichier meme. A l'opposé, un include avec un http revient exactement au meme que de tapper http://includemachein.php dans ton browser. Tu vois uniquement le résultat et en aucun cas le php.

Dans ton cas, il y a 2 solutions qui correspondent a ton problème.

Solution 1: tu met a jours la variable include_path avec le chemin vers le répertoire qui contient les fichiers que tu souhaites inclure de n'importe ou. Quand tu fera un include, il le fera en prenant en compte l'include path. tu n'as donc plus donner de path. Cela se fait soit dans le php.ini, soit dans le httpd.conf, soit dans les vhosts ou encore via la fonction set_include_path().

Solution 2: Tu définis un alias au niveau de ton vhost (ce sont des termes lié à apache, à adapter sur d'autre serveur http.
Défini un alias genre
alias /lib /path_absolu_to_mylib_from racine_hdd
Ensuite, quand tu fera http://serveur/lib tu fera automatiquement référence au chemin indiqué. C'est apache qui fera la conversion.
C'est l'équivalent d'un lien symbolique sous unix si ca te parle.
ln -s /path_absolu_to_mylib_from racine_hdd /path_to_racine_www/lib

Posté : 10 févr. 2007, 19:39
par Theri le Vorace
Je ne suis peut etre pas clair...
Il n'est pas interprété mais inclu comme si le contenu de l'include avait été dans le fichier meme. A l'opposé, un include avec un http revient exactement au meme que de tapper http://includemachein.php dans ton browser. Tu vois uniquement le résultat et en aucun cas le php.
Ben si au début j'ai pas bien compris, reformulé comme ça tout est bon !
Il me semble à présent logique que l'include en "http" ne renvoie pas la commande echo "test sans fonction" mais uniquement le "test sans fonction" puisque le code a déjà été exécuté et que par conséquent il ne reste "plus rien" pour mon propre serveur..
Dans ton cas, il y a 2 solutions qui correspondent a ton problème.
Solution 1: OK, je vais tâcher de tester ça. Note : il faut que je trouve maintenant où se fait cette déclaration, si je la met dans un fichier à inclure, encore faut-il qu'il soit inclus lui-même ! :lol:

Solution 2: Ne sachant trop si je peux redéfinir ça chez free, je vais m'y intéresser (plus tard).

Posté : 10 févr. 2007, 20:10
par sadeq
Bon, je vais essayer en partant de /, le problème, c'est que mon 'menu.php' est situe au même niveau qu''index.php', par conséquent dès que je descend dans un sous-dossier (/outils) pour afficher une page dans laquelle j'inclus le menu.php de la racine, les liens se font vers un hypothétique index.php5 du sous-dossier et pas de la racine ! :S
Le principe simple est que les pages qui se trouvent dans les sous-dossiers d'une racine doivent appeller les pages de cette racine avec un chemin relatif générique :
"." qui représente la racine absolue du site
ou ".." qui représente la racine du premier parent proche.

Exemple:
  • Racine du site (.)
    -------------------
    |
    |___ page1.php { include "pageX.php"; } appel à pageX de la même racine
    |
    |___ pageX.php
    |
    |___ Dossier1
    ____|
    ____|___ Page1.php { include "./pageX.php"; } appel à pageX de la racine du site
    ____|
    ____|___ PageX.php
    ____|
    ____|___ Dossier2
    ________|
    ________|___ Page1.php { include "./pageX.php" } appel à pageX de la racine du site
    ________|
    ________|___ Page2.php { include "../pageX.php" } appel à pageX du dossier précédent (Dossier2)

Posté : 10 févr. 2007, 22:41
par titerm
"." qui représente la racine absolue du site
Je ne suis pas vraiment daccord avec cette affirmation.
. represente le dossier courant, en aucun cas la racine du site.

La seule particularité totalement spécifique a php concernant le . est celle ci :
. prend dabord la valeur du chemin courant, celle du répertoire d'appel du premier script.
Puis ensuite, il prend la valeur du script courant.

Ce mécanisme un peu bizarre est très bien expliqué dans la doc d'include.
Les fichiers à inclure sont d'abord recherchés dans le dossier désigné par include_path, relativement au dossier courant, puis dans include_path, relativement au dossier de travail du script. Par exemple, si include_path est ., que le dossier de travail est /www/, et que vous incluez le fichier include/a.php et qu'il y a une instruction include "b.php" dans ce fichier, alors b.php est d'abord recherché dans /www/, puis dans /www/include/.

Posté : 11 févr. 2007, 04:22
par Theri le Vorace
Bon, le set_include_path ça défonce, et je n'ai eu qu'à remanier très légèrement la disposition des fichiers dans mon arborescence : menu.php5 et bas.html (pour le bas de page oui oui c'est ça) sont dans le dossier include.

Un p'tit "set_include_path" sur index.php5 et authentification(deconnexion).php5 (puisqu'on est forcé y passer) et c'est calé pour tout le site !! :shock: :D

Je suis super heureux d'appuyer sur "résolu".. Mon premier !
--------
@ titherm : exact !

D'où l'arrivée de mon index.php5 du sous-dossier et pas de la racine.

Mais je pense que j'ai merdouillé avec mon apache, j'ai comme dossier racine devPHP et sous-dossier le site sur lequel je bosse.

Y'aurait sans doute moyen de faire en sorte que les liens marchent en ligne comme en local, en attendant ça bidouille, j'avais un besoin urgent de sécuriser mon site (merci beaucoup au passage pour l'article concernant la protection contre les spammeurs des formulaires de mail, rien à voir.. :oops: )
---
Bon, vous n'y échapperez pas, tournée générale ! :boire9: Et merci à vos cortex, messieurs ! :agenouille: