J'ai déplacé un WordPress installation dans un nouveau dossier sur un serveur Windows / IIS . J'installe des redirections 301 en PHP, mais cela ne semble pas fonctionner. Les URL de mes messages ont le format suivant:
http:://www.example.com/OLD_FOLDER/index.php/post-title/
Je n'arrive pas à comprendre comment récupérer la partie /post-title/
de l'URL.
$_SERVER["REQUEST_URI"]
- que tout le monde semble recommander - renvoie une chaîne vide. $_SERVER["PHP_SELF"]
ne fait que renvoyer index.php
. Pourquoi est-ce et comment puis-je le réparer?
Peut-être, parce que vous êtes sous IIS,
$_SERVER['PATH_INFO']
est ce que vous voulez, en fonction des URL que vous avez utilisées pour expliquer.
Pour Apache, vous utiliseriez $_SERVER['REQUEST_URI']
.
$pageURL = (@$_SERVER["HTTPS"] == "on") ? "https://" : "http://";
if ($_SERVER["SERVER_PORT"] != "80")
{
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
}
else
{
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $pageURL;
'http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']
Vous pouvez également utiliser HTTP_Host
au lieu de SERVER_NAME
comme l'a commenté Herman. Voir cette question connexe pour une discussion complète. En bref, vous êtes probablement d'accord pour utiliser l'un ou l'autre. Voici la version "Host":
'http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['HTTP_Host'].$_SERVER['REQUEST_URI']
En règle générale, je place ServerName
dans VirtualHost
parce que je veux que that soit la forme canonical du site Web. Le $_SERVER['HTTP_Host']
est défini en fonction des en-têtes de la demande. Si le serveur répond à tout/tous les noms de domaine à cette adresse IP, un utilisateur pourrait usurper l'en-tête, ou pire encore, quelqu'un pourrait pointer un enregistrement DNS vers votre adresse IP et votre serveur/site Web servirait alors un site Web avec liens construits sur une URL incorrecte. Si vous utilisez cette dernière méthode, vous devez également configurer votre vhost
ou configurer une règle .htaccess
pour appliquer le domaine que vous souhaitez diffuser, par exemple:
RewriteEngine On
RewriteCond %{HTTP_Host} !(^stackoverflow.com*)$
RewriteRule (.*) https://stackoverflow.com/$1 [R=301,L]
#sometimes u may need to omit this slash ^ depending on your server
J'espère que cela pourra aider. Le véritable intérêt de cette réponse était simplement de fournir la première ligne de code aux personnes qui se sont retrouvées ici en cherchant un moyen d'obtenir l'URL complète avec Apache :)
$_SERVER['REQUEST_URI']
ne fonctionne pas sur IIS, mais j'ai trouvé ceci: http://neosmart.net/blog/2006/100-Apache-compliant-request_uri-for-iis-and-windows/ ce qui semble prometteur.
Utilisez cette classe pour que l'URL fonctionne.
class VirtualDirectory
{
var $protocol;
var $site;
var $thisfile;
var $real_directories;
var $num_of_real_directories;
var $virtual_directories = array();
var $num_of_virtual_directories = array();
var $baseURL;
var $thisURL;
function VirtualDirectory()
{
$this->protocol = $_SERVER['HTTPS'] == 'on' ? 'https' : 'http';
$this->site = $this->protocol . '://' . $_SERVER['HTTP_Host'];
$this->thisfile = basename($_SERVER['SCRIPT_FILENAME']);
$this->real_directories = $this->cleanUp(explode("/", str_replace($this->thisfile, "", $_SERVER['PHP_SELF'])));
$this->num_of_real_directories = count($this->real_directories);
$this->virtual_directories = array_diff($this->cleanUp(explode("/", str_replace($this->thisfile, "", $_SERVER['REQUEST_URI']))),$this->real_directories);
$this->num_of_virtual_directories = count($this->virtual_directories);
$this->baseURL = $this->site . "/" . implode("/", $this->real_directories) . "/";
$this->thisURL = $this->baseURL . implode("/", $this->virtual_directories) . "/";
}
function cleanUp($array)
{
$cleaned_array = array();
foreach($array as $key => $value)
{
$qpos = strpos($value, "?");
if($qpos !== false)
{
break;
}
if($key != "" && $value != "")
{
$cleaned_array[] = $value;
}
}
return $cleaned_array;
}
}
$virdir = new VirtualDirectory();
echo $virdir->thisURL;
Ajouter:
function my_url(){
$url = (!empty($_SERVER['HTTPS'])) ?
"https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] :
"http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
echo $url;
}
Ensuite, appelez simplement la fonction my_url
.
J'utilise la fonction suivante pour obtenir l'URL complète actuelle. Cela devrait fonctionner sur IIS et Apache.
function get_current_url() {
$protocol = 'http';
if ($_SERVER['SERVER_PORT'] == 443 || (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')) {
$protocol .= 's';
$protocol_port = $_SERVER['SERVER_PORT'];
} else {
$protocol_port = 80;
}
$Host = $_SERVER['HTTP_Host'];
$port = $_SERVER['SERVER_PORT'];
$request = $_SERVER['PHP_SELF'];
$query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';
$toret = $protocol . '://' . $Host . ($port == $protocol_port ? '' : ':' . $port) . $request . (empty($query) ? '' : '?' . $query);
return $toret;
}
REQUEST_URI est défini par Apache, vous ne l'obtiendrez donc pas avec IIS. Essayez de faire un var_dump ou print_r sur $ _SERVER et voyez quelles sont les valeurs utilisables.
La partie post-titre du URL se trouve après votre fichier index.php
, qui est un moyen courant de fournir des URL conviviales sans utiliser mod_rewrite. Le post-titre fait donc réellement partie de la chaîne de requête. Vous devriez donc pouvoir le récupérer avec $ _SERVER ['QUERY_STRING'].
Utilisez la ligne suivante en haut de la page PHP où vous utilisez $_SERVER['REQUEST_URI']
. Cela résoudra votre problème.
$_SERVER['REQUEST_URI'] = $_SERVER['PHP_SELF'] . '?' . $_SERVER['argv'][0];
Oh, le plaisir d'un extrait!
if (!function_exists('base_url')) {
function base_url($atRoot=FALSE, $atCore=FALSE, $parse=FALSE){
if (isset($_SERVER['HTTP_Host'])) {
$http = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ? 'https' : 'http';
$hostname = $_SERVER['HTTP_Host'];
$dir = str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
$core = preg_split('@/@', str_replace($_SERVER['DOCUMENT_ROOT'], '', realpath(dirname(__FILE__))), NULL, PREG_SPLIT_NO_EMPTY);
$core = $core[0];
$tmplt = $atRoot ? ($atCore ? "%s://%s/%s/" : "%s://%s/") : ($atCore ? "%s://%s/%s/" : "%s://%s%s");
$end = $atRoot ? ($atCore ? $core : $hostname) : ($atCore ? $core : $dir);
$base_url = sprintf( $tmplt, $http, $hostname, $end );
}
else $base_url = 'http://localhost/';
if ($parse) {
$base_url = parse_url($base_url);
if (isset($base_url['path'])) if ($base_url['path'] == '/') $base_url['path'] = '';
}
return $base_url;
}
}
Il a de beaux retours comme:
// A URL like http://stackoverflow.com/questions/189113/how-do-i-get-current-page-full-url-in-php-on-a-windows-iis-server:
echo base_url(); // Will produce something like: http://stackoverflow.com/questions/189113/
echo base_url(TRUE); // Will produce something like: http://stackoverflow.com/
echo base_url(TRUE, TRUE); || echo base_url(NULL, TRUE); //Will produce something like: http://stackoverflow.com/questions/
// And finally:
echo base_url(NULL, NULL, TRUE);
// Will produce something like:
// array(3) {
// ["scheme"]=>
// string(4) "http"
// ["Host"]=>
// string(12) "stackoverflow.com"
// ["path"]=>
// string(35) "/questions/189113/"
// }
J'ai utilisé le code suivant et j'obtiens le bon résultat ...
<?php
function currentPageURL() {
$curpageURL = 'http';
if ($_SERVER["HTTPS"] == "on") {
$curpageURL.= "s";
}
$curpageURL.= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
$curpageURL.= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
}
else {
$curpageURL.= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $curpageURL;
}
echo currentPageURL();
?>
Sur mon serveur Apache, cela me donne l'URL complète au format exact que vous recherchez:
$_SERVER["SCRIPT_URI"]
Quelque chose d'un peu plus robuste. Note Cela ne fonctionnera que sur 5.3
ou supérieur.
/*
* Compatibility with multiple Host headers.
* Support of "Reverse Proxy" configurations.
*
* Michael Jett <[email protected]>
*/
function base_url() {
$protocol = @$_SERVER['HTTP_X_FORWARDED_PROTO']
?: @$_SERVER['REQUEST_SCHEME']
?: ((isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") ? "https" : "http");
$port = @intval($_SERVER['HTTP_X_FORWARDED_PORT'])
?: @intval($_SERVER["SERVER_PORT"])
?: (($protocol === 'https') ? 443 : 80);
$Host = @explode(":", $_SERVER['HTTP_Host'])[0]
?: @$_SERVER['SERVER_NAME']
?: @$_SERVER['SERVER_ADDR'];
// Don't include port if it's 80 or 443 and the protocol matches
$port = ($protocol === 'https' && $port === 443) || ($protocol === 'http' && $port === 80) ? '' : ':' . $port;
return sprintf('%s://%s%s/%s', $protocol, $Host, $port, @trim(reset(explode("?", $_SERVER['REQUEST_URI'])), '/'));
}
Tout le monde a oublié http_build_url ?
http_build_url($_SERVER['REQUEST_URI']);
Quand aucun paramètre n'est passé à http_build_url
, l'URL actuelle sera automatiquement assumée. Je m'attendrais à ce que REQUEST_URI
soit également inclus, bien que cela semble nécessaire pour inclure les paramètres GET.
L'exemple ci-dessus renverra une URL complète.