본문 바로가기

PHP & Laravel

PHP 8의 Constructor Property Promotion과 Laravel에서의 코드 간소화

반응형

PHP 8의 Constructor Property Promotion과 Laravel에서의 코드 간소화

 

PHP 8에서는 객체 생성 시 생성자에서의 속성 선언과 할당을 간소화할 수 있는 Constructor Property Promotion(생성자 프로퍼티 승격) 기능이 도입되었습니다. 이를 활용하면 Laravel 애플리케이션에서 모델, 서비스 클래스, DTO(Data Transfer Object) 등의 코드 가독성과 유지보수성을 크게 향상할 수 있습니다.

 

이 글에서는 Constructor Property Promotion의 개념, 기존 방식과의 비교, Laravel에서의 활용법 및 주의할 점을 살펴보겠습니다.

 

1. PHP 8의 Constructor Property Promotion이란?

 

PHP 8 이전에는 클래스의 속성을 선언하고 생성자에서 값을 할당해야 했습니다. 그러나 PHP 8에서는 생성자에서 직접 속성을 선언하고 값을 할당하는 방식을 지원하여 코드가 간결해졌습니다.

 

1.1 기존 방식(PHP 7 이하)

 

class User {

    private string $name;

    private string $email;



    public function __construct(string $name, string $email) {

        $this->name = $name;

        $this->email = $email;

    }

}

 

객체 생성:

 

$user = new User('Alice', 'alice@example.com');

 

1.2 PHP 8의 새로운 방식

 

PHP 8에서는 생성자에서 직접 속성을 정의할 수 있습니다.

 

class User {

    public function __construct(

        private string $name,

        private string $email

    ) {}

}

객체 생성:

 

$user = new User('Alice', 'alice@example.com');

 

장점:

불필요한 코드 제거

클래스가 더 간결해짐

유지보수가 쉬워짐

 

2. Laravel에서의 Constructor Property Promotion 활용

 

Laravel 애플리케이션에서는 다음과 같은 부분에서 Constructor Property Promotion을 효과적으로 활용할 수 있습니다.

1. Eloquent 모델의 데이터 관리

2. 서비스 클래스에서의 의존성 주입

3. DTO(Data Transfer Object) 적용

4. 테스트 코드 간소화

 

2.1 Eloquent 모델에서의 활용

 

Laravel의 Eloquent 모델에서는 기본적으로 속성을 선언하지 않지만, 서비스 계층이나 비즈니스 로직에서 유용하게 활용할 수 있습니다.

 

기존 방식:

 

class UserProfile {

    private User $user;

    private string $bio;



    public function __construct(User $user, string $bio) {

        $this->user = $user;

        $this->bio = $bio;

    }

}

 

PHP 8 방식:

 

class UserProfile {

    public function __construct(

        private User $user,

        private string $bio

    ) {}

}

 

2.2 서비스 클래스에서의 의존성 주입

 

Laravel의 서비스 클래스에서는 의존성을 주입할 때 Constructor Property Promotion을 사용하면 코드를 더 간결하게 만들 수 있습니다.

 

기존 방식:

 

class UserService {

    private UserRepository $repository;



    public function __construct(UserRepository $repository) {

        $this->repository = $repository;

    }



    public function getAllUsers() {

        return $this->repository->getAll();

    }

}

 

PHP 8 방식:

 

class UserService {

    public function __construct(private UserRepository $repository) {}



    public function getAllUsers() {

        return $this->repository->getAll();

    }

}

장점:

불필요한 코드 제거

의존성 주입이 더욱 직관적

 

2.3 DTO(Data Transfer Object) 적용

 

DTO 패턴을 적용할 때 Constructor Property Promotion을 활용하면 데이터 전달이 더 간편해집니다.

 

class CreateUserDTO {

    public function __construct(

        public string $name,

        public string $email,

        public string $password

    ) {}

}

 

컨트롤러에서 활용:

 

public function store(Request $request) {

    $userData = new CreateUserDTO(

        name: $request->input('name'),

        email: $request->input('email'),

        password: bcrypt($request->input('password'))

    );



    User::create([...get_object_vars($userData)]);

}

 

장점:

간편한 객체 생성 및 활용

입력 데이터 검증과 분리된 책임 유지

 

2.4 테스트 코드에서의 활용

 

테스트 코드에서 의존성을 간편하게 주입할 수 있습니다.

 

class OrderTest extends TestCase {

    public function __construct(

        private OrderService $orderService

    ) {}



    public function test_order_creation() {

        $order = $this->orderService->createOrder(['product_id' => 1]);

        $this->assertNotNull($order);

    }

}

 

3. Constructor Property Promotion 사용 시 주의할 점

 

3.1 프로퍼티 가시성 설정 주의

private, public, protected 가시성을 반드시 지정해야 합니다.

기본적으로 private을 사용하고 필요 시 public을 활용합니다.

 

예제:

 

public function __construct(

    public string $name,   // 공용

    private string $email  // 비공개

) {}

 

3.2 상속 관계에서의 활용 제한

상속된 클래스에서 생성자 오버라이딩 시 혼란을 방지해야 합니다.

부모 클래스의 생성자 호출이 필요한 경우 명확히 지정합니다.

 

class ParentClass {

    public function __construct(protected string $title) {}

}



class ChildClass extends ParentClass {

    public function __construct(string $title, private int $age) {

        parent::__construct($title);

    }

}

 

3.3 단일 책임 원칙(SRP) 준수

생성자에서 비즈니스 로직을 추가하지 말고, 단순 속성 초기화에 집중해야 합니다.

데이터 검증은 별도의 메서드에서 수행하도록 합니다.

 

4. 결론

 

PHP 8의 Constructor Property Promotion 기능을 활용하면 Laravel 애플리케이션에서 코드를 간결하게 유지하면서도 더 명확하고 유지보수하기 쉬운 아키텍처를 만들 수 있습니다.

 

핵심 요약:

속성을 생성자에서 바로 선언 및 할당 가능

Laravel의 서비스, 모델, DTO에 적용 시 큰 효율성 제공

코드의 가독성과 유지보수성을 대폭 향상

 

Laravel 프로젝트에서 PHP 8의 최신 기능을 적극 활용해 보세요!

 

반응형