Hướng dẫn php 8 named parameters - php 8 tham số được đặt tên

Scout APM giúp các nhà phát triển PHP xác định các truy vấn N+1, rò rỉ bộ nhớ và nhiều hơn nữa để bạn có thể khắc phục sự cố nhanh chóng và quay lại mã hóa nhanh hơn. Bắt đầu dùng thử 14 ngày miễn phí của bạn ngay hôm nay.

Đó là một cuộc gọi gần, nhưng các đối số được đặt tên - còn được gọi là tham số được đặt tên - được hỗ trợ trong Php 8! Trong bài đăng này, tôi sẽ thảo luận về sự xuất hiện của họ, nhưng hãy để tôi cho bạn thấy trước tiên chúng trông như thế nào với một vài ví dụ trong tự nhiên:

setcookie(
    name: 'test',
    expires: time() + 60 * 60 * 2,
);

Các đối số được đặt tên được sử dụng trên hàm PHP tích hợp

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

$data = new CustomerData(
    name: $input['name'],
    email: $input['email'],
    age: $input['age'],
);

DTO sử dụng các thuộc tính được quảng bá, cũng như các đối số được đặt tên

$data = new CustomerData(...$customerRequest->validated());

Các đối số được đặt tên cũng hỗ trợ lan truyền mảng

Bạn có thể đã đoán nó từ các ví dụ: các đối số được đặt tên cho phép bạn chuyển dữ liệu đầu vào vào một hàm, dựa trên tên đối số của chúng thay vì thứ tự đối số.

Tôi sẽ tranh luận về các đối số được đặt tên là một tính năng tuyệt vời sẽ có tác động đáng kể đến cuộc sống lập trình hàng ngày của tôi. Có lẽ bạn đang tự hỏi về các chi tiết mặc dù: Điều gì sẽ xảy ra nếu bạn vượt qua một cái tên sai, có gì với cú pháp lan truyền mảng đó? Chà, hãy nhìn vào tất cả những câu hỏi sâu.

# Tại sao các đối số được đặt tên?

Giả sử tính năng này là một cuộc tranh luận cao, và có một số đối số phản biện để không thêm chúng. Tuy nhiên, tôi muốn nói rằng lợi ích của họ vượt xa nỗi sợ về các vấn đề tương thích ngược hoặc API đầy hơi. Theo cách tôi nhìn thấy, họ sẽ cho phép chúng tôi viết mã sạch hơn và linh hoạt hơn.

Đối với một, các đối số được đặt tên cho phép bạn bỏ qua các giá trị mặc định. Hãy xem một lần nữa ví dụ cookie:

setcookie(
    name: 'test',
    expires: time() + 60 * 60 * 2,
);

Chữ ký phương pháp của nó thực sự là như sau:

setcookie ( 
    string $name, 
    string $value = "", 
    int $expires = 0, 
    string $path = "", 
    string $domain = "", 
    bool $secure = false, 
    bool $httponly = false,
) : bool

Trong ví dụ tôi đã chỉ ra, chúng tôi không cần phải đặt Cookie

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

$data = new CustomerData(
    name: $input['name'],
    email: $input['email'],
    age: $input['age'],
);
9, nhưng chúng tôi cần phải đặt thời gian hết hạn. Các đối số được đặt tên làm cho phương thức này gọi ngắn gọn hơn một chút:

setcookie(
    'test',
    '',
    time() + 60 * 60 * 2,
);

$data = new CustomerData(...$customerRequest->validated());
0 mà không có đối số được đặt tên

setcookie(
    name: 'test',
    expires: time() + 60 * 60 * 2,
);

$data = new CustomerData(...$customerRequest->validated());
0 với các đối số được đặt tên

Bên cạnh việc bỏ qua các đối số với các giá trị mặc định, cũng có lợi ích của việc có sự rõ ràng về biến nào làm những gì; Một cái gì đó đặc biệt hữu ích trong các chức năng với chữ ký phương pháp lớn. Bây giờ chúng ta có thể nói rằng rất nhiều đối số thường là mùi mã; Chúng tôi vẫn phải đối phó với họ bất kể điều gì, vì vậy tốt hơn là nên làm như vậy để làm như vậy, hơn là không có gì cả.

Nhận thấy một tpyo? Bạn có thể gửi PR để sửa nó. Nếu bạn muốn cập nhật những gì đang xảy ra trên blog này, bạn có thể theo dõi tôi trên Twitter hoặc đăng ký nhận bản tin của tôi:

# Các đối số được đặt tên theo chiều sâu

Với những điều cơ bản, chúng ta hãy xem xét những gì đối số có thể và không thể làm được.

Trước hết, các đối số được đặt tên có thể được kết hợp với các đối số không tên - còn được gọi là đặt hàng -. Trong trường hợp đó, các đối số được đặt hàng phải luôn luôn đến trước.

Lấy ví dụ DTO của chúng tôi từ trước:

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

Bạn có thể xây dựng nó như vậy:

$data = new CustomerData(
    $input['name'],
    age: $input['age'],
    email: $input['email'],
);

Tuy nhiên, có một đối số được đặt hàng sau khi một người được đặt tên sẽ gây ra lỗi:

$data = new CustomerData(
    age: $input['age'],
    $input['name'],
    email: $input['email'],
);

Tiếp theo, có thể sử dụng lan truyền mảng kết hợp với các đối số được đặt tên:

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

$data = new CustomerData(
    name: $input['name'],
    email: $input['email'],
    age: $input['age'],
);
0

Tuy nhiên, nếu có thiếu các mục yêu cầu trong mảng hoặc nếu có khóa không được liệt kê là đối số được đặt tên, một lỗi sẽ bị ném:

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

$data = new CustomerData(
    name: $input['name'],
    email: $input['email'],
    age: $input['age'],
);
1

Có thể kết hợp các đối số được đặt tên và đặt hàng trong một mảng đầu vào, nhưng chỉ khi các đối số được đặt hàng tuân theo quy tắc tương tự như trước đây: chúng phải đến trước!

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

$data = new CustomerData(
    name: $input['name'],
    email: $input['email'],
    age: $input['age'],
);
2

Nếu bạn đang sử dụng các hàm variadic, các đối số được đặt tên sẽ được chuyển bằng tên khóa của chúng vào mảng đối số variadic. Lấy ví dụ sau:

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

$data = new CustomerData(
    name: $input['name'],
    email: $input['email'],
    age: $input['age'],
);
3

Trong trường hợp này,

$data = new CustomerData(...$customerRequest->validated());
2 trong
$data = new CustomerData(...$customerRequest->validated());
3 sẽ chứa các dữ liệu sau:

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

$data = new CustomerData(
    name: $input['name'],
    email: $input['email'],
    age: $input['age'],
);
4

Các thuộc tính - còn được gọi là chú thích - cũng hỗ trợ các đối số được đặt tên:

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

$data = new CustomerData(
    name: $input['name'],
    email: $input['email'],
    age: $input['age'],
);
5

Không thể có một biến như tên đối số:

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

$data = new CustomerData(
    name: $input['name'],
    email: $input['email'],
    age: $input['age'],
);
6

Và cuối cùng, các đối số được đặt tên sẽ giải quyết một cách thực dụng với các thay đổi tên trong quá trình thừa kế. Lấy ví dụ này:

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

$data = new CustomerData(
    name: $input['name'],
    email: $input['email'],
    age: $input['age'],
);
7

PHP sẽ âm thầm cho phép thay đổi tên của

$data = new CustomerData(...$customerRequest->validated());
4 thành
$data = new CustomerData(...$customerRequest->validated());
5 và
$data = new CustomerData(...$customerRequest->validated());
6 thành
$data = new CustomerData(...$customerRequest->validated());
7; Nhưng nếu bạn quyết định sử dụng các đối số có tên bằng tên của cha mẹ, nó sẽ dẫn đến lỗi thời gian chạy:

class CustomerData
{
    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) {}
}

$data = new CustomerData(
    name: $input['name'],
    email: $input['email'],
    age: $input['age'],
);
8

Lỗi thời gian chạy trong trường hợp

$data = new CustomerData(...$customerRequest->validated());
8 là một ví dụ là
$data = new CustomerData(...$customerRequest->validated());
9

Cách tiếp cận thực dụng này đã được chọn để ngăn chặn một sự thay đổi lớn khi tất cả các đối số được kế thừa sẽ phải giữ cùng một tên. Có vẻ như là một giải pháp tốt cho tôi.


Đó là hầu hết có để kể về các đối số được đặt tên. Nếu bạn muốn biết thêm một chút hậu trường đằng sau một số quyết định thiết kế, tôi sẽ khuyến khích bạn đọc RFC.

Bạn có mong muốn sử dụng các đối số được đặt tên không? Hãy cho tôi biết qua Twitter hoặc qua e-mail!

Chú thích

Các đối số được đặt tên RFC

Tại sao chúng ta cần đối số được đặt tên

Thuộc tính trong Php 8

Khuyến khích thuộc tính của hàm tạo trong Php 8