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

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 в PHP: зачем нужны и как использовать



Modern PHP development requires not only speed but also code reliability. One of the tools that helps achieve this goal is Generics (generic types). Despite PHP being a dynamically typed language, with the release of PHP 7.0 and higher, and especially PHP 8.0, static typing has become available and in demand. Generics allow you to write more flexible, reusable, and safe data structures such as collections, stacks, queues, and repositories without losing type information.



In this article, we will thoroughly examine what Generics in PHP are, why they are needed, how to use them correctly in practice, and look at specific code examples.



What are Generics and why are they needed?



Generics (generic types) is a mechanism that allows parameterizing classes, interfaces, traits, and functions with a data type. Instead of writing a separate implementation for each type (e.g., IntegerList, StringList, UserList), you create one universal class List<T>, where T is a placeholder for the specific type that will be passed when used.



Why is this needed?

  • Type safety: IDEs and static analyzers (Psalm, PHPStan) can check that only elements of one type enter a collection, preventing errors at the development stage.
  • Reducing code duplication: You don't need to write the same class for different data types.
  • Improved readability: Code becomes self-documenting — it's immediately clear what data types are expected.
  • Increased performance: Although PHP itself does not use Generics at the virtual machine level (like Java or C#), static analyzers help find potential errors before code execution.


How to use Generics in PHP? Syntax and examples



Starting with PHP 8.0, support for Generics was introduced at the annotation level (docblock) and partially at the code level (for variadic arguments). Full syntax-level support is expected in future versions, but you can already effectively use Generics with PHPDoc and static analyzers.



1. Basic syntax with PHPDoc



The most common way is to use @template and @param/@return annotations with a generic type specified.



<?php

/** * @template T */class Collection { /** @var array<T> */ private array $items;

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

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

// Usage example$intCollection = new Collection();$intCollection->add(42);// $intCollection->add('string'); // Static analyzer error

$userCollection = new Collection();$userCollection->add(new User());// $userCollection->add(123); // Error?>


In this example, @template T declares a generic type. @param T $item and @return T|null tell the analyzer that the element types must be consistent.



2. Type constraints (bounded generics)



You can restrict which types can be used as a parameter. This is done using @extends or @implements.



<?php

/** * @template T of \\Stringable */class StringableCollection { /** @var array<T> */ private array $items;

/** * @param T $item */ public function add($item): void { $this->it

Blogs

Book Recommendations