Generics has been discussed for years. There are a number of technical reasons why it won’t ever be added to PHP’s core. Though transpilers might be able to do it.
So if you consider this sort of functionality to be essential then you should consider moving to a different language such as C#.
However PHP can come close to providing similar sort of functionality. Consider:
// More or less typesafe array collection
class Teams extends ArrayIterator
{
// Constructor is optional but kind of nice
public function __construct(Team ...$items)
{
parent::__construct($items);
}
public function current() : Team
{
return parent::current();
}
public function offsetGet($offset) : Team
{
return parent::offsetGet($offset);
}
}
// Test entity
class Team {
private string $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function getName() : string
{
return $this->name;
}
}
// Test
$team0 = new Team('Alabama');
$team1 = new Team('Clemson');
$teams = new Teams($team0,$team1);
$teams[] = new Team('Ohio State');
foreach($teams as $team) {
// PHP knows you have a Team object
echo $team->getName() . "\n";
}
echo $teams[0]->getName() . "\n";
$team3 = new stdClass();
$teams[] = $team3; // Sadly this is allowed, cannot typehint offsetSet
echo $teams[3]->getName() . "\n"; // offsetGet will toss an error
So Teams is a mostly typesafe array of Team objects. I say mostly because you can add non-team objects without generating an error.
And of course you can do similar sort of things with stacks etc.