PHP 7.4에는 유형 속성이 추가되었으며 PHP 유형 시스템이 크게 개선되었습니다. 이러한 변경 사항은 전적으로 선택 사항이며 이전 버전을 손상시키지 않습니다.
이 기사에서는 이 기능을 더 자세히 살펴보겠지만 먼저 가장 중요한 사항을 요약해 보겠습니다.
● PHP 7.4부터 사용할 수 있습니다.
● 클래스에서만 사용할 수 있으며 액세스 한정자가 필요합니다: public, protected 또는 private; 또는 var.
● void 및 callable을 제외한 모든 유형이 허용됩니다
실제 상황은 다음과 같습니다.
class Foo { public int $a; public ?string $b = 'foo'; private Foo $prop; protected static string $static = 'default'; }
#Uninitialized
흥미롭게 보기 계속하기 전에 먼저 유형 속성의 중요한 측면에 대해 논의해 보겠습니다.
처음 보는 내용에도 불구하고 다음 코드는 유효합니다:
class Foo { public int $bar; } $foo = new Foo;
$bar의 값이 정수가 아니더라도 Foo 개체를 만든 후 PHP는 $bar가 Visit인 경우에만 오류를 발생시킵니다.
var_dump($foo->bar); Fatal error: Uncaught Error: Typed property Foo::$bar must not be accessed before initialization
오류 메시지에서 볼 수 있듯이 초기화되지 않은 새로운 "변수 상태"가 있습니다.
$bar에 유형이 없으면 해당 값은 null이 됩니다. 그러나 유형은 null일 수 있으므로 null 유형의 속성이 설정되었는지 아니면 단순히 잊어버렸는지 알 수 있는 방법이 없습니다. 그래서 "초기화되지 않음"이 추가되었습니다.
초기화 해제에 관해 기억해야 할 네 가지 사항:
● 초기화되지 않은 속성은 읽을 수 없으며, 그렇게 하면 치명적인 오류가 발생합니다.
● 속성에 접근할 때 초기화되지 않은 상태를 확인하기 때문에 해당 유형이 nullable이 아니더라도 초기화되지 않은 속성을 사용하여 객체를 생성할 수 있습니다.
● 초기화되지 않은 속성에 먼저 쓴 다음 읽을 수 있습니다.
● 유형이 지정된 속성에 unset을 사용하면 초기화가 취소되고, 유형이 지정되지 않은 속성을 설정하지 않으면 null이 됩니다.
특히, 다음 코드는 객체를 생성한 후 초기화되지 않고 null을 허용하지 않는 속성이 설정된 경우에 유효하다는 점에 유의하세요
class Foo { public int $a; } $foo = new Foo; $foo->a = 1;
초기화되지 않은 상태는 속성 값을 읽을 때만 확인하지만, 작성할 때는 확인하지 않습니다. 속성 값에 대해 유형 유효성 검사가 수행됩니다. 이는 유효하지 않은 유형이 속성 값으로 끝나지 않도록 할 수 있음을 의미합니다.
#기본값 및 생성자
입력된 값을 초기화하는 방법을 자세히 살펴보겠습니다. 스칼라 유형의 경우 기본값이 제공될 수 있습니다.
class Foo { public int $bar = 4; public ?string $baz = null; public array $list = [1, 2, 3]; }
유형이 실제로 비어 있는 경우에만 null을 기본값으로 사용할 수 있습니다. 이는 당연한 것처럼 보이지만 매개변수 기본값에는 다음을 허용하는 일부 오래된 동작이 있습니다.
function passNull(int $i = null) { /* … */ } passNull(null);
다행히도 유형 속성은 이러한 혼란스러운 동작을 허용하지 않습니다.
또한 개체나 클래스 유형에는 기본값을 가질 수 없다는 점에 유의하세요. 기본값을 설정하려면 생성자를 사용해야 합니다.
입력된 값을 초기화하는 확실한 장소는 물론 생성자입니다.
class Foo{ private int $a; public function __construct(int $a) { $this->a = $a; } }
하지만 앞서 언급한 내용도 기억하세요. 생성자 외부에서 초기화되지 않은 속성을 작성하는 것은 유효합니다. 속성에서 아무것도 읽지 않는 한 초기화되지 않은 검사는 수행되지 않습니다.
#TYPES OF TYPES
그렇다면 정확히 무엇을 입력할 수 있고 어떻게 입력할 수 있는지 이미 언급한 대로 입력된 속성은 클래스 내에서만 작동하며 앞에는 액세스 한정자나 var 키워드가 필요합니다.
사용 가능한 유형은 void 및 callable을 제외한 거의 모든 유형을 사용할 수 있습니다.
void는 값이 없음을 의미하므로 입력된 값에 사용하지 않는 것이 합리적입니다. 호출 가능은 약간 다릅니다.
Visible, "callable"은 다음과 같이 작성할 수 있습니다:
하지만 앞서 언급한 내용도 기억하세요. 생성자 외부에서 초기화되지 않은 속성을 작성하는 것은 유효합니다. 속성에서 아무것도 읽지 않는 한 초기화되지 않은 검사는 수행되지 않습니다.
참고로, PHP의 "호출 가능"은 다음과 같이 작성할 수 있습니다:
$callable = [$this, 'method'];
다음과 같은 (잘못된) 코드가 있다고 가정해 보겠습니다:
class Foo { public callable $callable; public function __construct(callable $callable) { /* … */ } } class Bar { public Foo $foo; public function __construct() { $this->foo = new Foo([$this, 'method']) } private function method() { /* … */ } } $bar = new Bar; ($bar->foo->callable)();
이 경우 $callable은 비공개 Bar:: 메서드를 참조하지만 사용됩니다. Foo 호출의 맥락에서. 이 문제로 인해 호출 가능 지원을 추가하지 않기로 결정되었습니다.
Closure는 유효한 유형이고 그것이 생성된 $this 컨텍스트를 기억할 것이기 때문에 이것은 큰 문제가 아닙니다.
그런데 사용 가능한 모든 유형의 목록은 다음과 같습니다.
● bool
● int
● float
● string
● array
● iterable
● object
● ?
● self & parent
● 클래스 및 인터페이스
# 강제 및 엄격한 타이핑
PHP는 우리가 좋아하고 싫어하는 동적 언어이며 가능할 때마다 유형을 캐스팅합니다. 정수가 필요한 문자열을 전달한다고 가정하면 PHP는 자동으로 문자열을 변환하려고 시도합니다.
function coerce(int $i) { /* … */ } coerce('1'); // 1
동일한 원칙이 유형 속성에도 적용됩니다.
아래 코드는 유효하며 "1"을 1로 변환합니다.
class Bar { public int $i; } $bar = new Bar; $bar->i = '1'; // 1
이 동작이 마음에 들지 않으면 엄격한 타이핑을 선언하여 비활성화할 수 있습니다.
declare(strict_types=1); $bar = new Bar; $bar->i = '1'; // 1 Fatal error: Uncaught TypeError: Typed property Bar::$i must be int, string used
#Type Differences and Inheritance
PHP 7.4에서 향상된 유형 차이가 도입되었음에도 불구하고 유형 속성은 변경되지 않습니다.
이는 다음이 유효하지 않음을 의미합니다.
class A {} class B extends A {} class Foo { public A $prop; } class Bar extends Foo { public B $prop; } Fatal error: Type of Bar::$prop must be A (as in class Foo)
위의 예가 중요하지 않은 경우 다음을 살펴봐야 합니다.
class Foo { public self $prop; } class Bar extends Foo { public self $prop; }
뒤에서 PHP는 실행하기 전에 참조하는 구체적인 클래스로 self를 대체합니다. 코드.
这意味着在本例中会抛出相同的错误。处理它的唯一方法,是执行以下操作:
class Foo { public Foo $prop; } class Bar extends Foo { public Foo $prop; }
说到继承,您可能会发现很难找到任何好的用例来覆盖继承属性的类型。
虽然我同意这种观点,但值得注意的是,可以更改继承属性的类型,但前提是访问修饰符也从private更改为protected或public。
以下代码有效:
class Foo{ private int $prop; } class Bar extends Foo { public string $prop; }
但是,不允许将类型从可为空的类型更改为不可为空或反向的类型。
class Foo { public int $a; public ?int $b; } class Bar extends Foo { public ?int $a; public int $b; } Fatal error: Type of Bar::$a must be int (as in class Foo)
翻译:https://stitcher.io/blog/typed-properties-in-php-74
위 내용은 PHP 7.4의 유형화된 속성의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!