Generics trong PHP

PHP được biết đến là 1 ngôn ngữ đơn giản, biến trong PHP đều bắt đầu bằng $, không bắt buộc phải khai báo rõ ràng kiểu dữ liệu, nhưng đó lại chính là một trong những thứ gây ra lỗi nhiều nhất trong PHP. Dưới đây là một ví dụ điển hình.


Một số developer nghĩ rằng: cái function đó do tôi code thì tôi control được, tôi sẽ truyền đúng kiểu dữ liệu, tôi sẽ ép kiểu trước khi truyền vào function. Nhưng DỰ ÁN CÓ NHIỀU NGƯỜI THAM GIA, ĐÂU PHẢI CHỈ CÓ MỘT NGƯỜI. VÀ CHÚNG TA CŨNG KHÔNG ĐẢM BẢO RẰNG DỮ LIỆU TRUYỀN VÀO LÚC NÀO CŨNG HỢP LỆ

Quay lại ví dụ, chúng ta có thể khai báo kiểu dữ liệu cho các biến của function để hạn chế vấn đề trên.


Lưu ý: Để validate kiểu dữ liệu chúng ta phải khai báo declare(strict_types=1); còn không thì PHP sẽ chỉ dùng kiểu dữ liệu khai báo để tự động ép kiểu mà thôi.

Nhưng nếu chúng ta khai báo kiểu dữ liệu cho array thì sao? Làm sao để đảm bảo các phần tử trong array truyền vào là int hay string?

Trong PHP không có khái niệm generics như các ngôn ngữ khác ví dụ như java, c# (https://viblo.asia/p/lam-chu-generics-trong-java-E1XVOjXELMz) cho đến hiện tại PHP 8.4. Vậy để kiểm tra input của array thì chúng ta phải làm như thế nào để hạn chế lỗi runtime?

 Sử dụng static analysis với PHPDoc thông qua Psalm hay PHPStan

 a. Khai báo kiểu dữ liệu bằng @param và @template

  • @template TKey of array-key ràng buộc keys là int hoặc string.
  • @template TValue is không ràng buộc (any type mixed).

b.  Định nghĩa ra các @template để tái sử dụng

Nếu chúng ta khai báo lặp lại các @param array<TKey, TValue> $items hoặc @param array<int, OrderItem> $orderItem chẳng hạn thì cũng khá bất tiện, nên chúng ta có thể định nghĩa thành các @template để có thể tái sử dụng 



Lưu ý: cách này chỉ là static analysis với PHPDoc thông qua Psalm hay PHPStan. Nên ở runtime thì vẫn có thể xảy ra lỗi.

Nhận xét

Bài đăng phổ biến từ blog này

Lập trình hướng đối tượng, khó hiểu hay do mình không hiểu

Singleton design pattern