Generics equivalent in PHP

Published 2 years ago by Mythos33

Hello guys,

I'm trying to use Repositories which implement my RepositoryInterface. As a C# .NET developer I would create a Generic interface like this:

public interface IRepository<TModelType>
{
    IEnumerable<TModelType> FindAll();
    void Save(TModelType model);
}

I would implement it like this:

public class UserRepository : IRepository<User>
{
    public IEnumerable<User> FindAll()
    {
        // Method body
    }

    public void Save(User model)
    {
        // Method body
    }
}

Now my question: Is there something like this in PHP?

EDIT:

The reason I want to do this is type safety and code completion assistance and I don't want to cast the model parameter all the time. ;-)

Regards, Stefan

Best Answer (As Selected By Mythos33)
Ruffles

I don't know much about C# because I don't really have any experience with it but I am guessing you want to do something like this:

interface RepositoryInterface
{
    public function findAll();
    public function save();
}

class UserRepository implements RepositoryInterface
{
    protected $user;

    public __construct(User $user)
    {
        $this->user = $user;
    }
    
    public function findAll()
    {
        // $this->user->modelMethod();
            // Method body
    }

        public function save()
        {
        // $this->user->modelMethod();
            // Method body
        }
}

There are no return types for methods in PHP 5.6 (PHP 7 will bring return types and scalar typehints). Currently, you can type hint method arguments only for objects and arrays, int string bool (scalar data types) are not supported.

PHP is a loosely typed language so you don't really have to typehint stuff, but it supports some kind of typehinting if you want to do that.

Ruffles
Ruffles
2 years ago (283,470 XP)

I don't know much about C# because I don't really have any experience with it but I am guessing you want to do something like this:

interface RepositoryInterface
{
    public function findAll();
    public function save();
}

class UserRepository implements RepositoryInterface
{
    protected $user;

    public __construct(User $user)
    {
        $this->user = $user;
    }
    
    public function findAll()
    {
        // $this->user->modelMethod();
            // Method body
    }

        public function save()
        {
        // $this->user->modelMethod();
            // Method body
        }
}

There are no return types for methods in PHP 5.6 (PHP 7 will bring return types and scalar typehints). Currently, you can type hint method arguments only for objects and arrays, int string bool (scalar data types) are not supported.

PHP is a loosely typed language so you don't really have to typehint stuff, but it supports some kind of typehinting if you want to do that.

Mythos33

Isn't there a way to type hint my parameter for the save method?

Because a Group should not be passed into UserRepository's save method. ;-)

Using it like this also does not work, because of the different method signature:

(pseudo code)

function save(Model $model); // Method in my Interface

function save(User $model); // Method in my UserRepository implementing the RepositoryInterface
Ruffles
Ruffles
2 years ago (283,470 XP)
function save(Model $model); // Method in Interface

function save(Model $model); // Method in UserRepository implementing the RepositoryInterface

When you call the method somewhere in the controller or a service class, you should be able to pass a User object and be sure that it's a User object (if that's the model object you want to pass as an argument). Probably a check which class that object belongs to is a good idea here.

tag
tag
2 years ago (47,940 XP)

@Mythos33, unfortunately PHP does not have native generics, so you'll need an interface for each type of repository if you want to be able to type hint a specific type of Model. The only other option is to be less strict and allow anything that is a Model, as @Ruffles suggested.

Mythos33

Ah thanks for your answers @Ruffles @tag :-)

Please sign in or create an account to participate in this conversation.