3

I have the following structure:

class AffiliateRepository extends GenericRepository implements IAffiliateRepository {

}


abstract class GenericRepository  {
    public function save(BaseModel $model) : int{
        $model->save();
        return $model->getId();
    }

}

interface IAffiliateRepository  {

    public function save(Affiliate $affiliate) : int;
}

public class Affiliate extends BaseModel{}


$affiliateRepository  = new AffiliateRepository();
$affiliateRepository->save(new Affiliate());

I am expecting GenericRepository to take care on the save action.

but I'm getting the following error:

Declaration of App\Services\AffiliateRepository::save(App\Models\Affiliate $affiliate): int should be compatible with App\Services\GenericRepository::save(App\Models\BaseModel $model): int

Why is that? Affiliate inherits from BaseModel.
Whats the best way to overcome that and let GenericRepository handle the save function call.

thanks

3
  • 3
    Because the method signature of GenericRepository::save is not met. That method says that it can accept any BaseModel, whereas IAffiliateRepository::save only accepts Affiliate instances. So it clearly breaks the contract. Commented Apr 3, 2017 at 6:43
  • Is \App\Models\Affiliate a descendant of \App\Models\BaseModel? Commented Apr 3, 2017 at 6:58
  • "Why is that? Affiliate inherits from BaseModel." -- because PHP is not C++ :-( Commented Apr 3, 2017 at 7:30

3 Answers 3

1

Look at methods:

// GenericRepository
public function save(BaseModel $model)

// IAffiliateRepository
public function save(Affiliate $affiliate) : int;

Both classes have to expect the same type. If you implement IAffiliateRepository into GenericRepository class, it will be correct. You may also need to change variable names to be the same.

Sign up to request clarification or add additional context in comments.

Comments

0

Seems a bit messy but the problem is, in order for AffiliateRepository to implement the IAffiliateRepository, the signature of save must be

save(Affiliate $affiliate) : int

The implementation in GenericRepository does not satisfy this.

You could try this in AffiliateRepository...

public function save(Affiliate $affiliate) : int {
    return parent::save($affiliate);
}

Comments

0

@enricog gave the correct answer in a comment: to satisfy the interface the save method must accept any object that is a BaseModel. The method provided by IAffiliateRepository does not do that.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.