4.3.8에서 4.4.0으로 업그레이드

설치 방법에 맞는 업그레이드 지침을 참조하십시오.

보안

$this->validate() 사용 시

컨트롤러의 $this->validate()에 유효성 검사를 우회할 수 있는 잠재적 취약점이 있었습니다. 이 공격은 개발자가 유효성 검사를 통과하지 못한 빈 데이터를 검사가 완료된 것으로 잘못 해석하고 처리를 진행하도록 허용할 수 있었습니다.

유효성 검사를 통과한 데이터를 확실히 가져올 수 있도록 Validation::getValidated()메서드가 추가되었습니다.

따라서 컨트롤러에서 $this->validate()를 사용할 때는 유효성 검사를 통과한 데이터를 가져오기 위해 새로운 Validation::getValidated() 메서드를 사용해야 합니다.

// In Controller.

if (! $this->validateData($data, [
    'username' => 'required',
    'password' => 'required|min_length[10]',
])) {
    // The validation failed.
    return view('login', [
        'errors' => $this->validator->getErrors(),
    ]);
}

// The validation was successful.

// Get the validated data.
$validData = $this->validator->getValidated();

주요 변경사항

URI::setSegment() 변경

버그로 인해 이전 버전에서는 마지막 세그먼트에 +2를 지정해도 예외가 발생하지 않았습니다. 이 버그가 수정되었습니다.

코드가 이 버그에 의존하는 경우 세그먼트 번호를 수정하십시오.

// URI: http://example.com/one/two

// Before:
$uri->setSegment(4, 'three');
// The URI will be http://example.com/one/two/three

// After:
$uri->setSegment(4, 'three'); // Will throw Exception
$uri->setSegment(3, 'three');
// The URI will be http://example.com/one/two/three

사이트 URI 변경

  • 현재 URI 판별 방식이 재작업되었으므로 프레임워크가 사이트 URI 또는 URI 경로를 이전 버전과 약간 다르게 반환할 수 있습니다. 이로 인해 테스트 코드가 실패할 수 있습니다. 기존 테스트가 실패하면 단언문을 업데이트하십시오.

  • baseURL에 하위 디렉터리가 있고 URI::getPath() 메서드로 현재 URI의 baseURL에 대한 상대 경로를 가져오는 경우, 대신 새로운 SiteURI::getRoutePath() 메서드를 사용해야 합니다.

자세한 내용은 사이트 URI 변경를 참조하십시오.

예외를 확장할 때

CodeIgniter\Debug\Exceptions를 확장하면서 exceptionHandler() 메서드를 오버라이드하지 않은 경우, app/Config/Exceptions.php에 새로운 Config\Exceptions::handler() 메서드를 정의하면 지정된 예외 핸들러가 실행됩니다.

오버라이드한 코드는 더 이상 실행되지 않으므로, 자체 예외 핸들러를 정의하여 필요한 변경을 하십시오.

자세한 내용은 사용자 정의 예외 처리기를 참조하십시오.

자동 라우팅(개선됨)과 translateURIDashes

자동 라우팅(개선됨)을 사용하고 $translateURIDashes가 true ($routes->setTranslateURIDashes(true))인 경우, 이전 버전에서는 버그로 인해 하이픈을 사용하는 URI(예: foo-bar)와 밑줄을 사용하는 URI(예: foo_bar)가 하나의 컨트롤러 메서드에 대응되었습니다.

이 버그가 수정되어 밑줄을 사용하는 URI(foo_bar)에는 더 이상 접근할 수 없습니다.

밑줄 URI(foo_bar)로의 링크가 있다면 하이픈 URI(foo-bar)로 업데이트하십시오.

Factories에 네임스페이스가 포함된 클래스명을 전달할 때

Factories에 네임스페이스가 포함된 클래스명을 전달하는 동작이 변경되었습니다. 자세한 내용은 변경 로그를 참조하십시오.

model(\Myth\Auth\Models\UserModel::class) 또는 model('Myth\Auth\Models\UserModel')와 같은 코드(서드파티 패키지에 있을 수 있음)가 있고 App\Models\UserModel을 로드하려는 경우, 해당 클래스가 처음 로드되기 전에 로드할 클래스명을 정의해야 합니다:

Factories::define('models', 'Myth\Auth\Models\UserModel', 'App\Models\UserModel');

자세한 내용은 로드할 클래스 이름 정의를 참조하십시오.

인터페이스 변경사항

일부 인터페이스가 변경되었습니다. 이를 구현하는 클래스는 변경사항을 반영하여 API를 업데이트해야 합니다. 자세한 내용은 인터페이스 변경를 참조하십시오.

메서드 시그니처 변경사항

일부 메서드 시그니처가 변경되었습니다. 이를 확장하는 클래스는 변경사항을 반영하여 API를 업데이트해야 합니다. 자세한 내용은 메서드 시그니처 변경를 참조하십시오.

또한 일부 생성자와 Services::security()의 매개변수 타입이 변경되었습니다. 매개변수를 전달하여 호출하는 경우 매개변수 값을 변경하십시오. 자세한 내용은 매개변수 타입 변경를 참조하십시오.

RouteCollection::$routes

성능 향상을 위해 보호된(protected) 속성 $routes의 배열 구조가 변경되었습니다.

RouteCollection을 확장하고 $routes를 사용하는 경우, 새로운 배열 구조에 맞게 코드를 업데이트하십시오.

필수 파일 변경사항

index.php 및 spark

다음 파일들은 중요한 변경사항이 있으므로 업데이트된 버전을 반드시 애플리케이션에 병합해야 합니다:

중요

위 파일들을 업데이트하지 않으면 composer update 실행 후 CodeIgniter가 제대로 동작하지 않습니다.

업그레이드 절차의 예는 다음과 같습니다:

composer update
cp vendor/codeigniter4/framework/public/index.php public/index.php
cp vendor/codeigniter4/framework/spark spark

설정 파일

app/Config/App.php

$proxyIPs 속성은 배열이어야 합니다. 프록시 서버를 사용하지 않는 경우 public array $proxyIPs = [];로 설정해야 합니다.

app/Config/Routing.php

라우팅 시스템 정리를 위해 다음과 같은 변경이 이루어졌습니다:

  • Routes 파일에 있던 설정을 담는 새로운 app/Config/Routing.php 파일이 추가되었습니다.

  • app/Config/Routes.php 파일이 단순화되어 설정 및 불필요한 내용 없이 라우트만 포함하도록 변경되었습니다.

  • 환경별 라우트 파일은 더 이상 자동으로 로드되지 않습니다.

따라서 다음을 수행해야 합니다:

  1. 새 프레임워크에서 app/Config/Routing.php를 복사하여 app/Config 디렉터리에 넣고 설정하십시오.

  2. app/Config/Routes.php에서 더 이상 필요하지 않은 모든 설정을 제거하십시오.

  3. 환경별 라우트 파일을 사용하는 경우, app/Config/Routing.php$routeFiles 속성에 추가하십시오.

app/Config/Toolbar.php

핫 리로딩를 위해 새로운 속성 $watchedDirectories$watchedExtensions를 추가해야 합니다:

--- a/app/Config/Toolbar.php
+++ b/app/Config/Toolbar.php
@@ -88,4 +88,31 @@ class Toolbar extends BaseConfig
      * `$maxQueries` defines the maximum amount of queries that will be stored.
      */
     public int $maxQueries = 100;
+
+    /**
+     * --------------------------------------------------------------------------
+     * Watched Directories
+     * --------------------------------------------------------------------------
+     *
+     * Contains an array of directories that will be watched for changes and
+     * used to determine if the hot-reload feature should reload the page or not.
+     * We restrict the values to keep performance as high as possible.
+     *
+     * NOTE: The ROOTPATH will be prepended to all values.
+     */
+    public array $watchedDirectories = [
+        'app',
+    ];
+
+    /**
+     * --------------------------------------------------------------------------
+     * Watched File Extensions
+     * --------------------------------------------------------------------------
+     *
+     * Contains an array of file extensions that will be watched for changes and
+     * used to determine if the hot-reload feature should reload the page or not.
+     */
+    public array $watchedExtensions = [
+        'php', 'css', 'js', 'html', 'svg', 'json', 'env',
+    ];
 }

app/Config/Events.php

핫 리로딩를 위한 라우트를 추가하는 코드를 넣어야 합니다:

--- a/app/Config/Events.php
+++ b/app/Config/Events.php
@@ -4,6 +4,7 @@ namespace Config;

 use CodeIgniter\Events\Events;
 use CodeIgniter\Exceptions\FrameworkException;
+use CodeIgniter\HotReloader\HotReloader;

 /*
  * --------------------------------------------------------------------
@@ -44,5 +45,11 @@ Events::on('pre_system', static function () {
     if (CI_DEBUG && ! is_cli()) {
         Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect');
         Services::toolbar()->respond();
+        // Hot Reload route - for framework use on the hot reloader.
+        if (ENVIRONMENT === 'development') {
+            Services::routes()->get('__hot-reload', static function () {
+                (new HotReloader())->run();
+            });
+        }
     }
 });

app/Config/Security.php

app/Config/App.php의 CSRF 설정 항목은 더 이상 사용되지 않습니다.

  1. 새 프레임워크에서 app/Config/Security.php를 복사하여 app/Config 디렉터리에 넣고 설정하십시오.

  2. app/Config/App.php에서 $CSRFTokenName부터 $CSRFSameSite까지의 속성을 제거하십시오.

app/Config/Session.php

app/Config/App.php의 세션 설정 항목은 더 이상 사용되지 않습니다.

  1. 새 프레임워크에서 app/Config/Session.php를 복사하여 app/Config 디렉터리에 넣고 설정하십시오.

  2. app/Config/App.php에서 $sessionDriver부터 $sessionDBGroup까지의 속성을 제거하십시오.

주요 변경을 수반하는 개선사항

  • 라우팅: RouteCollection::__construct()의 메서드 시그니처가 변경되었습니다. 세 번째 매개변수 Routing $routing이 추가되었습니다. LSP를 위반하지 않으려면 확장 클래스도 동일하게 매개변수를 추가해야 합니다.

  • 유효성 검사: Validation::check()의 메서드 시그니처가 변경되었습니다. $rule 매개변수의 string 타입힌트가 제거되었습니다. LSP를 위반하지 않으려면 확장 클래스도 동일하게 타입힌트를 제거해야 합니다.

프로젝트 파일

프로젝트 공간 (root, app, public, writable)의 일부 파일이 업데이트되었습니다. 이 파일들은 system 범위 밖에 있으므로 직접 변경하지 않으면 수정되지 않습니다.

프로젝트 공간의 변경사항 병합을 도와주는 서드파티 CodeIgniter 모듈이 있습니다: Packagist에서 찾기.

콘텐츠 변경사항

다음 파일들은 중요한 변경사항(사용 중단 또는 시각적 조정 포함)이 있으므로 업데이트된 버전을 애플리케이션에 병합하는 것을 권장합니다:

설정

  • app/Config/CURLRequest.php
  • app/Config/Exceptions.php

모든 변경사항

다음은 프로젝트 공간에서 변경된 모든 파일 목록입니다. 많은 파일들이 런타임에 영향을 미치지 않는 단순한 주석이나 형식 변경입니다:

  • app/Config/App.php

  • app/Config/CURLRequest.php

  • app/Config/Cookie.php

  • app/Config/Database.php

  • app/Config/Events.php

  • app/Config/Exceptions.php

  • app/Config/Filters.php

  • app/Config/Routes.php

  • app/Config/Routing.php

  • app/Config/Toolbar.php

  • public/index.php

  • spark