PHP에서 배열 구조 선언

Feb 20 2023
불행하게도 Java와 같은 다른 프로그래밍 언어처럼 명시적인 배열 유형을 정의하는 것은 불가능합니다. PHPStan 또는 Psalm과 같은 일부 도구는 코드를 정적으로 분석하는 데 도움이 됩니다. PHP 주석에. PHP 배열의 요소 유형을 정의하는 방법에는 3가지가 있습니다. 이것은 특정 유형의 요소 목록을 정의하는 유행 방식입니다. 문제는 이것이 모호해지고 이러한 종류의 목록을 사용하는 클라이언트는 키는 정수, 부동 소수점 또는 문자열입니다.

안타깝게도 Java와 같은 다른 프로그래밍 언어처럼 명시적인 배열 유형을 정의하는 것은 불가능합니다.

List<User> users = new ArrayList<>();

바라건대 PHPStan 또는 Psalm 과 같은 일부 도구는 코드를 정적으로 분석하는 데 도움이 됩니다. 즉, 실행하지 않고 PHP 주석을 기반으로 코드의 불일치를 확인합니다.

PHP 배열의 요소 유형을 정의하는 방법에는 3가지가 있습니다.

  1. 레거시 방식:User[]
  2. 목록 모양: array<int,mixed>&list<mixed>
  3. 개체 모양:array{0:int, foo:?string, bar:mixed}

이것은 특정 유형의 요소 목록을 정의하는 세련된 방법입니다. 문제는 이것이 모호 해지고 이러한 종류의 목록을 사용하는 클라이언트는 키가 정수인지 부동 소수점인지 문자열인지 알 수 없다는 것입니다.
또한 유형이 잘못된 키로 요소를 가져오려고 해도 정적 분석기가 실패하지 않습니다. 이러한 시나리오에서는 array<int,mixed>.

결국 명시적일수록 좋습니다.

/** @var User[] $users */
$users = [ ... ];

# Are keys autoincremental integers, random numbers, maybe strings... ?
$firstUser = $users[ ? ];

# Static analyzers won't complain if you use an incorrect type 

동일한 유형의 요소 배열이 있을 때 목록을 사용합니다.
이를 위해 다이아몬드 구문을 사용하여 키와 값의 유형을 선언합니다 array<int,mixed>. 키가 자동 증분 정수인 경우 매우 편리한 단축키가 있습니다: list<mixed>.

/** @var array<string,User> $users */
$users = [
    'jesus' => new User('Jesus Valera'),
    'chema' => new User('Chema Valera'),
];

$userJesus = $users['jesus'];
$userChema = $users['chema'];

$users[0]; # ERROR: "Offset 0 does not exist on array<string, User>"

---

/** @var list<User> $users */
$users = [ ... ];

$firstUser = reset($users);
$lastUser = end($users);

배열이 객체의 모음이 아니라 정보를 담고 있는 지도일 때 객체 모양을 사용합니다.
이를 위해 중괄호 구문을 사용 하고 키 이름과 유형을 정의합니다. 여러 요소가 있는 경우 쉼표로 나눌 수 있습니다 array{foo:int, bar:string}.

/** @var array{id:int, birthdate: DateTimeImmutable} */
$additionalInfo = [ ... ];

$id = $additionalInfo['id']; # int
$birthdate = $additionalInfo['birthdate']; # DateTimeImmutable

final class User
{
    /** @var list<Comment> */
    public readonly array $comments;

    /** @var array{id:int, birthdate: DateTimeImmutable} */
    public readonly array $additionalInfo;
}

물론 이러한 PHP 주석을 사용하여 PHP에서 복잡한 배열 구조를 나타내는 것이 가능합니다. 예:

/**
 * @var list<
 *   array{
 *     uuid?: string,
 *     content: array{name: string, foo: ?stdClass},
 *   }
 * > $array
 */
$array = [
    0 => [
        'uuid' => 'XXXX-XXX-XXX-XXXX',
        'content' => [
            'name' => 'str',
            'foo' => null,
        ],
    ],
    1 => [
        'content' => [
            'name' => 'str',
            'foo' => new stdClass(),
        ],
    ],
    // ...
];

자원:

  • 시편 | 배열 모양
  • PHP스탄 | PHPDoc 유형