Instanceof error в классе обертки php

Я начал писать класс-оболочку для предопределенного пакета php. Вот классы:

class phpclass1
    :: ping()
    :: __construct(array $options)
    :: clear() 
    :: addDoc(phpclass2 $string)

...

class phpclass2 
    :: __construct()
    :: update()
...

Вот классы-оболочки, которые я написал для вышеуказанных двух классов:

class wrapper1 {
    private $conn;

    public function __construct(phpclass1 $object) {
        $this->conn = $object;
    }

    public function add(wrapper2 $document) {
        return $this->conn->addDoc($document);
    }
}

class wrapper2 extends phpclass2 {
    private $doc;
    public function __construct() {
        $this->doc = new phpclass2();
    }    
}

Here how I'm using them:
$options = array (...);
$object = new phpclass1($options);
$conn = new wrapper1($object);
$doc = new wrapper2();
....
....
$conn->add($doc);

Все работало, пока я не использовал функцию add. Это дает ошибку: Argument 1 passed to phpclass1::addDoc() must be an instance of phpclass2, instance of wrapper2 given

Что мне не хватает? Я пробовал много вещей, но полностью потерял здесь.

Ответ 1

Вы определили

class phpclass1 :: addDoc(phpclass2 $string)

Этот метод ожидает, что аргумент будет объектом phpclass2, но вы проходите

return $this->conn->addDoc($document);

через

$conn->add($doc);

и $doc - это объект wrapper2, а не phpclass2

Чтобы исправить добавление нового общедоступного метода

wrapper2::getDoc()

public function add(wrapper2 $document) {
    return $this->conn->addDoc($document->getDoc());
}

Ответ 2

ПРОБЛЕМА

Вы вводите тип wrapper1, чтобы принять тип wrapper2 все хорошо и хорошо. Внутри метода wrapper1 вы объявляете

public function add(wrapper2 $document) {
        return $this->conn->addDoc($document);
    }

где $conn определяется как экземпляр phpclass1. Проблема возникает при вызове

return $this->conn->addDoc($document);

который ожидает тип phpclass2, но $document на самом деле является типом wrapper2, поскольку мы его не можем редактировать либо phpclass1 OR phpclass2, вам нужно будет изменить классы обертки.

Решения

Решение 1

либо измените wrapper2 to be

class wrapper2 {
    private $doc;
    public function __construct() {
        $this->doc = new phpclass2();
    }
    public function GetDoc()
    {
      return $this->doc;
    }
}

и используйте следующим образом

$conn->add($doc->GetDoc());

Решение 2

изменить подпись $doc; внутри wrapper2 до public и использовать следующим образом

$conn->add($doc->doc);

для получения дополнительной информации о typehinting в php см. страницу документации для него подсказка типа php

еще одна вещь, которую нужно рассмотреть, - это вам нужно/хотите набрать подсказку, не помещая аргумент для/против, поскольку его уже обсуждали подробно, просто вопрос, который вы можете задать.

Если да, вы можете прочитать следующую ссылку , в которой говорится о хороших способах и причинах использования намека типа

Я надеюсь, что это поможет

Ответ 3

Твой phpclass1::addDoc тип намекает, чтобы взять только объект phpclass2. Ваш метод wrapper1::add принимает объект типа wrapper2, а затем передает его в phpclass1::addDoc. Основываясь на ваших классах, это несовместимо, поскольку wrapper2 не является экземпляром phpclass2.

Вам нужно изменить свой тип или разрешить классу wrapper2 предоставлять объект phpclass2, который он обертывает или расширяет wrapper2, чтобы он являлся экземпляром phpclass2

Ответ 4

Измените public function add(wrapper2 $document) на public function add($document). тип hinting является проблемой.