Windows / IIS 서버에서 현재 페이지의 전체 URL을 얻으려면 어떻게해야합니까?


137

WordPress 설치를 Windows / IIS 서버 의 새 폴더 로 옮겼습니다 . PHP에서 301 리디렉션을 설정하고 있지만 작동하지 않는 것 같습니다. 내 게시물 URL의 형식은 다음과 같습니다.

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

/post-title/URL 의 일부 를 얻는 방법을 알 수 없습니다 .

$_SERVER["REQUEST_URI"]-모두가 권장하는 것처럼-빈 문자열을 반환합니다. $_SERVER["PHP_SELF"]그냥 돌아오고 index.php있습니다. 왜 이런 것이며 어떻게 고칠 수 있습니까?


24
print_r ($ _ SERVER)를 수행하고 사용 가능한 데이터를 확인하십시오. 전체 URL을 얻을 수 있으면 pathinfo ($ url)를 호출하여 파일 이름을 얻을 수 있습니다.
gradbot

18
이 질문은 일반적으로 PHP가 아니라 IIS에 관한 것입니다. 아파치에서는 $ _SERVER [ 'REQUEST_URI']를 사용하면됩니다.
Michał Tatarynowicz

@Pies 확실히 $ _SERVER [ 'REQUEST_URI']는 갈 길입니다 ... 그러나 URI의 특정 부분을 잡는 방법. 예를 들어이 URI가 있습니다 : /Appointments/Administrator/events.php/219 ... /events.php/ 이후에 숫자를 얻는 방법
Dimitris Papageorgiou

가능한 복제본 PHP에서 전체 URL 얻기
T.Todua

답변:


135

아마도 당신은 IIS 아래 있기 때문에

$_SERVER['PATH_INFO']

설명에 사용한 URL을 기반으로 원하는 것입니다.

Apache의 경우을 사용 $_SERVER['REQUEST_URI']합니다.


안녕하세요 이것을 사용하여 다음과 같은 오류가 발생합니까? Notice: Undefined index: PATH_INFO in /home/tdpk/public_html/system/config.php on line 14
11

6
oops, drat-방금이 질문이 IIS에 관한 것이라는 것을 깨달았습니다. 공감이 유감입니다.
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는 IIS를 명확하게 언급했습니다-REQUEST_URI는 IIS에서 사용할 수 없습니다
Tom Auger

1
PHP에서 절대적으로 필요하지 않으면 마법 인용 부호를 사용해서는 안됩니다.
Case

2
@TomAuger 타임 라인을 봐야합니다. OP가 질문에 대답 한 후 오랫동안 추가했습니다. 원래 질문은 약 1 년 전에 대답했습니다.
타일러 카터

7
@Stan, 싱글을 두 배 이상 사용하면 순 성능 이점이 없습니다. 없음, nadda, zip, zero. PHP3 시대의 오래된 이야기입니다. 내용에 대한 사소한 조작을 수행하지 마십시오.
Charles

36

Apache의 경우 :

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


허먼이 언급 한대로 HTTP_HOST대신 사용할 수도 있습니다 SERVER_NAME. 자세한 내용은 이 관련 질문 을 참조하십시오 . 요컨대, 어느 쪽을 사용해도 괜찮습니다. 다음은 '호스트'버전입니다.

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


편집증을 위해 / 왜 중요한가

일반적으로, 나는 설정 ServerNameVirtualHost내가 원하기 때문에 정식 웹 사이트의 형태로. 는 $_SERVER['HTTP_HOST']요청 헤더를 기반으로 설정됩니다. 서버가 해당 IP 주소의 모든 / 도메인 이름에 응답하면 사용자가 헤더를 스푸핑하거나 더 나쁜 사람이 DNS 레코드를 IP 주소로 지정하면 서버 / 웹 사이트에서 동적 웹 사이트를 제공하게됩니다 잘못된 URL에 작성된 링크 후자의 방법을 사용하는 경우 다음과 같이 제공하려는 도메인을 시행하도록 규칙을 vhost설정하거나 .htaccess규칙을 설정해야합니다 .

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

희망이 도움이됩니다. 이 답변의 진정한 요점은 아파치와 함께 완전한 URL을 얻는 방법을 검색 할 때 여기에 나온 사람들에게 첫 번째 코드 줄을 제공하는 것이 었습니다. :)


2
$_SERVER['HTTP_HOST']대신 사용해야 합니다 $_SERVER['SERVER_NAME']. 가상 호스트 설정이 있으면 SERVER_NAME에 해당 이름이 표시됩니다. *.example.com유효하지 않은 것일 수 있습니다 .
허먼 J. Radtke III


9

URL을 작동 시키려면이 클래스를 사용하십시오.

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
이것은 과잉이 아닌가?
s3v3n

7

더하다:

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

그런 다음 my_url함수를 호출하십시오 .


5

다음 함수를 사용하여 현재 전체 URL을 가져옵니다. 이것은 IIS와 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;
}

CGI 기반 Apache 또는 IIS를 사용하지 않으면 argv가 작동하지 않습니다. 위의 코드를 Apache2에서 CGI 모드가 아닌 일반 모드로 시도했지만 $ _SERVER [ 'arv'] [0]이 색인이 아니기 때문에 오류가 발생했습니다. 또한 전체 PHP 오류보고 기능이 설정되어 있으며 이러한 오류는 알림 오류입니다.
Volomike

매력처럼 작동하며 쿼리 문자열 매개 변수의 오류를 방지하기 위해 약간의 업데이트가 필요합니다 $query = isset($_SERVER['argv']) ? substr($_SERVER['argv'][0], strpos($_SERVER['argv'][0], ';') + 1) : '';. 이것을 포함하도록 귀하의 답변을 업데이트했습니다.
Zuul

4

REQUEST_URI는 Apache에 의해 설정되므로 IIS에서는 얻을 수 없습니다. $ _SERVER에서 var_dump 또는 print_r을 시도하고 사용할 수있는 값을 확인하십시오.


3

URL 의 제목 부분은 index.php파일 뒤에 있으며, mod_rewrite를 사용하지 않고 친숙한 URL을 제공하는 일반적인 방법입니다. 따라서 제목은 실제로 쿼리 문자열의 일부이므로 $ _SERVER [ 'QUERY_STRING']을 사용하여 얻을 수 있어야합니다.


2

사용중인 PHP 페이지 상단에서 다음 줄을 사용하십시오 $_SERVER['REQUEST_URI']. 문제가 해결됩니다.

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

1

스 니펫의 재미!

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

다음과 같은 아름다운 수익이 있습니다.

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

모두가 http_build_url을 잊어 버렸 습니까 ?

http_build_url($_SERVER['REQUEST_URI']);

매개 변수가 전달되지 않으면 http_build_url현재 URL을 자동으로 가정합니다. REQUEST_URIGET 매개 변수를 포함하는 데 필요한 것으로 보이지만 포함 될 것으로 예상 됩니다.

위의 예는 전체 URL을 반환합니다.


1
pecl_http가 필요합니다.
Omar Abid

@OmarAbid 추천합니다. :-)
Gajus

당신의 입장을 이해합니다. 그러나 제어 할 수없는 다른 플랫폼에서 사용될 스크립트를 작성할 때는 상당히 표준적인 것을 선택해야합니다.
Omar Abid

1
라이브러리를 작성하는 경우 요구 사항을 정의하는 것은 사용자의 책임입니다. 원래의 질문은 그러한 시나리오를 전혀 다루지 않습니다. 따라서 모든 대안의 이름을 지정하는 것이 좋습니다.
Gajus

0

다음 코드를 사용했으며 올바른 결과를 얻고 있습니다 ...

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

잘 작동합니다. HTTPS가 없으면 해당 회선을 제거하려고합니다.

0

내 아파치 서버에서 이것은 당신이 찾고있는 정확한 형식의 전체 URL을 제공합니다.

$_SERVER["SCRIPT_URI"]

0

리버스 프록시 지원!

좀 더 견고한 것. 참고5.3 이상 에서만 작동합니다 .

/*
 * 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'])), '/'));
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.