Parametrized classes (just thinking)

I think, subject is very required in PHP. Something like…

abstract class Collection<Foo>
{
    /**
    * @var <Foo>[]
    **/
    private $items = [];

    public function get(string $key) : <Foo> {/*...*/}

    public function set(string $key, <Foo> $item) : static {/*...*/}
}

I hoped, in PHP 8 something like that will be realized. But it seems not…

1 Like

The concept is called Generics and no, PHP8 does not have it.

You can kinda sorta emulate it with tools like Psalm (see https://psalm.dev/docs/annotating_code/templated_annotations/) and PHPStan (see https://phpstan.org/blog/generics-in-php-using-phpdocs), but that’s only through static analysis. At runtime all these annotations are ignored by the compiler.

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.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.