유형 선언(Type declarations)

유형 선언은 함수 인수, 반환 값 및 PHP 7.4.0부터 클래스 속성에 추가할 수 있습니다. 호출 시 값이 지정된 유형인지 확인합니다. 그렇지 않으면 TypeError가 발생합니다.

메모: 부모 메서드를 재정의할 때 자식 메서드는 부모의 반환 형식 선언과 일치해야 합니다. 부모가 반환 유형을 정의하지 않으면 자식 메서드가 그렇게 할 수 있습니다.

Single types
Type Description Version
Class/interface name 값은 지정된 클래스 또는 인터페이스의 instanceof여야 합니다.  
self 값은 유형 선언이 사용된 것과 동일한 클래스의 instanceof여야 합니다. 클래스에서만 사용할 수 있습니다.  
parent 값은 형식 선언이 사용되는 클래스의 부모 instanceof여야 합니다. 클래스에서만 사용할 수 있습니다.  
array 값은 배열이어야 합니다.  
callable 값은 유효한 callable이어야 합니다. 클래스 속성 유형 선언으로 사용할 수 없습니다.  
bool 값은 부울 값이어야 합니다.  
float 값은 부동 소수점 숫자여야 합니다.  
int 값은 정수여야 합니다.  
string 값은 문자열이어야 합니다.  
iterable 값은 배열 또는 Traversableinstanceof여야 합니다. PHP 7.1.0
object 값은 객체여야 합니다. PHP 7.2.0
mixed 값은 모든 값이 될 수 있습니다. PHP 8.0.0

경고 위의 스칼라 유형에 대한 별칭은 지원되지 않습니다. 대신 클래스 또는 인터페이스 이름으로 처리됩니다. 예를 들어, 부울을 유형 선언으로 사용하려면 값이 부울 유형이 아니라 클래스 또는 인터페이스 부울instanceof여야 합니다.

                    
  <?php
      function test(boolean $param) {}
      test(true);
  ?>
                    
                  

PHP 8에서 위 예제의 출력:

Warning: "boolean" will be interpreted as a class name. Did you mean "bool"? Write "\boolean" to suppress this warning in /in/9YrUX on line 2

Fatal error: Uncaught TypeError: test(): Argument #1 ($param) must be of type boolean, bool given, called in - on line 3 and defined in -:2
Stack trace:
#0 -(3): test(true)
#1 {main}
  thrown in - on line 2
                  
mixed

mixedunion type object|resource|array|string|int|float|bool|null과 동일합니다. PHP 8.0.0부터 사용 가능합니다.

Examples

예제 #1 기본 클래스 유형 선언

                  
<?php
class C {}
class D extends C {}

// This doesn't extend C.
class E {}

function f(C $c) {
    echo get_class($c)."\n";
}

f(new C);
f(new D);
f(new E);
?>
                  
                

PHP 8에서 위 예제의 출력:

C
D

Fatal error: Uncaught TypeError: f(): Argument #1 ($c) must be of type C, E given, called in /in/gLonb on line 14 and defined in /in/gLonb:8
Stack trace:
#0 -(14): f(Object(E))
#1 {main}
  thrown in - on line 8
                

예제 #2 기본 인터페이스 유형 선언

                  
<?php
interface I { public function f(); }
class C implements I { public function f() {} }

// This doesn't implement I.
class E {}

function f(I $i) {
    echo get_class($i)."\n";
}

f(new C);
f(new E);
?>
                  
                

PHP 8에서 위 예제의 출력:

C

Fatal error: Uncaught TypeError: f(): Argument #1 ($i) must be of type I, E given, called in - on line 13 and defined in -:8
Stack trace:
#0 -(13): f(Object(E))
#1 {main}
  thrown in - on line 8
                

예제 #3 기본 반환 유형 선언

                  
<?php
function sum($a, $b): float {
    return $a + $b;
}

// Note that a float will be returned.
var_dump(sum(1, 2));
?>
                  
                

위의 예는 다음을 출력합니다.

float(3)
                

예제 #4 객체 반환

                  
<?php
class C {}

function getC(): C {
    return new C;
}

var_dump(getC());
?>
                  
                

위의 예는 다음을 출력합니다.

object(C)#1 (0) {
}
                
Nullable type

PHP 7.1.0부터 유형 이름 앞에 물음표(?)를 붙여 유형 선언을 nullable로 표시할 수 있습니다. 이는 값이 지정된 유형 또는 null일 수 있음을 나타냅니다.

예제 #5 Nullable 인수 유형 선언

                  
<?php
class C {}

function f(?C $c) {
    var_dump($c);
}

f(new C);
f(null);
?>
                  
                

위의 예는 다음을 출력합니다.

object(C)#1 (0) {
}
NULL
                

예제 #6 Nullable 반환 유형 선언

                  
<?php
function get_item(): ?string {
    if (isset($_GET['item'])) {
        return $_GET['item'];
    } else {
        return null;
    }
}
?>
                  
                

메모: null을 기본값으로 만들어 nullable 인수를 얻을 수 있습니다. 상속 중에 중단되므로 권장하지 않습니다.

예제 #7 인수를 null 허용으로 만드는 오래된 방법

                    
  <?php
  function get_item(): ?string {
      if (isset($_GET['item'])) {
          return $_GET['item'];
      } else {
          return null;
      }
  }
  ?>
                    
                  

위의 예는 다음을 출력합니다.

object(C)#1 (0) {
}
NULL
                  
Union types

공용체 유형 선언은 단일 유형이 아닌 여러 다른 유형의 값을 허용합니다. Union 유형은 T1|T2|.... 구문을 사용하여 지정됩니다. Union 유형은 PHP 8.0.0부터 사용할 수 있습니다.

Nullable union types

null 형식은 T1|T2|null을 사용하여 nullable 공용 구조체를 만드는 데 사용할 수 있도록 공용 구조체의 일부로 지원됩니다. 기존 ?T 표기법은 T|null의 일반적인 경우에 대한 약어로 간주됩니다.

주의 null은 독립 실행형 형식으로 사용할 수 없습니다.

false pseudo-type

false 리터럴 유형은 공용체의 일부로 지원되며 역사적 이유로 많은 내부 함수가 실패 시 null 대신 false를 반환하기 때문에 포함됩니다. 이러한 함수의 고전적인 예는 strpos()입니다.

주의 false는 독립 실행형 형식(nullable 독립 실행형 형식 포함)으로 사용할 수 없습니다. 따라서 false, false|null?false는 모두 허용되지 않습니다.

주의 true 리터럴 유형이 존재하지 않습니다.

Duplicate and redundant types

공용체 유형 선언에서 간단한 버그를 잡기 위해 클래스 로딩을 수행하지 않고 감지할 수 있는 중복 유형은 컴파일 시간 오류를 발생시킵니다. 여기에는 다음이 포함됩니다.

  • 각 이름 확인 유형은 한 번만 발생할 수 있습니다. int|string|INT와 같은 유형은 오류를 발생시킵니다.
  • bool을 사용하는 경우 false를 추가로 사용할 수 없습니다.
  • 객체를 사용하는 경우 클래스 유형을 추가로 사용할 수 없습니다.
  • iterable을 사용하면 array와 Traversable을 추가로 사용할 수 없습니다.

참고: 이렇게 하면 사용된 모든 클래스 유형을 로드해야 하기 때문에 유형이 "최소"임을 보장하지 않습니다.

예를 들어 AB가 클래스 별칭이면 A|BA 또는 B로 축소될 수 있지만 유효한 공용체 유형으로 유지됩니다. 마찬가지로 클래스 B extends A {}하면 A|B도 a A로 축소될 수 있지만 legal union type입니다.

                  
<?php
function foo(): int|INT {} // Disallowed
function foo(): bool|false {} // Disallowed

use A as B;
function foo(): A|B {} // Disallowed ("use" is part of name resolution)

class_alias('X', 'Y');
function foo(): X|Y {} // Allowed (redundancy is only known at runtime)
?>
                  
                
Return only types

void

void는 함수가 값을 반환하지 않음을 나타내는 반환 유형입니다. 따라서 공용체 유형 선언의 일부일 수 없습니다. PHP 7.1.0부터 사용 가능합니다.

메모: void 함수에서 참조로 반환하는 것은 모순되는 함수이기 때문에 PHP 8.1.0부터 더 이상 사용되지 않습니다. 이전에는 호출될 때 이미 다음 E_NOTICE를 내보냈습니다. 변수 참조만 참조로 반환되어야 합니다.

                    
<?php
function &test(): void {}
?>
                    
                  

never

never는 함수가 반환하지 않음을 나타내는 반환 유형입니다. 이것은 exit()를 호출하거나 예외를 발생시키거나 무한 루프임을 의미합니다. 따라서 공용체 유형 선언의 일부일 수 없습니다. PHP 8.1.0부터 사용 가능합니다.

유형 이론 용어로 절대 바닥 유형이 아닙니다. 이는 다른 모든 유형의 하위 유형이며 상속 중에 다른 반환 유형을 대체할 수 있음을 의미합니다.

static

값은 메서드가 호출된 것과 동일한 클래스의 instanceof여야 합니다. PHP 8.0.0부터 사용 가능합니다.

Strict typing

기본적으로 PHP는 가능한 경우 잘못된 유형의 값을 예상되는 스칼라 유형 선언으로 강제 변환합니다. 예를 들어, 문자열을 예상하는 매개변수에 대해 int가 지정된 함수는 문자열 유형의 변수를 가져옵니다.

파일별로 엄격 모드를 활성화할 수 있습니다. 엄격 모드에서는 유형 선언과 정확히 일치하는 값만 허용되며, 그렇지 않으면 TypeError가 발생합니다. 이 규칙의 유일한 예외는 int 값이 float 유형 선언을 전달한다는 것입니다.

경고 내부 함수 내에서 함수 호출은 strict_types 선언의 영향을 받지 않습니다.

엄격 모드를 활성화하기 위해 declare 문은 strict_types 선언과 함께 사용됩니다.

메모: 엄격한 형식 지정은 해당 파일 내에 선언된 함수가 아니라 엄격한 형식 지정이 활성화된 파일 내에서 수행된 함수 호출에 적용됩니다. 엄격한 형식 지정이 활성화되지 않은 파일이 엄격한 형식 지정이 있는 파일에 정의된 함수를 호출하면 호출자의 기본 설정(강제 형식 지정)이 존중되고 값이 강제 변환됩니다.

메모: 엄격한 유형 지정은 스칼라 유형 선언에 대해서만 정의됩니다.

예제 #8 인수 값에 대한 엄격한 입력

                  
<?php
declare(strict_types=1);

function sum(int $a, int $b) {
    return $a + $b;
}

var_dump(sum(1, 2));
var_dump(sum(1.5, 2.5));
?>
                  
                

PHP 8에서 위 예제의 출력:

int(3)

Fatal error: Uncaught TypeError: sum(): Argument #1 ($a) must be of type int, float given, called in - on line 9 and defined in -:4
Stack trace:
#0 -(9): sum(1.5, 2.5)
#1 {main}
  thrown in - on line 4
                

예제 #9 인수 값에 대한 강제 입력

                  
<?php
function sum(int $a, int $b) {
    return $a + $b;
}

var_dump(sum(1, 2));

// These will be coerced to integers: note the output below!
var_dump(sum(1.5, 2.5));
?>
                  
                

위의 예는 다음을 출력합니다.

int(3)
int(3)
                

예제 #10 반환 값에 대한 엄격한 입력

                  
<?php
declare(strict_types=1);

function sum($a, $b): int {
    return $a + $b;
}

var_dump(sum(1, 2));
var_dump(sum(1, 2.5));
?>
                  
                

위의 예는 다음을 출력합니다.

int(3)

Fatal error: Uncaught TypeError: sum(): Return value must be of type int, float returned in -:5
Stack trace:
#0 -(9): sum(1, 2.5)
#1 {main}
  thrown in - on line 5
                
Coercive typing with union types

strict_types가 활성화되지 않은 경우 스칼라 유형 선언은 제한된 암시적 유형 강제의 적용을 받습니다. 값의 정확한 유형이 공용체의 일부가 아닌 경우 대상 유형은 다음 기본 설정 순서로 선택됩니다.

  • int
  • float
  • string
  • bool

유형이 둘 다 유니온에 존재하고 값이 PHP의 기존 유형 검사 의미 체계에 따라 유형으로 강제 변환될 수 있는 경우 유형이 선택됩니다. 그렇지 않으면 다음 유형이 시도됩니다.

주의 예외적으로 값이 문자열이고 int와 float가 모두 공용체의 일부인 경우 기본 유형은 기존 "숫자 문자열" 의미 체계에 의해 결정됩니다. 예를 들어 "42"의 경우 int가 선택되고 "42.0"의 경우 float가 선택됩니다.

메모: 위의 기본 설정 목록에 포함되지 않은 유형은 암시적 강제의 대상이 아닙니다. 특히 nullfalse 유형에 대한 암시적 강제가 발생하지 않습니다.

예제 #11 공용체의 유형 부분으로 강제 변환되는 유형의 예

                  
<?php
// int|string
42    --> 42          // exact type
"42"  --> "42"        // exact type
new ObjectWithToString --> "Result of __toString()"
                      // object never compatible with int, fall back to string
42.0  --> 42          // float compatible with int
42.1  --> 42          // float compatible with int
1e100 --> "1.0E+100"  // float too large for int type, fall back to string
INF   --> "INF"       // float too large for int type, fall back to string
true  --> 1           // bool compatible with int
[]    --> TypeError   // array not compatible with int or string

// int|float|bool
"45"    --> 45        // int numeric string
"45.0"  --> 45.0      // float numeric string

"45X"   --> true      // not numeric string, fall back to bool
""      --> false     // not numeric string, fall back to bool
"X"     --> true      // not numeric string, fall back to bool
[]      --> TypeError // array not compatible with int, float or bool
?>
                  
                
Misc

예제 #12 형식화된 참조에 의한 전달 매개변수

선언된 참조 매개변수 유형은 함수 입력 시 확인되지만 함수가 반환될 때는 확인되지 않으므로 함수가 반환된 후 인수의 유형이 변경되었을 수 있습니다.

                  
<?php
function array_baz(array &$param)
{
    $param = 1;
}
$var = [];
array_baz($var);
var_dump($var);
array_baz($var);
?>
                  
                

PHP 8에서 위 예제의 출력:

int(1)

Fatal error: Uncaught TypeError: array_baz(): Argument #1 ($param) must be of type array, int given, called in - on line 9 and defined in -:2
Stack trace:
#0 -(9): array_baz(1)
#1 {main}
  thrown in - on line 2
                

Example #13 Catching TypeError

                  
<?php
declare(strict_types=1);

function sum(int $a, int $b) {
    return $a + $b;
}

try {
    var_dump(sum(1, 2));
    var_dump(sum(1.5, 2.5));
} catch (TypeError $e) {
    echo 'Error: ', $e->getMessage();
}
?>
                  
                

PHP 8에서 위 예제의 출력:

int(3)
Error: sum(): Argument #1 ($a) must be of type int, float given, called in - on line 10