Geçerli sayfanın tam URL'sini bir Windows / IIS sunucusunda nasıl alabilirim?


137

WordPress kurulumunu Windows / IIS sunucusundaki yeni bir klasöre taşıdım . PHP 301 yönlendirmeleri ayarlıyorum, ama çalışmıyor gibi görünüyor. Yazı URL'lerim şu biçimde:

http:://www.example.com/OLD_FOLDER/index.php/post-title/

/post-title/URL'nin bir kısmını nasıl yakalayacağımı anlayamıyorum.

$_SERVER["REQUEST_URI"]- herkesin önerdiği gibi - boş bir dize döndürüyor. $_SERVER["PHP_SELF"]sadece geri dönüyor index.php. Bu neden ve nasıl düzeltebilirim?


24
Sadece bir print_r ($ _ SERVER) yapın ve hangi verilerin kullanılabilir olduğunu görün. Tam URL'yi alabiliyorsanız dosya adını almak için pathinfo ($ url) 'yı arayabilirsiniz.
gradbot

18
Bu sorunun genel olarak PHP ile değil IIS ile ilgili olduğu unutulmamalıdır. Apache altında sadece $ _SERVER ['REQUEST_URI'] kullanırsınız.
Michał Tatarynowicz

@Pies Kesinlikle $ _SERVER ['REQUEST_URI'] gitmek için bir yol ... ama nasıl URI belirli bir bölümünü kapmak.Örneğin bu URI var: /Appointments/Administrator/events.php/219 ... /events.php/'den sonra numarayı nasıl yakalayabilirim
Dimitris Papageorgiou

Yanıtlar:


135

Belki, IIS altında olduğunuz için,

$_SERVER['PATH_INFO']

açıklamak için kullandığınız URL'lere göre istediğiniz şeydir.

Apache için kullanırsınız $_SERVER['REQUEST_URI'].


merhaba bu kullanarak sadece aşağıdaki hatayı alıyorum? Notice: Undefined index: PATH_INFO in /home/tdpk/public_html/system/config.php on line 14
chhameed

6
ayy, drat - bu sorunun IIS ile ilgili olduğunu fark ettim ve kullanıyorum. İniş için üzgünüm.
Jason S

63
$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;

11
OP açıkça belirtilen IIS - REQUEST_URI, IIS altında kullanılamaz
Tom Auger

1
Kesinlikle php yapmak zorunda sürece asla magicquotes kullanmamalısınız.
Dava

2
@TomAuger Zaman çizelgesine bakmanız gerekiyor. OP bu soruyu cevapladıktan çok sonra ekledi. Orijinal soru cevap vermeden yaklaşık bir yıl önce soruldu.
Tyler Carter

7
@Stan, çiftler üzerinde single kullanmanın net performans avantajı sıfır. Yok, nadda, zip, sıfır. PHP3 döneminden kalma eski bir eşin hikayesi. Lütfen içeriğe bu kadar önemsiz bir yönetim yapmayın.
Charles

36

Apache için:

'http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']


Herman'ın yorumladığı gibi HTTP_HOSTyerine de kullanabilirsiniz SERVER_NAME. Tam bir tartışma için bu ilgili soruya bakın . Kısacası, muhtemelen ikisini de kullanarak sorun değil. İşte 'host' sürümü:

'http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']


Paranoyak İçin / Neden Önemlidir

Tipik olarak, ben set ServerNameiçinde VirtualHostben istediğim için o olmak kanonik web sitesinin formu. $_SERVER['HTTP_HOST']İstek başlıklarına dayanarak ayarlanır. Sunucu bu IP adresindeki herhangi bir etki alanına / tüm etki alanı adlarına yanıt verirse, kullanıcı üstbilgiyi taklit edebilir veya daha da kötüsü, birisi IP adresinize bir DNS kaydı gösterebilir ve ardından sunucunuz / web siteniz dinamik bir web sitesi sunabilir Yanlış bir URL üzerine kurulmuş bağlantılar. İkinci yöntemi kullanıyorsanız, sunmak istediğiniz alanı zorunlu kılmak için yapılandırmanız vhostveya bir .htaccesskural oluşturmanız gerekir:

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

Umarım yardımcı olur. Bu cevabın asıl amacı, apache ile tam URL'yi almanın bir yolunu ararken burada bulunanlar için ilk kod satırını sağlamaktı :)


2
Bunun $_SERVER['HTTP_HOST']yerine kullanması gerekir $_SERVER['SERVER_NAME']. Sanal bir ana bilgisayar kurulumu varsa, SERVER_NAME bu adı gösterir. Bu *.example.comgeçerli olmayan bir şey olabilir .
Herman J. Radtke III


9

URL'nin çalışmasını sağlamak için bu sınıfı kullanın.

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;

10
bu biraz abartılı değil mi?
s3v3n

7

Ekle:

function my_url(){
    $url = (!empty($_SERVER['HTTPS'])) ?
               "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] :
               "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
    echo $url;
}

Sonra sadece my_urlişlevi çağırın .


5

Geçerli, tam URL almak için aşağıdaki işlevi kullanın. Bu IIS ve Apache üzerinde çalışmalıdır.

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;
}

CGI tabanlı bir Apache veya IIS kullanmıyorsanız argv çalışmaz diye düşünüyorum. Kodunuzu yukarıda Apache2 normal modda (CGI modu değil) denedim ve $ _SERVER ['arv'] [0] bir dizin olmadığından hata veriyor. Ayrıca tam PHP hata raporlama açık olduğunu ve bu hatalar uyarı hataları olduğunu unutmayın.
Volomike

Sadece sorgu dizesi parametresi hataları önlemek için biraz güncelleştirme ihtiyacı bir cazibe gibi çalışır: $query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';. Cevabınızı bunu içerecek şekilde güncelledim.
Zuul

4

REQUEST_URI, Apache tarafından ayarlanır, bu nedenle IIS ile elde edemezsiniz. $ _SERVER üzerinde var_dump veya print_r yapmayı deneyin ve orada kullanabileceğiniz değerleri görün.


3

URL'nin posttitle kısmı, index.phpmod_rewrite kullanmadan kolay URL'ler sağlamanın yaygın bir yolu olan dosyanızdan sonra gelir . Bu nedenle yazı başlığı aslında sorgu dizesinin bir parçasıdır, bu nedenle $ _SERVER ['QUERY_STRING'] kullanarak alabilmeniz gerekir


2

Kullandığınız PHP sayfasının üstünde aşağıdaki satırı kullanın $_SERVER['REQUEST_URI']. Bu, sorununuzu çözecektir.

$_SERVER['REQUEST_URI'] = $_SERVER['PHP_SELF'] . '?' . $_SERVER['argv'][0];

1

Bir parçacığın eğlencesi!

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;
    }
}

Gibi güzel geri dönüşler var:

// 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/"
//      }

0

Herkes http_build_url unuttu mu?

http_build_url($_SERVER['REQUEST_URI']);

Herhangi bir parametre iletilmediğinde http_build_url, otomatik olarak geçerli URL'yi kabul eder. REQUEST_URIGET parametrelerini dahil etmek için gerekli görünse de ben de dahil edilmeyi bekliyorum .

Yukarıdaki örnek tam URL'yi döndürecektir.


1
Bu, pecl_http gerektirir.
Omar Abid

@OmarAbid Bunu tavsiye ederim. :-)
Gajus

Pozisyonunu anlıyorum. Ancak, kontrolünüz olmayan farklı platformlarda kullanılacak komut dosyaları oluştururken, oldukça standart bir şey seçmeniz gerekir.
Omar Abid

1
Bir kütüphane kuruyorsanız, gereksinimleri tanımlamak size bağlıdır. Orijinal soru böyle bir senaryoyu hiç ele almıyor. Bu nedenle, tüm alternatifleri adlandırmak mantıklıdır.
Gajus

0

Aşağıdaki kodu kullandım ve doğru sonucu alıyorum ...

<?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();
?>

Eğer HTTPS yoksa, o zaman onun hattını kaldırmak istiyoruz.

0

Apache sunucumda bu, tam URL'yi tam olarak aradığınız biçimde verir:

$_SERVER["SCRIPT_URI"]

0

Ters Proxy Desteği!

Biraz daha sağlam bir şey. Not Sadece üzerinde 5.3veya üstünde çalışacaktır .

/*
 * Compatibility with multiple host headers.
 * Support of "Reverse Proxy" configurations.
 *
 * Michael Jett <mjett@mitre.org>
 */

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'])), '/'));
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.