PATH_INFO almak için taşınabilir ve güvenli bir şekilde

6 Cevap php

Ben (kullanışlı) $_SERVER['PATH_INFO'] değişkeni almak için portable yolunu arayan kulüpler.

Bir süre okuduktan sonra, PATH_INFO CGI/1.1 kökenli çıkıyor, ve benim her zaman tüm yapılandırmada mevcut değil.

apart from extracting it manually (güvenlik sorunu) - Ne o değişkeni almak için yol (çoğunlukla güvenlik-bilge) en iyisidir.

6 Cevap

Peki, (neredeyse) eminim ki, $_SERVER superglobal tuşlarının yararlanarak PATH_INFO söyleniyor, sadece imkansız anlamaya alternatif bir yol vermeden {[(2 )]} biz possibly kullanabilir ki:

  • 'PHP_SELF'
  • 'QUERY_STRING'
  • 'SCRIPT_FILENAME'
  • 'PATH_TRANSLATED'
  • 'SCRIPT_NAME'
  • 'REQUEST_URI'
  • 'PATH_INFO'yu'
  • 'ORIG_PATH_INFO'

Biz tabii ki son iki görmezden gerekir. Şimdi biz (I don't know this for a fact, I'm just assuming because you said so) aşağıdaki tuşları ile bize bırakır size (which BTW is offline ATM) sağlanan bağlantı, mevcut tüm anahtarları filtre olmalıdır:

  • 'PHP_SELF'
  • 'SCRIPT_FILENAME'
  • 'REQUEST_URI'

Için yorum ile ilgili Anthonys answer:

You are just juggling variables now. SCRIPT_FILENAME is a part of the CGI spec. It will not be available if PATH_INFO is unavailable. As for REQUEST_URI, it's apache's mod_rewrite specific. – LiraNuna

I LightTPD/1.4.20-1 (Win32) with PHP 5.3.0 as CGI, cgi.fix_pathinfo = 1 çalışan ve $_SERVER['REQUEST_URI'] benim için çok geçerli ediyorum , I also remember using that same variable back in the days when no one used mod_rewrite böylece my honest humble guess is that you're plain wrong in this point. SCRIPT_FILENAME tuşuyla ilgili ben ATM o bir test etmek mümkün değilim. Yine de, biz gerçekten zor bizim gözlerinizi kapatın ve konum inanıyorum eğer bu doğru tek bir değişken ile bize bırakır:

  • 'PHP_SELF'

Burada sert olmaktan çalışıyorum değilim (ve hala daha çözüm olduğuna inanıyorum) ama PHP_SELF bize (varsayarak {hiçbir dayatmalar vardır çalışmak istediğiniz tek anahtarı ise [(0)]} kendisi sadece tek bir çözüm kalmadı) :

function PATH_INFO()
{
 if (array_key_exists('PATH_INFO'yu', $_SERVER) === true)
 {
  return $_SERVER['PATH_INFO'yu'];
 }

 $whatToUse = basename(__FILE__); // see below

 return substr($_SERVER['PHP_SELF'], strpos($_SERVER['PHP_SELF'], $whatToUse) + strlen($whatToUse));
}

Bu işlev ancak __FILE__ sabit istenen PHP script {yolunu beyan değildir ve dosyanın yolunu döndürür beri the __FILE__ sabit kullanarak bazı sorunlar olabilir, çalışması gerekir [(2)]} or if you really believe in what you are saying, just use '.php' .

You should also read this regarding why not to use PHP_SELF .

Bu sizin için işe yaramazsa, üzgünüm ama ben başka bir şey düşünemiyorum.

EDIT - Some more reading for you:

Bu "taşınabilir" ve "güvenli" için tanımlara bağlıdır.

Ben anladım Bakalım:

1) CLI ilgilenmiyor:

  • PHP / CGI söz
  • PATH_INFO'yu bir URL bir parçasıdır; betik (genellikle bir tarayıcı tarafından istenen bir HTTP bağlantısı, gelen yani) bir URL'den erişildiğinde nedenle, sadece PATH_INFO tartışmak için mantıklı

2) Tüm işletim sistemi + HTTP sunucusu + PHP birlikte PATH_INFO istiyorum:

  • OS, Windows, Linux, vb olabilir
  • HTTP sunucusu vb Apache 1, Apache 2, nginx, Lighttpd olabilir
  • PHP sürüm 4, 5, 6 ya da herhangi bir sürümü olabilir

Hmmm ... php_info, $ _SERVER dizisinde, yukarıda belirtilen yazılımlar bağlı, sadece belirli koşullar altında yürütülmesine bir komut dosyası PHP tarafından sağlanmaktadır. O her zaman mevcut değildir. Aynı tüm $ _SERVER dizisi için de geçerlidir!

Kısacası: "$_SERVER depends on the server" ... yani taşınabilir bir çözüm sadece bir örnek vermek (... $ _SERVER röle değil: PHP / CGI $ _SERVER değişkenleri kurmak için bir öğretici var kbeezie.com / view / php-öz-yol-nginx /) de nginx HTTP sunucusu

3) Yukarıda belirtilen ne rağmen, biz nasılsa bir dizge olarak the full URL that was requested kullanılabilir varsa, güvenli bir şekilde (aynı zamanda, düzenli ifadeler ve diğer PHP string fonksiyonları uygulayarak ondan PATH_INFO elde etmek mümkün olduğunu vurgulamak gerekir ) geçerli bir tanım olarak giriş dizesi doğrulama.

Yani, biz URL string ... sonra YES, WE ondan PATH_INFO belirlemek için bir taşınabilir ve güvenli bir şekilde VAR olması kaydıyla.


Şimdi, biz iki net ve odaklı uygulama sorunları var:

  1. URL'yi nasıl elde edilir?
  2. URL'den PATH_INFO nasıl elde edilir?

Çeşitli olasılıklar arasında, burada olası bir yaklaşımdır:

URL'yi nasıl elde edilir?

1) Her bir HTTP sunucusu + OS + PHP version kombinasyon hakkında derin ve kapsamlı bilgi birikimi ile, kontrol ve $ _SERVER dizisinde (doğrulamak 'PHP_SELF', 'QUERY_STRING', 'SCRIPT_FILENAME', 'PATH_TRANSLATED' den URL elde etmek için her imkanı çalışın , 'SCRIPT_NAME', 'REQUEST_URI', 'PATH_INFO'yu', 'ORIG_PATH_INFO', 'HTTP_HOST', 'DOCUMENT_ROOT' ya da her neyse)

Önceki adım başarısız olursa 2), PHP komut dosyası arka "document.URL" bilgi gönderen bir javascript kodu döndürebilir olun. (Taşınabilirlik sorunu istemci tarafında aktarılır.)

URL'den PATH_INFO nasıl elde edilir?

This code linked here does this.

Bu benim düşünceme ve soruna yaklaşım.

Sen ne düşünüyorsun?

Ben burada başka bir şekilde "PATH_INFO" almak için bir hile olduğunu düşünüyorum:

$path_info = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['PHP_SELF']);

Örneğin, böyle bir URL'ye erişim: http://somehost.com/index.php/some/path/here, değeri $path_info olacaktır: "/some/path/here"

Bu windows ve linux üzerinde çalışan çeşitli apache sunucularında benim için çalıştı, ama "güvenli" ve "taşınabilir" ise, ovbiously ben "TÜM" sunucular biçimlendirimleri bunu test değil% 100 emin değilim, ama çalışması için görünür ...

Ben göndermeden önce yorum veya bağlantısını görmedim. İşte dayalı işe yarayabilecek bir şey, yukarıda başvurulan sayfa CGI-türetilmiş değişkenler olarak ne verir:

function getPathInfo() {
    if (isset($_SERVER['PATH_INFO'])) {
        return $_SERVER['PATH_INFO'];
    }  

    $script_filename = $_SERVER["SCRIPT_FILENAME"];
    $script_name_start = strrpos($script_filename, "/");
    $script_name = substr($script_filename, $script_name_start);

    //With the above you should have the plain file name of script without path        

    $script_uri = $_SERVER["REQUEST_URI"];
    $script_name_length = strlen($script_name);
    $path_start = $script_name_length + strpos($script_name, $script_uri);

    //You now have the position of where the script name ends in REQUEST_URI

    $pathinfo = substr($script_uri, $path_start);
    return $pathinfo;
}
function getPathInfo() {
    if (isset($_SERVER['PATH_INFO'])) {
        return $_SERVER['PATH_INFO'];
    }  
    $scriptname = preg_quote($_SERVER["SCRIPT_NAME"], '/');
    $pathinfo = preg_replace("/^$scriptname/", "", $_SERVER["PHP_SELF"]);
    return $pathinfo;
}

Düzenleme: SCRIPT_NAME olmadan, ve o zaman, DOCUMENT_ROOT (veya kendiniz keşfedebilirsiniz / tanımlayabilirsiniz) varsayarak ve Betiklerinizi sahip varsayarak:

function getPathInfo() {
    if (isset($_SERVER['PATH_INFO'])) {
        return $_SERVER['PATH_INFO'];
    }  
    $docroot = preg_quote($_SERVER["DOCUMENT_ROOT"], "/");
    $scriptname = preg_replace("/^$docroot/", "", $_SERVER["SCRIPT_FILENAME"]);
    $scriptname = preg_quote($scriptname, "/");
    $pathinfo = preg_replace("/^$scriptname/", "", $_SERVER["PHP_SELF"]);
    return $pathinfo;
}

Ayrıca Anthony @ (Yorumlamak için yeterli değil rep, üzgünüm): str_replace () kullanarak dizede herhangi bir maç olacak. Bu sadece başında maç istiyorum, çalışmak için garanti değil. Script docroot karşı Betiklerinizi diffing daha iyiyiz neden olan kök altında ise de, sadece SCRIPT_NAME belirlemek için (strrpos'un yoluyla) geri 1 bölü gidiş yönteminiz, sadece çalışacaktır.

Eğer deneyebilirsiniz

$_ENV['PATH_INFO']; or
getenv('PATH_INFO'];