PHP의 입력된 배열

8796 단어 arraygenericstypedphp
PHP에서 누락된 기능에 대한 대안: Generics

완벽한 조합


  • 인수 압축 풀기: 인수 자체를 함수에 전달하는 대신 함수에 포함된 요소가 개별 인수로 전달됩니다.
  • 함수 변수 인수 목록: 인수가 지정된 변수에 배열로 전달됩니다.
  • Variadics 기능: 유형 힌트를 사용하여 유형을 확인할 수 있습니다.

  • 예를 들어 이것을 잘라서 사용할 것입니다.
    클래스를 가지고, Customer :

    /** 
     * @psalm-immutable 
     */
    final class Customer
    {
        // Using PHP 8 constructor property promotion
        public function __construct(
            public string $name,
        ) {}
    }
    // We create a list of 6 customers
    $customers = array_map(
        fn(int $i): Customer => new Customer("name-{$i}"),
        range(1, 6)
    );
    


    고객 목록을 조작하고 싶을 때마다 인수로 전달할 수 있습니다: …$customers .

    사용 방법



    위의 PHPDoc 매개변수 주석 블록을 사용하여 배열 유형을 정의합니다. 그러나 항목의 실제 유형을 정의할 수는 없습니다. 코드는 해당 인수에 유형을 전달하는 데 아무런 문제 없이 계속 실행됩니다array $customers.

    /** 
     * @param Customer[] 
     */
    function createInvoiceForCustomers(array $customers): void
    {
        foreach ($customers as $customer) {
            // ... some irrelevant logic for this example
        }
    }
    


    아래 코드는 "컴파일 타임"에서 작동합니다. 그러나 "런타임"에서 실패할 수 있습니다.

    createInvoiceForCustomers($customers);
    createInvoiceForCustomers([new Customer('any name')]);
    createInvoiceForCustomers([new AnyOtherType()]);
    


    대안(권장!)은 해당 논리를 추출하고 특정 순간에 런타임에 "확인"하기 위해 특정 유형을 요청하는 것일 수 있습니다. 항목 중 하나가 실제로 고객이 아닌 경우 실패합니다.

    /** 
     * @param Customer[] 
     */
    function createInvoiceForCustomers(array $customers): void
    {
        foreach ($customers as $customer) {
            createInvoice($customer);
        }
    }
    function createInvoice(Customer $customer): void
    {
        // ... some irrelevant logic for this example
    }
    


    아래의 모든 것은 "컴파일 타임"에 작동합니다. createInvoice(Customer $customer)가 고객과 다른 것을 수신하는 경우 "런타임"동안 확실히 중단됩니다.

    createInvoiceForCustomers($customers);
    createInvoiceForCustomers([new Customer('any name')]);
    createInvoiceForCustomers([new AnyOtherType()]); // won't work
    


    그렇게 함으로써createInvoice(Customer $customer) 인수의 유형을 보장할 수 있습니다. 하지만, 한 걸음 더 나아가면 어떨까요? 함수를 호출할 때 요소의 유형을 확인할 수 있습니까createInvoiceForCustomers(array $customers). 유형이 올바르지 않을 때 IDE가 불평하도록 만들 수 있습니까?

    제네릭이 필요한 이유는 사실이지만 슬프게도 아직 PHP에는 없습니다. 곧 출시될 PHP 8에서도 마찬가지입니다. 가까운 미래에 나오길 바라지만 지금은 예측할 수 없습니다.
    운 좋게도 현재 대안이 있지만 그다지 인기가 없습니다. 자체 "장점"과 "단점"이 있으므로 먼저 예를 살펴보겠습니다.

    function createInvoiceForCustomers(Customer ...$customers): void
    {
        foreach ($customers as $customer) {
            createInvoice($customer);
        }
    }
    


    아래의 모든 것은 "컴파일 타임"에 작동합니다. createInvoice()가 고객과 다른 것을 수신하는 경우 "런타임"동안 확실히 중단됩니다.

    createInvoiceForCustomers(...$customers); // OK
    createInvoiceForCustomers(
        new Customer('any name'), 
        new Customer('any name'),
    ); // OK
    // This is not even possible to write. The IDE will yeld at you. 
    // It's expecting a `Customer`, but `AnyOtherType` is given:
    createInvoiceForCustomers(new AnyOtherType());
    


    장점


  • 모든 구체적인 유형의 목록을 쉽게 입력할 수 있습니다.

  • 단점


  • 최대 1개 또는 2개의 인수로 함수를 정의하는 것이 좋습니다. 그렇지 않으면 읽기에 너무 복잡할 것입니다.

  • 중요사항


  • 함수의 마지막 인수여야 합니다.
  • 함수에서 사용하는 인수의 수를 최소화하는 데 도움이 됩니다.

  • 결론



    인수 압축 해제는 가변 함수와 결합하여 형식화된 배열을 시뮬레이트하는 데 도움이 되는 훌륭한 기능입니다. 큰 힘에는 큰 책임이 따르며 이는 예외가 아닙니다.
    도구 상자를 현명하게 사용하려면 도구 상자에 대해 배워야 합니다.




    참조
  • Argument unpacking
  • Function variable argument list
  • Variadics function

  • Originally published on https://chemaclass.es/blog/typed-arrays-php/

    좋은 웹페이지 즐겨찾기