URI 작업하기

CodeIgniter는 애플리케이션에서 URI를 다루기 위한 객체 지향 솔루션을 제공합니다. 이를 사용하면 URI가 아무리 복잡하더라도 구조가 항상 올바른지 간단하게 확인할 수 있으며, 기존 URI에 상대 URI를 추가하고 안전하고 올바르게 해석할 수 있습니다.

URI 인스턴스 생성하기

URI 인스턴스를 생성하는 것은 새 클래스 인스턴스를 생성하는 것만큼 간단합니다.

새 인스턴스를 생성할 때 생성자에 전체 또는 부분 URL을 전달할 수 있으며, 적절한 섹션으로 파싱됩니다.

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path');

또는 service() 함수를 사용하여 인스턴스를 반환받을 수 있습니다.

$uri = service('uri', 'http://www.example.com/some/path');

v4.4.0부터 URL을 전달하지 않으면 현재 URI를 반환합니다.

$uri = service('uri'); // returns the current SiteURI instance.

참고

위 코드는 URI 클래스를 확장한 SiteURI 인스턴스를 반환합니다. URI 클래스는 일반 URI를 위한 것이고, SiteURI 클래스는 사이트 URI를 위한 것입니다.

현재 URI

요청의 현재 URL을 나타내는 객체가 필요할 때 URL 헬퍼에서 사용 가능한 current_url() 함수를 사용할 수 있습니다.

$uri = current_url(true);

첫 번째 매개변수로 true를 전달해야 합니다. 그렇지 않으면 현재 URL의 문자열 표현을 반환합니다.

이 URI는 현재 요청 객체와 Config\App의 설정(baseURL, indexPage, forceGlobalSecureRequests)에 의해 결정된 경로(baseURL에 상대적인)를 기반으로 합니다.

CodeIgniter\Controller를 확장한 컨트롤러 안에 있다면, 현재 SiteURI 인스턴스를 가져올 수도 있습니다.

$uri = $this->request->getUri();

URI 문자열

대부분의 경우 URI의 문자열 표현을 얻는 것이 필요합니다. URI를 문자열로 캐스팅하기만 하면 간단하게 처리할 수 있습니다.

<?php

$uri = current_url(true);
echo (string) $uri;  // http://example.com/index.php

URI의 각 구성 요소를 알고 있고 형식이 올바른지 확인만 하고 싶다면, URI 클래스의 정적 메서드인 createURIString()을 사용하여 문자열을 생성할 수 있습니다.

<?php

use CodeIgniter\HTTP\URI;

$uriString = URI::createURIString($scheme, $authority, $path, $query, $fragment);

// Creates: http://exmample.com/some/path?foo=bar#first-heading
echo URI::createURIString('http', 'example.com', 'some/path', 'foo=bar', 'first-heading');

중요

URI를 문자열로 캐스팅하면 Config\App에 정의된 설정에 맞게 프로젝트 URL을 조정하려고 합니다. 정확하고 변경되지 않은 문자열 표현이 필요한 경우 URI::createURIString()을 사용하세요.

URI 구성 요소

URI 인스턴스가 있으면 URI의 다양한 구성 요소를 설정하거나 가져올 수 있습니다. 이 섹션에서는 해당 구성 요소가 무엇인지, 그리고 그것들을 다루는 방법을 자세히 설명합니다.

스킴

스킴은 보통 ‘http’ 또는 ‘https’이지만, ‘file’, ‘mailto’ 등 모든 스킴이 지원됩니다.

<?php

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path');

echo $uri->getScheme(); // 'http'
$uri->setScheme('https');

권한(Authority)

많은 URI에는 ‘권한(authority)’으로 통칭되는 여러 요소가 포함됩니다. 여기에는 사용자 정보, 호스트, 포트 번호가 포함됩니다. getAuthority() 메서드로 이 모든 구성 요소를 하나의 문자열로 가져오거나, 개별 구성 요소를 조작할 수 있습니다.

<?php

$uri = new \CodeIgniter\HTTP\URI('ftp://user:password@example.com:21/some/path');

echo $uri->getAuthority();  // user@example.com:21

기본적으로 비밀번호 부분은 표시되지 않습니다. 비밀번호를 표시하려면 showPassword() 메서드를 사용할 수 있습니다. 이 URI 인스턴스는 비밀번호 표시를 끌 때까지 계속 표시하므로, 사용이 끝나면 반드시 비밀번호 표시를 꺼야 합니다.

<?php

echo $uri->getAuthority();  // user@example.com:21
echo $uri->showPassword()->getAuthority();   // user:password@example.com:21

// Turn password display off again.
$uri->showPassword(false);

포트를 표시하지 않으려면 유일한 매개변수로 true를 전달하세요.

<?php

echo $uri->getAuthority(true);  // user@example.com

참고

현재 포트가 스킴의 기본 포트인 경우 포트는 표시되지 않습니다.

사용자 정보(UserInfo)

사용자 정보 섹션은 FTP URI에서 볼 수 있는 사용자 이름과 비밀번호입니다. 권한(Authority)의 일부로 가져올 수도 있지만, 직접 가져올 수도 있습니다.

<?php

echo $uri->getUserInfo();   // user

기본적으로 비밀번호는 표시되지 않지만, showPassword() 메서드로 이를 재정의할 수 있습니다.

<?php

echo $uri->showPassword()->getUserInfo();   // user:password
$uri->showPassword(false);

호스트

URI의 호스트 부분은 일반적으로 URL의 도메인 이름입니다. getHost()setHost() 메서드로 쉽게 설정하고 가져올 수 있습니다.

<?php

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path');

echo $uri->getHost();   // www.example.com
echo $uri->setHost('anotherexample.com')->getHost();    // anotherexample.com

포트

포트는 0에서 65535 사이의 정수입니다. 각 스킴에는 연관된 기본값이 있습니다.

<?php

$uri = new \CodeIgniter\HTTP\URI('ftp://user:password@example.com:21/some/path');

echo $uri->getPort();   // 21
echo $uri->setPort(2201)->getPort(); // 2201

setPort() 메서드를 사용할 때 포트가 유효한 범위 내에 있는지 확인한 후 할당됩니다.

경로

경로는 사이트 내의 모든 세그먼트로 구성됩니다. 예상대로 getPath()setPath() 메서드를 사용하여 조작할 수 있습니다.

<?php

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path');

echo $uri->getPath();                            // '/some/path'
echo $uri->setPath('/another/path')->getPath();  // '/another/path'

참고

경로를 설정할 때 위험한 문자를 인코딩하고 안전을 위해 점 세그먼트를 제거하는 처리가 이루어집니다.

참고

v4.4.0부터 SiteURI::getRoutePath() 메서드는 baseURL에 상대적인 URI 경로를 반환하고, SiteURI::getPath() 메서드는 항상 선행 /가 있는 전체 URI 경로를 반환합니다.

쿼리

쿼리 데이터는 단순한 문자열 표현을 사용하여 클래스를 통해 조작할 수 있습니다.

쿼리 가져오기/설정하기

현재 쿼리 값은 문자열로만 설정할 수 있습니다.

<?php

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar');

echo $uri->getQuery();  // 'foo=bar'
$uri->setQuery('foo=bar&bar=baz');

setQuery() 메서드는 기존 쿼리 변수를 덮어씁니다.

참고

쿼리 값에는 프래그먼트가 포함될 수 없습니다. 포함될 경우 InvalidArgumentException이 발생합니다.

배열로 쿼리 설정하기

배열을 사용하여 쿼리 값을 설정할 수 있습니다.

<?php

$uri->setQueryArray(['foo' => 'bar', 'bar' => 'baz']);

setQueryArray() 메서드는 기존 쿼리 변수를 덮어씁니다.

쿼리 값 추가하기

addQuery() 메서드를 사용하면 기존 쿼리 변수를 제거하지 않고 쿼리 변수 컬렉션에 값을 추가할 수 있습니다. 첫 번째 매개변수는 변수 이름이고, 두 번째 매개변수는 값입니다.

<?php

$uri->addQuery('foo', 'bar');

쿼리 값 필터링하기

getQuery() 메서드에 only 또는 except 키가 있는 옵션 배열을 전달하여 반환되는 쿼리 값을 필터링할 수 있습니다.

<?php

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar&bar=baz&baz=foz');

// Returns 'foo=bar'
echo $uri->getQuery(['only' => ['foo']]);

// Returns 'foo=bar&baz=foz'
echo $uri->getQuery(['except' => ['bar']]);

이는 이번 호출 중에 반환되는 값만 변경합니다.

쿼리 값 변경하기

URI의 쿼리 값을 더 영구적으로 변경해야 한다면, stripQuery()keepQuery() 메서드를 사용하여 실제 객체의 쿼리 변수 컬렉션을 변경할 수 있습니다.

<?php

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar&bar=baz&baz=foz');

// Leaves just the 'baz' variable
$uri->stripQuery('foo', 'bar');

// Leaves just the 'foo' variable
$uri->keepQuery('foo');

참고

기본적으로 setQuery()setQueryArray() 메서드는 데이터를 준비하기 위해 네이티브 parse_str() 함수를 사용합니다. 더 유연한 규칙(키 이름에 점을 포함하도록 허용)을 사용하려면 사전에 특수 메서드 useRawQueryString()을 사용할 수 있습니다.

프래그먼트

프래그먼트는 파운드 기호(#) 뒤에 오는 URL 끝 부분입니다. HTML URL에서는 페이지 내 앵커 링크이며, 미디어 URI에서는 다양한 방식으로 활용될 수 있습니다.

<?php

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path#first-heading');

echo $uri->getFragment();   // 'first-heading'
echo $uri->setFragment('second-heading')->getFragment();    // 'second-heading'

URI 세그먼트

슬래시 사이의 경로 각 섹션이 하나의 세그먼트입니다.

참고

사이트 URI의 경우, URI 세그먼트는 baseURL에 상대적인 URI 경로 부분만을 의미합니다. baseURL에 하위 폴더가 포함된 경우 값이 현재 URI 경로와 다를 수 있습니다.

URI 클래스는 세그먼트의 값을 확인하는 간단한 방법을 제공합니다. 세그먼트는 경로의 가장 왼쪽인 1번부터 시작합니다.

<?php

// URI = http://example.com/users/15/profile

// Prints '15'
if ($uri->getSegment(1) === 'users') {
    echo $uri->getSegment(2);
}

getSegment() 메서드의 두 번째 매개변수를 사용하여 특정 세그먼트의 다른 기본값을 설정할 수도 있습니다. 기본값은 빈 문자열입니다.

<?php

// URI = http://example.com/users/15/profile

// will print 'profile'
echo $uri->getSegment(3, 'foo');
// will print 'bar'
echo $uri->getSegment(4, 'bar');
// will throw an exception
echo $uri->getSegment(5, 'baz');
// will print 'baz'
echo $uri->setSilent()->getSegment(5, 'baz');
// will print '' (empty string)
echo $uri->setSilent()->getSegment(5);

참고

마지막 +1 세그먼트를 가져올 수 있습니다. 마지막 +2 이상의 세그먼트를 가져오려고 하면 기본적으로 예외가 발생합니다. setSilent() 메서드를 사용하여 예외 발생을 방지할 수 있습니다.

전체 세그먼트 수를 가져올 수 있습니다.

<?php

$total = $uri->getTotalSegments(); // 3

마지막으로 모든 세그먼트의 배열을 가져올 수 있습니다.

<?php

$segments = $uri->getSegments();

/*
 * Produces:
 * [
 *     0 => 'users',
 *     1 => '15',
 *     2 => 'profile',
 * ]
 */

예외 발생 비활성화

기본적으로 이 클래스의 일부 메서드는 예외를 발생시킬 수 있습니다. 이를 비활성화하려면 예외 발생을 방지하는 특별한 플래그를 설정할 수 있습니다.

<?php

// Disable throwing exceptions
$uri->setSilent();

// Enable throwing exceptions (default)
$uri->setSilent(false);