parsing de REQUEST_URI pour un meilleur referencement

Eléphanteau du PHP | 10 Messages

27 oct. 2006, 14:23

:!: UPDATE: une version sans URL rewriting est possible aussi, si mod_rewrite ou les .htaccess ne sont pas disponibles chez votre hébergeur, voir fin de post

Enoncé du probleme:

Soit un site ou les url's seront du type http://www.monsite.be/site/section1/section2/section3
mais avec un nombre de sections pouvant aller de 0 (racine) à 3

J'ai fait de l'url rewrite pour que tout ce qui suit http://www/monsite.be/site/ soit redirigé sur une page index.php
pour se faire, dans le .htaccess du repertoire site, j'ai mis ceci:

Code : Tout sélectionner

<IfModule mod_rewrite.c> RewriteEngine On RewriteBase /site/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /site/index.php [L] </IfModule>

--> donc
avec une page de test index.php comme ceci:

<html> 
<head><body> 
<?php 
echo "<p>"; 
echo "PHP_SELF " . $_SERVER["PHP_SELF"]; 
echo "<br/>REQUEST_URI " . $_SERVER["REQUEST_URI"]; 
echo "<br/>QUERY_STRING " . $_SERVER["QUERY_STRING"]. "</p>"; 
?> 
</body> 
</html>

j'obtiens pour l'url
http://www.monsite.be/site/europe/belgique/mons
un résultat comme celui-ci:

Code : Tout sélectionner

monsite.be ... en construction page de test PHP_SELF /site/index.php REQUEST_URI /site/europe/belgique/mons QUERY_STRING

Maintenant, je voudrais parser la REQUEST_URI pour extraire les 3 variables dans un tableau qui contiendrait en index 'arg1' --> europe
'arg2' --> belgique et 'arg3" --> mons


Contraintes

1) nombre de sous-niveau variable (de 0 à 3)
2) il pourrait y avoir un / final après chaque niveau
3) il pourrait y avoir un .php après chaque niveau
( http://www.monsite.be/site/europe/belgique/mons.php )
4) Les variables doivent être suffisament générique, et pouvoir être utilisée partout ... donc, dans un tableau global, avec des index du genre arg1, arg2, arg3

Resolution
<html>
<head><body>monsite.be ... en construction new index
<?php

define('DEF_myBasePath','/news');

function RemoveExtensionOrGetVar($valeur)
{
	// Note our use of ===.  Simply == would not work as expected
	// because the position of 'a' is the 0th (first) character.
	$pos=strpos($valeur,'.');
	if ($pos !== false)
	{
	 $valeur=substr($valeur,0,$pos);
	}
	$pos=strpos($valeur,'?');
	if ($pos !== false)
	{
	 $valeur=substr($valeur,0,$pos);
	}
	return $valeur;
}

function RemoveBasePathFromRequestURI()
{

	//PHP_SELF = /news/index.php
	//REQUEST_URI = /news/europe/belgique/?blabla=truc&fdjdfs=dd
	//this function must return /europe/belgique?blabla=truc&fdjdfs=dd
	$beginPathToRemove="";
	if(!defined('DEF_myBasePath'))
	{
	   $pathindex= pathinfo($_SERVER["PHP_SELF"]);
	   $beginPathToRemove=$pathindex["dirname"];
	}
	else
	{
		$beginPathToRemove=DEF_myBasePath;
	}

	$pos=strpos($_SERVER["REQUEST_URI"],$beginPathToRemove);
	if ($pos === false)
	{
       echo "<br/>error, returning REQUEST_URI<br/>";
       return $_SERVER["REQUEST_URI"];
	}
	else
	{
       $returnstring=substr($_SERVER["REQUEST_URI"],strlen($beginPathToRemove));
       return $returnstring;
	}


}

function ExtractVarFromRequestUri()
{

   	$paramstring=RemoveBasePathFromRequestURI();
	$pathvar= preg_split("/\//i", $paramstring, -1, PREG_SPLIT_NO_EMPTY);
	foreach ($pathvar as $cle => $valeur)
	{
		$pathvar[$cle]=RemoveExtensionOrGetVar($valeur);
	}
	return $pathvar;
}

echo "<p>";
echo "PHP_SELF " . $_SERVER["PHP_SELF"];
echo "<br/>REQUEST_URI " . $_SERVER["REQUEST_URI"];
echo "<br/>QUERY_STRING " . $_SERVER["QUERY_STRING"];
echo "<br/>SCRIPT_FILENAME " . $_SERVER["SCRIPT_FILENAME"] . "</p>";

$pathvar3=ExtractVarFromRequestUri();
echo "<br/><br/>Fonction ExtractVar: <br/>";
print_r($pathvar3);
?>
</body>
</html>

Donc, une url du type
http://www.monsite.be/news/europe/belgique/bruxelles

sortira comme tableau de la fonction ExtractVarFromRequestUri:
Array ( [0] => europe [1] => belgique [2] => bruxelles )

http://www.monsite.be/news/europe/belgique/bruxelles/
http://www.monsite.be/news/europe/belgi ... xelles.php
http://www.monsite.be/news/europe/belgi ... true&dd=ee

retournerons le même tableau

Si la constante DEF_myBasePath est définie, on l'utilise comme base pour savoir à partir d'où extraire
ici:
define('DEF_myBasePath','/news');

si on avait fait
define('DEF_myBasePath','/');
--> On aurait eu un tableau de 4 éléments, avec news en premier

define('DEF_myBasePath','/news/europe');
--> nous aurait donné un tableau de 2 éléments avec belgique et bruxelles ...

Pas de define ... on se base sur le PHP_SELF ... qui vaut ici /news/index.php --> équivalent à define('DEF_myBasePath','/news');

et dans le cas d'une erreur du define
define('DEF_myBasePath','/truc');
on parse à partir de REQUEST_URI sans enlever le début, donc c'est équivalent à define('DEF_myBasePath','/');

====================================

:!: UPDATE
========
Si votre hébergeur n'accepte pas les .htaccess ou si le mod_rewrite n'est pas activé voici une autre méthode (merci petitchevalroux)
--> il suffit d'expliciter le index.php du repertoire de base dans l'url:

Ainsi on avait avant:
http://www.monsite.be/news/europe/belgique/bruxelles
et on avait comme sortie le tableau de la fonction ExtractVarFromRequestUri:
Array ( [0] => europe [1] => belgique [2] => bruxelles )

si on l'appelle http://www.monsite.be/news/index.php/europe/belgique/bruxelles
en enlevant le .htaccess ... ca fonctionne aussi, mais y a un élément en +

Array ([0] => index.php [1] => europe [2] => belgique [3] => bruxelles )

Pour avoir le même résultat qu'avant, il faut simplement changer le define('DEF_myBasePath','/news'); en define('DEF_myBasePath','/news/index.php');


Avez-vous des commentaires, améliorations, ou autre???

merci
Modifié en dernier par jimich le 29 oct. 2006, 20:50, modifié 1 fois.

Eléphanteau du PHP | 11 Messages

28 oct. 2006, 18:15

Personnellement je te conseil de travailler directement avec REQUEST_URI et de ne pas utilisé d'url rewriting. En effet vu que tu traites deja en php REQUEST_URI pour quoi ne pas faire un système du genre de Webinterdit ce qui t'eviteras de consommer des ressources par apache. Mais bon l'idée est bonne c'est juste une suggestion :wink:

Eléphanteau du PHP | 10 Messages

28 oct. 2006, 21:19

parce que j ai l impression que ca ne marchera pas ... dans le cas de webinterdit, je crois que index.php est un repertoire, reellement, pas un fichier ... et de l url rewriting travaille derrière pour mapper sur index.php\index.php

WordPress fait la même chose ...

avec mon code, suffit de remplacer news\ par index.php\

mais je me trompe peut-être ...

Eléphanteau du PHP | 11 Messages

29 oct. 2006, 11:03

Je t'assure que le fichier index.php n'est pas un répertoire sur webinterdit. Pour tout t'avouer je débute aussi dans ce genre d'utilsation de request_uri mais test ce petit bout de code qui te permet d'illustrer mes propos.

Code : Tout sélectionner

<?php $explode=explode('/',$_SERVER['REQUEST_URI']); $section1=isset($explode[2])?$explode[2]:''; $section2=isset($explode[3])?$explode[3]:''; $section3=isset($explode[4])?$explode[4]:''; echo "Section 1 $section1<br/>"; echo "Section 2 $section2<br/>"; echo "Section 3 $section3<br/>"; ?>
Pour voir ce que ça donne test http://petitchevalroux.net/url_rewritin ... /section3/
Ensuite à toi de faire ce qui te plait mais sache que ça fonctionne
:wink:

Eléphanteau du PHP | 10 Messages

29 oct. 2006, 19:25

je ne pensais pas qu'il était possible de faire ça, je pensais que apache, sans htaccess, allait forcément aller chercher un fichier index.php dans http://petitchevalroux.net/url_rewritin ... /section3/

et pas prendre le url_rewriting.php ...

intéressant ...

et pas de probleme pour le tableau $_GET?

Eléphanteau du PHP | 11 Messages

29 oct. 2006, 20:31

Euh a vrai dire si tu fais de l'url rewriting c'est justement pour ne pas avoir de variable GET. Mais bon dans ce cas précis ça fonctionne :D
http://petitchevalroux.net/url_rewritin ... ?toto=toto
j'ai juste ajouter

Code : Tout sélectionner

var_dump($_GET);
pour voir si ça passait et oui en effet ça passe.
Aprés comme je viens de te le dire je vois pas l'interet de faire de l'url rewriting et d'utiliser get mais bon la ce n'est plus mon problème et c'est une vision personnelle donc No Comment :wink:.

Eléphanteau du PHP | 10 Messages

29 oct. 2006, 20:43

Moi, je vois bien mon intérêt :-)

Je dois faire un site complet pour un client, avec module de news, annuaires, pages statiques, pages privées, dépots de documents ...

bref, ce système d'url rewriting est là de manière globale, pour la gestion globale du site ... maintenant, certains composants (par exemple une gallerie de photo venant d'un site externe POURRAIT utiliser des variables GET ... je n'en sais rien ;-)

J'ai testé mon script, en effet, ca marche aussi si on appelle

http://www.monsite.be/news/europe/belgique/bruxelles
on avait comme sortie le tableau de la fonction ExtractVarFromRequestUri:
Array ( [0] => europe [1] => belgique [2] => bruxelles )

si on l'appelle http://www.monsite.be/news/index.php/eu ... /bruxelles
en enlevant le .htaccess ... on a donc vu que ca fonctionnait aussi, mais y a un élément en +

Array ([0] => index.php [1] => europe [2] => belgique [3] => bruxelles )

Pour avoir le même résultat qu'avant, il faut simplement changer le define('DEF_myBasePath','/news'); en define('DEF_myBasePath','/news/index.php');

et ca fonctionne ...

Eléphanteau du PHP | 10 Messages

29 oct. 2006, 20:51

merci petitchevalroux, je viens de faire un update dans mon post pour ta solution...

Eléphanteau du PHP | 11 Messages

29 oct. 2006, 20:53

Alors si ça fonctionne tant mieux. Content d'avoir pus t'aider :D :D