0/5 (21 avis)
Vue 28 575 fois - Téléchargée 846 fois
<?php ///////////////////////////////////////////////////////////////////////////// // Nom : PHPrewrite // // Auteur : Shisui // // Version : 1.2 // // Description : Remplacement PHP du mod rewrite d'Apache, permettant une // redirection d'URL meme sur les serveurs n'ayant pas activé // ce module. // // Notes : C'est un code que j'ai trouvé plusieurs fois sur Internet, // mais qui à l'origine était long à mettre en place (une // condition par itération). // Cette version ci est donc plus perfectionnée grace à sa // compatibilité avec les expressions du mod rewrite original. // // Installation : L'installation est simple, il suffit de placer toutes les // régles en cohésion avec le mod original dans le fichier // spécifié dans la configuration ci dessous. De configurer // celle ci,puis de mettre dans un .htaccess à la racine // de votre site : // ErrorDocument 404 /urlrewriting.php // // Changelog : 1.2 - Utilisation d'une classe sur les conseils de XaF // Pourquoi une classe ? Tout simplement pour améliorer // (un peu) la rapidité et pour que le code soit moins // "brouillon", il est mieux structuré et ainsi plus // facile à comprendre, et donc à modifier, adapter. // - Mise en place du systéme de casse // - Support de nouveaux flags : // . QSA : "Query String Append" // // 1.1 - Premiére version de ce script // 1.0 - Version de base trouvée sur internet // // A faire : - Compréhension des RewriteCond (30%) // - Flags : // . QSA : "Query String Append", ajouter // les paramétres demandés à l'url source // vers l'url de sortie. // - Debug (Ca restera toujours à faire :]) // ////////////////////////////////////////////////////////////////////////////// error_reporting(E_ALL); // Affichage de toutes les erreurs class PHPRewrite { // Initialisation des variables utilisées dans la classe var $config; var $erreur; var $UrlReq; var $ligne; var $RespectCasse; var $LignesTot; var $url_sortie; var $i; var $QSA; var $Chainage; function PHPRewrite() { ///////////////////////////////// //// Configuration du script //// ///////////////////////////////// $this->config['FichierConf'] = ".rewritemod"; // Nom du fichier ou se trouvent les directives à appliquer ([Nom]) $this->config['ForcerNonVerif'] = FALSE; // Focer la non-vérification de la ligne "RewriteEngine On" (TRUE|FALSE) $this->config['LangueDefaut'] = 'en'; // Langue utilisée pour les erreurs, voir ci dessous //// Fin de la configuration //// //// Configuration des Erreurs //// $this->erreur['header']['301'] = "HTTP/1.0 301 Permanently Moved"; $this->erreur['header']['302'] = "HTTP/1.0 302 Temporarily Moved"; $this->erreur['header']['404'] = "HTTP/1.0 404 Not Found"; // Header à envoyer $this->erreur['404']['en']['titre'] = "Not Found"; // Titre de l'erreur $this->erreur['404']['en']['expli'] = "The requested URL %u% was not found on this server"; // Description, %u% = url demandée $this->erreur['header']['403'] = "HTTP/1.0 403 Forbidden"; $this->erreur['403']['en']['titre'] = "Forbidden"; $this->erreur['403']['en']['expli'] = "You don't have permission to access %u% on this server"; $this->erreur['header']['410'] = "HTTP/1.0 410 Gone"; $this->erreur['410']['en']['titre'] = "Gone"; $this->erreur['410']['en']['expli'] = "The requested resource<br />%u%<br />is no longer available on this server and there is no forwarding address. Please remove all references to this resource."; ///// Fin de la configuration ///// $this->Chainage = TRUE; $this->RespectCasse = TRUE; $this->UrlReq = substr_replace($_SERVER['REQUEST_URI'], '', 0, 1); } function OuvrirFichier() { if (!$this->config['ForcerNonVerif'] && !$this->mod_active()) { $this->erreur(); exit; } else { $handle = fopen($this->config['FichierConf'],"r"); $texte = fread($handle, filesize($this->config['FichierConf'])); $this->ligne = preg_split("/\n/", $texte); $this->LignesTot = count($this->ligne) - 1; } } function RedirectUrl() { $i = 0; while ($this->i <= $this->LignesTot) { $this->ligne[$this->i] = (!empty($this->ligne[$this->i]))?$this->ligne[$this->i]:"#"; if (substr($this->ligne[$this->i],0,1) == "#") { if ($this->i == $this->LignesTot) { $this->erreur(); exit; } $this->i++; } else { $this->getUrlSortie($this->i); if ($this->url_sortie) { header("HTTP/1.0 200 OK"); if (!$this->QSA) { $_GET = ""; } $_GET = $this->getPageVars($this->url_sortie); include($this->getPageVars($this->url_sortie,"page")); exit; } else { if ($this->i == $this->LignesTot) { $this->erreur(); exit; } } $this->i++; } } } function getUrlSortie($L) { $regle = (!empty($this->ligne[$L]))?$this->regle_info($this->ligne[$L]):FALSE; if ($regle) { if ((!$this->RespectCasse) || ($this->flagPresent("NC",$regle["FLAGS"]))) $Correspondance = eregi($regle['MASQUEE'], $this->UrlReq); else $Correspondance = ereg($regle['MASQUEE'], $this->UrlReq); if ($Correspondance) { if ($this->Chainage && ($this->flagPresent("C",$regle["FLAGS"]))) { $this->url_sortie = $this->url_rewrite($this->UrlReq,$regle["MASQUEE"],$regle["MASQUES"]); $this->Chainage = TRUE; $this->UrlReq = $this->url_sortie; $this->url_sortie = FALSE; } else { if ($this->flagPresent("F",$regle["FLAGS"])) { $this->erreur("403"); } elseif ($this->flagPresent("G",$regle["FLAGS"])) { $this->erreur("410"); } elseif ($this->flagPresent("^R(=:alnum:{3})?$",$regle["FLAGS"])) { if ($this->flagPresent("^R$",$regle["FLAGS"])) { $this->erreur("302","en",$this->url_rewrite($this->UrlReq,$regle['MASQUEE'],$regle['MASQUES'])); } else { ereg("^R(=:alnum:{3})?$",$this->flagPresent("^R(=:alnum:{3})?$",$regle["FLAGS"]),$res); $res = substr_replace($res[1],'',0,1); $this->erreur($res,"en",$this->url_rewrite($this->UrlReq,$regle['MASQUEE'],$regle['MASQUES'])); } } else { $this->url_sortie = $this->url_rewrite($this->UrlReq,$regle["MASQUEE"],$regle["MASQUES"]); if ($this->flagPresent("^N$",$regle["FLAGS"])) { $this->UrlReq = $this->url_sortie; $this->url_sortie = FALSE; $this->i = -1; } elseif ($this->flagPresent("^C$",$regle["FLAGS"])) { $this->Chainage = TRUE; $this->UrlReq = $this->url_sortie; $this->url_sortie = FALSE; } elseif ($this->flagPresent("^QSA$",$regle["FLAGS"])) { $this->QSA = TRUE; } } } } else $this->url_sortie =FALSE; } else $this->url_sortie = FALSE; } function erreur($num = "404",$langue,$redir = FALSE) { //D: Fonction servant à afficher un message d'erreur if(!isset($langue)) $langue = $this->config['LangueDefaut']; if (!isset($this->erreur['header'][$num])) { exit("Titre ou description de code introuvable pour l'erreur ou la langue spécifiée"); } else { header($this->erreur['header'][$num]); if (!$redir) { echo '<html><head><title>'.$this->erreur[$num][$langue]['titre'].'</title></head>'; echo '<body><h1>'.$this->erreur[$num][$langue]['titre'].'</h1>'.str_replace("%u%",$_SERVER['REQUEST_URI'],$this->erreur[$num][$langue]['expli']); echo "<p><hr><address>".$_SERVER['SERVER_SIGNATURE']."</address></body></html>"; exit; } else { header('Location: '.$redir); exit; } } } function mod_active() { //D: Fonction servant à savoir si Rewrite engine On est présent dans le fichier de régles //R: (TRUE|FALSE) $handle = fopen($this->config['FichierConf'],"r"); // ouverture du fichier $fichier = fread($handle, filesize($this->config['FichierConf'])); // lecture de son contenu fclose ($handle); // fermeture du fichier if (eregi("RewriteEngine On",$fichier)) { // si le ligne se trouve dans le fichier return true; // on retourne TRUE } else { return false; // sinon FALSE :) } } function regle_info($ligneregle) { //D: Fonction servant à retourner les informations d'une régle sous forme de tableau //R: Masque d'entrée (MASQUEE) Masque de sortie (MASQUES) et les Flags (Drapeaux) avec leur nombre $regle = str_replace("RewriteRule", '',$ligneregle); // On supprime le "RewriteRule" du début de la ligne $regle = split(" +",trim($regle)); // On sépare les différentes itérations if (count($regle) != 3) { return FALSE; } $flags = str_replace("]","",str_replace("[","",$regle[2])); // On enléve les [ et ] entourants les flags $flags = explode(",",$flags); // On les séparent array_unshift($flags, count($flags)); // Et on ajoute le nombre de flags en position 0 return array("MASQUEE" => $regle[0], "MASQUES" => $regle[1], "FLAGS" => $flags); // Et on retourne le tableau de valeurs :) } function url_rewrite($page,$masqueE,$masqueS) { // D: Fonction qui retourne la page réécrite en fonction de la page spécifiée et // du masque d'entrée ou FALSE si ils ne correspondent pas // R: Page réécrite ou FALSE // Exemple de masque d'entrée : ^page-([0-9]+)-([0-9]+)\.html$ // Exemple de masque de sortie : article.php?numero=$1&page=$2 // Exemple de page demandée : article-8125-2.html // Page réécrite : article.php?numero=8125&page=2 if (ereg($masqueE, $page, $vars)) { // On regarde si le masque d'entrée et la page correspondent $urlrewrite = $masqueS; // Si oui on définit $urlrewrite $i = 0; // on initialise $i while ($i <= count($vars) - 1) { // et on fait une boucle, tant que $i sera inférieur au nombre de variables $urlrewrite = str_replace("$".$i, $vars[$i], $urlrewrite); // on remplace la variable "$1" par exemple par sa correspondance $vars[1] $i++; // on refait un tour ... } return $urlrewrite; // on retourne l'url réécrite } else { // si le masque et la page ne correspondent pas ... return FALSE; // on retourne FALSE :) } } function getPageVars($page,$mode = "getvars") { // D: Fonction qui retourne un tableau de valeur des variables passées à une page // R: Tableau de valeur de type Array( [VAR] => valeur ) // Exemple : $_GET = get_page_vars("index.php?page=news&id=5"); // Retournera le tableau $_GET tel que : // $_GET['page'] == "news" // et $_GET['id'} == "5" // $page = get_page_vars("index.php?page=news&id=5","page"); // Retournera "index.php" if ($mode == "getvars") { if (ereg("(.*)\?(.*)",$page,$vars)) { // On vérifie que l'adresse posséde des variables (page?variables) // et on récupére le bloc de variables $get = $vars[2]; //on définit $get comme le bloc de variable if (ereg("(.*)\&(.*)",$get,$vars)) { // on regarde si plusieurs vars sont définies (blocvar1&blocvar2) array_shift($vars); // on supprime le $vars[0] qui correspond à $get foreach ($vars as $val) { // pour chaque bloc de variables if (ereg("(.*)\=(.*)",$val,$var)) { // on regarde si ca correspond bien à une déf de var (var1=valeur) $GETVARS[$var[1]] = $var[2]; // on définit le tableau } } return $GETVARS; // que l'on retourne ... } elseif (ereg("(.*)\=(.*)",$get,$var)) { // il n'y a pas plusieurs blocs de var, donc on regarde si il y en a au moins un $GETVARS[$var[1]] = $var[2]; // on définit l'unique variable return $GETVARS; // on retourne le tableau } else { // la page passée n'a pas de variables correctes en parametres return FALSE; // on retourne FALSE } } else { // la page passée n'a pas de variables en paramétres return FALSE; // on retourne FALSE } } else { if (ereg("(.*)\?(.*)",$page,$vars)) { // Si la page est bien consituée de la forme url?vars return $vars[1]; // On retourne juste la page } else { return $page; // Sinon on retourne la page passée en paramétres } } } function flagPresent($flag,$array) { //D: Fonction servant à savoir si le flag $flag est précisé dans le tableau $array retourné par regle_info['FLAGS'] //R: (FALSE|flag) if (!is_array($array)) { return FALSE; } else { foreach ($array as $v => $k) { if (ereg($flag, $k)) { return $k; } } } } function BaseServeur($uri) { //D: Fonction qui retourne la base d'une URI passée en paramétre //R: (uri_base) if (substr($uri,0,7) == "http://") { // si l'url posséde le http:// du début $url = split("/",$uri); // on coupe $url tout les / $url = $url[2]; // on prend le troisiéme } else { $url = split("/",$uri); $url = $url[0]; } return "http://".$url; // on retourne l'url de base } } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Appel de la classe ! // Sans ca tout ce qu'il y a au dessus ne sert plus à rien :) /////////////////////////////////////////////////////////////////////// $phpR = new PHPRewrite(); // Création de la classe $phpR->OuvrirFichier(); // On ouvre le fichier et on voit si il est conforme à la config. $phpR->RedirectUrl(); // Et hop, on redirige ... ?>
18 août 2005 à 14:20
19 août 2005 à 00:26
"Ca n'est pas vraiment un bug mais le serveur de Free affiche des alertes et notices lorsque la page ne correspond à aucun masque, d'ou la présence de la ligne error_reporting(E_ALL ^ E_WARNING ^ E_NOTICE);"
à toi de le gérer pour que ça ne fasse pas ça, mets l'error_reporting à E_ALL
Sinon très bonne source, j'aime bien le principe et ça change du reste. 10/10 :-)
a +
19 août 2005 à 10:08
Quant aux erreurs c'est réglé, j'ai rajouté quelques conditions et changé quelques petites choses (notemment au niveau des boucles et des fonctions) ce qui fait que plus aucune erreur n'apparait avec l'error_reporting à E_ALL :)
Voilà les changement :
Dans la fonction regle_info,
if (count($regle) != 3) {
return FALSE;
}
a été rajouté pour éviter le passage de string qui ne sont pas des régles (condition minime mais ca évite des erreurs :) )
Dans la fonction url_rewrite :
while ($i <= 9) {
a été changé en while ($i <= count($vars) - 1) { (erreur de ma part :/) pour eviter les "Offset X undefined"
Dans le script, la boucle for : for ($i=0; $i <= $lignes_tot; $i++) a été changée (le script prenait une ligne en trop et ratait la premiére)
Voilà :) Si quelqu'un trouive d'autre bug qu'il le signale :)
Sinon je suis en train de passer le script en class, on m'a dit que ca accélérerait le script :)
19 août 2005 à 10:44
définit ton count() avant
$nb=count($vars);
while ($i < $nb)
19 août 2005 à 11:06
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.