Generics in PHP: Why They Are Needed and How to Use Them

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Generics in PHP: why they are needed and how to use them



Generic types (Generics) are one of the most anticipated and discussed features in the PHP world. Although they are not yet fully implemented in the language as of PHP 8.x, the community actively uses alternative approaches and awaits full support. In this article, we will break down why Generics are needed in PHP, how they can be emulated, and what advantages they give to the developer.



What are Generics and why are they needed?



Generics allow you to create classes, interfaces, and functions that work with different data types while maintaining strict typing. In statically typed languages (Java, C#, TypeScript), they have long been a standard. For PHP, which was originally dynamically typed, Generics are a step towards more reliable and readable code.



Main problems that Generics solve:

  • Type safety — eliminates errors related to passing data of the wrong type.
  • Reducing code duplication — no need to write separate classes for each type.
  • Improved readability — it is immediately clear what types a function or class works with.
  • IDE support — autocompletion and code analysis become more accurate.


The problem without Generics: example in PHP



Imagine you need to create a collection that stores only integers. Without Generics, you could write:



class IntegerCollection {    private array $items = [];

public function add(int $item): void { $this->items[] = $item; }

public function get(int $index): int { return $this->items[$index]; }}


It works, but if you need a collection for strings, you have to copy the code and change the types. And if you need a collection for objects — the same thing. This leads to duplication and an increase in code volume.



Emulating Generics in PHP using annotations and PHPDoc



Currently, PHP does not support full Generics at the syntax level, but they can be emulated using PHPDoc annotations and special libraries (e.g., phpstan/phpstan or vimeo/psalm).



Example of a generic class with annotations:



/** * @template T */class Collection {    private array $items = [];

/** * @param T $item */ public function add($item): void { $this->items[] = $item; }

/** * @return T */ public function get(int $index) { return $this->items[$index]; }}


Now, when using the class, you can specify a specific type:



/** @var Collection<int> $intCollection */$intCollection = new Collection();$intCollection->add(42);$value = $intCollection->get(0); // IDE knows this is int


Static analyzers (PHPStan, Psalm) will check that you are not passing a string into a collection of integers. This provides almost the same safety as full Generics.



Real-world examples of using Generics in PHP



Let's look at a few practical scenarios where Generics are particularly useful.



1. Repositories in Doctrine



In Doctrine ORM, you often work with repositories. Generics help to explicitly specify which entity the repository works with:



/** * @template T of object */interface RepositoryInterface {    /**     * @param int $id     * @return T|null     */    public function find(int $id): ?object;}

/** * @implements RepositoryInterface<User> */class UserRepository implements RepositoryInterface { public function find(int $id): ?User { // search logic }}


2. Strategy pattern with generics



Generics allow you to create

Blogs

Book Recommendations