컨트롤러 속성
PHP 속성은 컨트롤러 클래스와 메서드에 필터와 기타 메타데이터를 정의하는 데 사용할 수 있습니다. 이렇게 하면 설정이 영향을 받는 코드와 가까이 유지되며, 특정 컨트롤러나 메서드에 어떤 필터가 적용되는지 한눈에 더 쉽게 파악할 수 있습니다. 이는 자동 라우팅을 포함한 모든 라우팅 방식에서 동작하며, 더 견고한 라우트 선언과 자동 라우팅 사이의 기능 차이를 거의 없애 줍니다.
시작하기
컨트롤러 속성은 클래스 전체 또는 특정 메서드에 적용할 수 있습니다. 다음 예제는 컨트롤러 클래스에 Filters 속성을 적용하는 방법을 보여줍니다:
<?php
namespace App\Controllers;
use CodeIgniter\Router\Attributes\Filter;
#[Filter(by: 'auth')]
class AdminController extends BaseController
{
public function index()
{
return view('welcome_message');
}
}
이 예제에서는 Auth 필터가 AdminController의 모든 메서드에 적용됩니다.
컨트롤러의 특정 메서드에만 Filters 속성을 적용할 수도 있습니다. 이렇게 하면 특정 메서드에만 필터를 적용하고 다른 메서드는 영향을 받지 않게 할 수 있습니다. 예제는 다음과 같습니다:
<?php
namespace App\Controllers;
use CodeIgniter\Router\Attributes\Filter;
#[Filter(by: 'group', having: ['admin', 'superadmin'])]
class AdminController extends BaseController
{
#[Filter(by: 'permission', having: ['users.manage'])]
public function users()
{
// Will have 'group' filter with ['admin', 'superadmin']
// and 'permission' filter with ['users.manage']
}
}
클래스 수준과 메서드 수준의 속성은 함께 작동하여 컨트롤러 수준에서 라우트를 유연하게 관리할 수 있게 합니다.
속성 비활성화
애플리케이션에서 속성을 사용하지 않을 것이 확실하다면 app/Config/Routing.php 파일의 $useControllerAttributes 속성을 false로 설정하여 기능을 비활성화할 수 있습니다.
제공되는 속성
필터
Filters 속성을 사용하면 컨트롤러 클래스나 메서드에 적용할 하나 이상의 필터를 지정할 수 있습니다. 컨트롤러 작업 전 또는 후에 실행할 필터를 지정할 수 있으며, 필터에 매개변수를 전달할 수도 있습니다. Filters 속성 사용 예제는 다음과 같습니다:
<?php
namespace App\Controllers;
use CodeIgniter\Router\Attributes\Filter;
class HomeController extends BaseController
{
// Apply the filter by it's alias name
#[Filter(by: 'csrf')]
public function index()
{
}
// Apply a filter with arguments
#[Filter(by: 'throttle', having: ['60', '1'])]
public function api()
{
}
// Multiple filters can be applied by repeating the attribute
#[Filter(by: 'auth')]
#[Filter(by: 'csrf')]
public function admin()
{
}
}
참고
필터가 속성과 필터 설정 파일 양쪽에서 적용되면 둘 다 적용되지만, 예상하지 못한 결과가 생길 수 있습니다.
참고
필터에 적용되는 모든 매개변수는 문자열로 변환된다는 점을 기억하세요. 이 동작은 필터에만 영향을 줍니다.
제한
Restrict 속성을 사용하면 도메인, 서브도메인 또는 애플리케이션이 실행되는 환경을 기준으로 클래스나 메서드에 대한 접근을 제한할 수 있습니다. Restrict 속성 사용 예제는 다음과 같습니다:
<?php
namespace App\Controllers;
use CodeIgniter\Router\Attributes\Restrict;
// Restrict access by environment
#[Restrict(environment: ['development', '!production'])]
class HomeController extends BaseController
{
// Restrict access by hostname
#[Restrict(hostname: 'localhost')]
public function index()
{
}
// Multiple allowed hosts
#[Restrict(hostname: ['localhost', '127.0.0.1', 'dev.example.com'])]
public function devOnly()
{
}
// Restrict to subdomain, e.g. admin.example.com
#[Restrict(subdomain: 'admin')]
public function deleteItem($id)
{
}
}
캐시
Cache 속성을 사용하면 컨트롤러 메서드의 출력을 지정한 시간 동안 캐시할 수 있습니다. 초 단위 지속 시간을 지정할 수 있고, 선택적으로 캐시 키도 지정할 수 있습니다. Cache 속성 사용 예제는 다음과 같습니다:
<?php
namespace App\Controllers;
use CodeIgniter\Router\Attributes\Cache;
class HomeController extends BaseController
{
// Cache this method's response for 2 hours
#[Cache(for: 2 * HOUR)]
public function index()
{
return view('welcome_message');
}
// Custom cache key
#[Cache(for: 10 * MINUTE, key: 'custom_cache_key')]
public function custom()
{
return 'This response is cached with a custom key for 10 minutes.';
}
}
사용자 정의 속성
컨트롤러와 메서드에 메타데이터나 동작을 추가하기 위해 직접 사용자 정의 속성을 만들 수도 있습니다. 사용자 정의 속성은 CodeIgniter\Router\Attributes\RouteAttributeInterface 인터페이스를 구현해야 합니다. 다음은 응답에 사용자 정의 헤더를 추가하는 사용자 정의 속성의 예제입니다:
<?php
namespace App\Attributes;
use Attribute;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Router\Attributes\RouteAttributeInterface;
/**
* Custom Header Attribute
*
* Adds custom headers to the response. This is useful for:
* - Adding security headers
* - Setting API version information
* - Adding custom metadata to responses
*/
#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
class AddHeader implements RouteAttributeInterface
{
/**
* @param string $name The header name
* @param string $value The header value
*/
public function __construct(
private readonly string $name,
private readonly string $value,
) {
}
/**
* Called before the controller method executes.
* Return null to continue to the controller.
*/
public function before(RequestInterface $request): RequestInterface|ResponseInterface|null
{
// We don't need to do anything before the controller runs
return null;
}
/**
* Called after the controller method executes.
* Add the custom header to the response.
*/
public function after(RequestInterface $request, ResponseInterface $response): ?ResponseInterface
{
$response->setHeader($this->name, $this->value);
return $response;
}
}
그다음에는 이 사용자 정의 속성을 내장 속성과 마찬가지로 컨트롤러 클래스나 메서드에 적용할 수 있습니다:
<?php
namespace App\Controllers;
use App\Attributes\AddHeader;
use CodeIgniter\Controller;
use CodeIgniter\Router\Attributes\Cache;
class Api extends Controller
{
/**
* Add a single custom header
*/
#[AddHeader('X-API-Version', '2.0')]
public function userInfo()
{
return $this->response->setJSON([
'name' => 'John Doe',
'email' => 'john@example.com',
]);
}
/**
* Add multiple custom headers using the IS_REPEATABLE attribute option.
* Each AddHeader attribute will be executed in order.
*/
#[AddHeader('X-API-Version', '2.0')]
#[AddHeader('X-Rate-Limit', '100')]
#[AddHeader('X-Content-Source', 'cache')]
public function statistics()
{
return $this->response->setJSON([
'users' => 1500,
'posts' => 3200,
]);
}
/**
* Combine custom attributes with built-in attributes.
* The Cache attribute will cache the response,
* and AddHeader will add the custom header.
*/
#[AddHeader('X-Powered-By', 'My Custom API')]
#[Cache(for: 3600)]
public function dashboard()
{
return $this->response->setJSON([
'status' => 'operational',
'uptime' => '99.9%',
]);
}
}