올바른 이해와 사용 방법
현재 페이지의 URL 정보는 슈퍼글로벌 변수인 $_SERVER를 조합하여 가져올 수 있습니다.
URL 전체 주소뿐만 아니라 프로토콜(http, https), 도메인, 경로, 쿼리 문자열 등 개별 URL 구성 요소도 문자열로 가져올 수 있습니다.
전체 URL 가져오기: $_SERVER 조합
슈퍼글로벌 변수인 $_SERVER는 현재 실행 중인 PHP 스크립트와 관련된 서버 및 실행 환경에 대한 정보가 키와 값으로 구성된 연관 배열입니다. 이 연관 배열에는 현재 실행 중인 URL 정보도 포함되어 있습니다. 이 URL 정보를 가지고 있는 키의 값을 조합하면 URL 전체 주소뿐만 아니라 프로토콜, 도메인, 경로, 쿼리 문자열 등 개별 URL 구성 요소도 문자열로 가져올 수 있습니다.
URL 구성 요소에 대한 이해를 돕기 위해 먼저 URL의 기본 구조를 살펴보겠습니다.
URL은 일반적으로 다음과 같은 여덟 가지 요소로 나눌 수 있습니다.
개별 URL 구성 요소를 가져오기 위해 사용하는 $_SERVER의 연관 배열 키와 값은 다음과 같습니다.
| 연관 배열 키 | URL 구성 요소 | 반환 값 예시 |
|---|---|---|
$_SERVER['HTTPS'] |
protocol
(HTTPS 사용 여부) |
HTTPS 프로토콜을 통해 요청된 경우 $_SERVER['HTTPS'] 키는 존재하며 비어 있지 않은 값(non-empty value)으로 설정됩니다. |
$_SERVER['HTTP_HOST'] |
hostname + port | "www.example.com:8080" |
$_SERVER['SERVER_NAME'] |
hostname | "www.example.com" |
$_SERVER['SERVER_PORT'] |
port |
|
$_SERVER['REQUEST_URI'] |
pathname + query | "/path/to/resource?key1=value1&key2=value2" |
$_SERVER['QUERY_STRING'] |
query |
|
참고하세요!
URL 구성 요소 중 문서 또는 리소스 내의 특정 부분을 가리키며, #으로 시작하는 fragment(또는 'hash'라고도 함)는 브라우저에서만 사용되며 서버에 전달되지 않습니다. 따라서 PHP에서는 현재 URL의 fragment를 가져올 수 없습니다. 반면, 자바스크립트에서는 fragment를 가져올 수 있습니다. 자바스크립트 현재 URL 해시(프래그먼트) 가져오기를 참고하세요.
예제
/* 전체 URL 예: https://www.example.com/products/list?page=1 */
// $_SERVER의 HTTPS와 SERVER_PORT를 확인하여 HTTPS 사용 여부를 판단하는 함수
function is_https() {
// HTTPS 서버 변수가 존재하고 문자열이 비어 있지 않은 경우
if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS'])) {
return true;
}
// HTTPS 서버 변수가 없거나 문자열이 비어 있는 경우 기본 HTTPS 포트인 443으로 확인
if (isset($_SERVER['SERVER_PORT']) && (string) $_SERVER['SERVER_PORT'] === '443') {
return true;
}
return false;
}
/*
주의: $_SERVER['HTTPS']와 $_SERVER['SERVER_PORT']를 이용한 HTTPS 확인은
PHP가 전달받은 서버 정보를 기준으로 합니다.
로드 밸런서나 리버스 프록시를 사용하는 환경에서는
실제 클라이언트의 HTTPS 접속 여부와 PHP가 인식하는 요청 정보가 다를 수 있습니다.
*/
// 1. 프로토콜 확인: HTTPS 사용 여부에 따라 http 또는 https 결정
$protocol = is_https() ? 'https' : 'http';
// 2. hostname + port: 호스트 이름과 포트 정보를 가져오기
$host = $_SERVER['HTTP_HOST'];
// 3. pathname + query: 요청된 경로(pathname)와 쿼리 문자열(query) 가져오기
$uri = $_SERVER['REQUEST_URI'];
// 4. 조각들을 하나로 합쳐서 전체 URL 완성
$current_url = $protocol . '://' . $host . $uri;
echo $current_url;
// 출력: https://www.example.com/products/list?page=1
위 예제 코드는 $_SERVER에 포함된 값을 조합하여 웹 브라우저에서 주로 사용하는 HTTP와 HTTPS 프로토콜 환경을 기준으로 현재 URL을 조합하는 것을 보여줍니다. URL의 scheme에는 HTTP와 HTTPS 외에도 FTP, file, ws(WebSocket), wss(WebSocket Secure) 등 다양한 종류가 있지만, 이 예제에서는 웹 페이지의 현재 URL을 가져오는 일반적인 HTTP(S) 환경을 대상으로 합니다.
개별 URL 구성 요소 가져오기
$_SERVER의 연관 배열 키를 개별적으로 사용해 현재 URL의 프로토콜, 도메인, 경로, 쿼리 문자열 등 개별 URL 구성 요소만 가져올 수 있습니다.
예제
/* 전체 URL 예: https://www.example.com:8080/products/list?page=1#review */
// HTTPS와 SERVER_PORT를 확인하여 HTTPS 사용 여부를 판단하는 함수
function is_https() {
// HTTPS 서버 변수가 존재하고 문자열이 비어 있지 않은 경우
if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS'])) {
return true;
}
// HTTPS 서버 변수가 없거나 문자열이 비어 있는 경우 기본 HTTPS 포트인 443으로 확인
if (isset($_SERVER['SERVER_PORT']) && (string) $_SERVER['SERVER_PORT'] === '443') {
return true;
}
return false;
}
/*
주의: $_SERVER['HTTPS']와 $_SERVER['SERVER_PORT']를 이용한 HTTPS 확인은
PHP가 전달받은 서버 정보를 기준으로 합니다.
로드 밸런서나 리버스 프록시를 사용하는 환경에서는
실제 클라이언트의 HTTPS 접속 여부와 PHP가 인식하는 요청 정보가 다를 수 있습니다.
*/
// protocol
$protocol = is_https() ? 'https' : 'http';
echo $protocol;
// "https"
// hostname + port
echo $_SERVER['HTTP_HOST'];
// "www.example.com:8080"
// hostname
echo $_SERVER['SERVER_NAME'];
// "www.example.com"
// port
echo $_SERVER['SERVER_PORT'];
// "8080"
// protocol + hostname + port
$origin = $protocol . '://' . $_SERVER['HTTP_HOST'];
echo $origin;
// "https://www.example.com:8080"
// pathname + query
echo $_SERVER['REQUEST_URI'];
// "/products/list?page=1"
// query
echo $_SERVER['QUERY_STRING'];
// "page=1"
// fragment
// PHP에서는 현재 URL의 fragment를 가져올 수 없습니다.