P
P
psfpro2018-08-08 13:41:39
PHP
psfpro, 2018-08-08 13:41:39

How to correctly specify the type parameter when implementing an interface in PHP?

I wondered why the class object is not compatible with the object type. Example below:

interface ExtractorInterface
{
    /**
     * @param object $object
     * @return array
     */
    public function extract(object $object);
}

class MyObjectExtractor implements ExtractorInterface
{
    /**
     * @param MyObject $object
     * @return array
     */
    public function extract(MyObject $object)
    {
        return [
            'a' => $object->a,
        ];
    }
}

class MyObject
{
    public $a;
}

There is an option not to specify the type and do the check inside the method. An even less reliable method is not to specify the type at all.
How to use typing correctly? Or maybe not use it?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
P
psfpro, 2018-08-08
@psfpro

PHP 7.2 added the ability to extend the parameter type
https://wiki.php.net/rfc/parameter-no-type-variance

<?php
 
class ArrayClass {
  public function foo(array $foo) { /* ... */ }
}
 
 
// This RFC proposes allowing the type to be widened to be untyped aka any
// type can be passed as the parameter.
// Any type restrictions can be done via user code in the method body.
class EverythingClass extends ArrayClass {
  public function foo($foo) { /* ... */ }
}

It turns out in my example not to specify the type and do the check inside the method

A
Alexey Ukolov, 2018-08-08
@alexey-m-ukolov

I wondered why the class object is not compatible with the object type.
On the contrary - it's object is incompatible with MyObject .
In general, you are doing it wrong - your interface is meaningless. This MyObject should implement the Extractable interface and have an extract method - then there are no problems and contradictions.
interface Extractable
{
    public function extract(): array;
}

class MyObject implements Extractable
{
    public $a;

    public function extract(): array
    {
        return [
            'a' => $this->a,
        ];
    }
}

class MyOtherObject implements Extractable
{
    public $a, $b, $c;

    public function extract(): array
    {
        return [
            'a-b' => $this->a . $this->b,
            'c' => $this->c->toArray(),
        ];
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question