PHP 8 ์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ - ํŠน์„ฑ(Attribute)

๊ฐœ์š”

Attribute ๋Š” ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ(meta data)๋‚˜ ์„ ์–ธ์  ์ •๋ณด(declarative information)๋ฅผ ์ฝ”๋“œ์™€ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

Java ์—์„œ๋Š” annotation ์ด๋ผ๊ณ  ๋ถ€๋ฅด๋ฉฐ C# ์—์„œ๋Š” PHP ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Attribute ๋กœ ๋ช…๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.


Attribute ๋ฅผย ์†์„ฑ์ด๋ผ๊ณ  ๋ฒˆ์—ญํ•œ ๊ณณ๋„ ์žˆ๋˜๋ฐ ์†์„ฑ์€ property ์™€ ์˜๋ฏธ๊ฐ€ ๊ฒน์น˜๋ฏ€๋กœ ์ ๋‹นํ•œ ์šฉ์–ด๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ์ˆ  ๋ฒˆ์—ญ์˜ ๋ ˆํผ๋Ÿฐ์Šค์ธ Microsoft ์˜ ์–ธ์–ด ํฌํ„ธ ์‚ฌ์ดํŠธ๋ฅผ ๋ณด๋ฉด attribute ๋ฅผ 'ํŠน์„ฑ' ์œผ๋กœ ๋ฒˆ์—ญํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ œ๊ฐ€ ์ƒ๊ฐํ•˜๊ธฐ์—๋„ ์†์„ฑ๋ณด๋‹ค๋Š” ํŠน์„ฑ์ด ๋” ์ ๋‹นํ•œ ๋‹จ์–ด๊ฐ™์œผ๋ฏ€๋กœ ์ด ๊ธ€์—์„œ๋„ Attribute ๋ฅผ ํŠน์„ฑ์ด๋ผ๊ณ  ์ง€์นญํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


PHP ์˜ attribute ๋Š” class, method, variable, parameter ๋“ฑ์— ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ compiler time ๊ณผ runtime ์— attribute ๋ฅผ ์ด์šฉํ•ด์„œ ํŠน๋ณ„ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋กœ PHPStorm ์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋ถˆ๋ณ€ ์†์„ฑ์„ ๊ฐ€์ง„ ๋ณ€์ˆ˜์— ๋Œ€ํ•ด ์•„๋ž˜์™€ ๊ฐ™์ด attribute ๋ฅผ ์ง€์ •ํ•˜๋ฉด ์ˆ˜์ •ํ•  ๊ฒฝ์šฐ IDE ์—์„œ ๊ฐ์ง€ํ•ด์„œ ์—๋Ÿฌ๋ฅผ ํ‘œ์‹œํ•˜๋ฏ€๋กœ ์ฝ”๋”ฉ ์‹ค์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<?php

use JetBrains\PhpStorm\Immutable;

class MyClass
{
    #[Immutable]
    private int $read_only_var;

    public function setValue(int $value): void
    {
        $this->read_only_var = $value;
    }
}

๊ธฐ์กด์— docblocks ์— @ ๋ฅผ ์‚ฌ์šฉํ•ด์„œ annotation ์„ ๋‹ฌ ๊ฒฝ์šฐ ์˜คํƒ€๋ฅผ ๋‚ด๊ฑฐ๋‚˜ ์—†๋Š” annotation ์„ ์‚ฌ์šฉํ•ด๋„ ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ ์ฃผ์„์ด๋ฏ€๋กœ IDE ์—์„œ ์—๋Ÿฌ๋ฅผ ๊ฐ์ง€ํ•˜์ง€ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค.

Attribute ๋Š” ๊ธฐ์กด์— docblocks ์‚ฌ์šฉํ•œ ์ฃผ์„์— ๋น„ํ•ด ํŒŒ์‹ฑ ๋ฐ ๋ถ„์„์ด ์šฉ์ดํ•˜๋ฏ€๋กœ PHPStorm ๊ฐ™์€ IDE ๊ฐ€ ๋” ์ •ํ™•ํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋ฉฐ phpstan ์ด๋‚˜ psalm ๊ฐ™์€ ์ •์  ๋ถ„์„๊ธฐ๊ฐ€ ๋” ์ •๊ตํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ docblocks ์ฃผ์„์„ ๋ฉ”๋ชจ๋ฆฌ๊นŒ์ง€ ๋กœ๋”ฉํ•ด์•ผ ํ–ˆ๋˜ ๊ธฐ์กด ๋ฐฉ์‹์— ๋น„ํ•ด JIT ์œผ๋กœ ์ตœ์ ํ™”๊ฐ€ ์šฉ์ดํ•˜๊ณ  Run time ์— Reflection ์„ ๋” ๋น ๋ฅด๊ฒŒ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์‹คํ–‰ ์‹œ๊ฐ„๋„ ๋” ์งง์•„์ง€์ง€ ์•Š์„๊นŒ ์ถ”์ธกํ•ฉ๋‹ˆ๋‹ค.


Symfony ๋‚˜ Doctrine ๊ฐ™์€ ์œ ๋ช…ํ•œ PHP Framework ๋„ Attribute ๋ฅผ ์ง€์›ํ•˜๋„๋ก ์ˆ˜์ •๋˜์—ˆ๊ณ  psalm ์ด๋‚˜ phpstan ๋„ Attribute ๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฒ„์ „์„ ๋ฐœํ‘œํ–ˆ์œผ๋ฏ€๋กœ Attribute ์„ ์ž˜ ํ™œ์šฉํ•ด์„œ ์ข‹์€ ํ’ˆ์งˆ์˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋„๋ก ์—ฐ์Šต์ด ํ•„์š”ํ•œ ์‹œ์ ์ž…๋‹ˆ๋‹ค.


๋งŒ์•ฝ attribute ์˜ ํ•„์š”์„ฑ๊ณผ ํ™œ์šฉ ๋ฐฉ๋ฒ•์ด ์ž˜ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด C# ์ด๋‚˜ Java ์—์„œ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์„ ์ฐพ์•„ ๋ณด๋Š” ๊ฒƒ๋„ ๋งŽ์€ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

ํŠนํžˆ Spring framework ๋ฅผ ์ž˜ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์–ด์ง€๋Ÿฌ์šธ ์ •๋„๋กœ ์ˆ˜๋งŽ์€ annotation ์„ ํ™œ์šฉํ•œ meta programming ๊ธฐ๋ฒ•์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ๋ฒ•

PHP ๋Š” ํŠน์„ฑ์„ ๋ถ€์—ฌํ•˜๋Š” ๋ฌธ๋ฒ•์œผ๋กœ #[Attr] ์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์ด๊ฑธ๋กœ ๊ฒฐ์ •ํ•˜๊ธฐ๊นŒ์ง€ ์—ฌ๋Ÿฌ ์šฐ์—ฌ ๊ณก์ ˆ์ด ์žˆ์—ˆ๋‚˜ ๋ด…๋‹ˆ๋‹ค.(PHP Annotated โ€“ August 2020 (haah.kr)ย ์ฐธ๊ณ )


use App\Attributes\ExampleAttribute;

#[ExampleAttribute]
class Foo
{
    #[ExampleAttribute]
    public const FOO = 'foo';
 
    #[ExampleAttribute]
    public $x;
 
    #[ExampleAttribute]
    public function foo(#[ExampleAttribute] $bar) { }
}


Laravel 8์€ PHP 7.3 ๋ถ€ํ„ฐ ์ง€์›ํ•˜๋ฏ€๋กœ Attribute ๋ฅผ ์ œ๋Œ€๋กœ ์ง€์›ํ•˜๊ณ  ์žˆ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  PHP 8 ๋กœ ๋ผ๋ผ๋ฒจ์„ ๊ตฌ๋™ํ•  ๊ฒฝ์šฐ Attribute ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์˜ˆ๋กœ PHP 8 ์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋ผ๋ผ๋ฒจ ๋ผ์šฐํŒ…์„ Attribute ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ํŒจํ‚ค์ง€์ธ spatie/laravel-route-attributes ๋ฅผ ์ด์šฉํ•ด์„œ ๋ผ์šฐํŒ…์„ ๊ด€๋ฆฌํ•ด ์ค˜๋„ ๋ฉ๋‹ˆ๋‹ค.

๊ฐ™์ด ๋ณด๊ธฐ

Ref