简体   繁体   中英

instanceof error in php wrapper class

I started of writing a wrapper class for a pre-defined php package. Here are the classes:

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

...

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

Here are the wrapper classes that I wrote for the above 2 classes:

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's how I'm using them:
$options = array (...);
$object = new phpclass1($options);
$conn = new wrapper1($object);
$doc = new wrapper2();
....
....
$conn->add($doc);

Everything was working until I used the add function. It gives an error: Argument 1 passed to phpclass1::addDoc() must be an instance of phpclass2, instance of wrapper2 given

What am I missing? I've tried out many things, but completely lost here.

You have defined

class phpclass1 :: addDoc(phpclass2 $string)

This method expects the argument to be an object of phpclass2, but you are passing

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

through

$conn->add($doc);

and $doc is an object of wrapper2 not phpclass2

To fix add a new public method

wrapper2::getDoc()

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

THE PROBLEM

You are type hinting a wrapper1 method to accept type of wrapper2 all well and good. Inside the wrapper1 method you declare

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

where $conn is defined as a phpclass1 instance. The problem arises as you call

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

which is expecting a type of phpclass2 but $document is in fact a type of wrapper2 as we take it you cannot edit either phpclass1 OR phpclass2 you will need to modify your wrapper classes.

The Solutions

Solution 1

either change wrapper2 to be

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

and use as follows

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

Solution 2

change the signature of $doc; inside of wrapper2 to public and use as follows

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

for more information on typehinting in php have a look at the documentation page for it php type hinting

one other thing to consider is do you need/want to type hint, not putting up an argument for/against as its already been debated at length, just a question that you may want to ask.

If the answer is yes, you may want to read the following link which talks about good ways and reasons to use type hinting

I hope this helps

Your phpclass1::addDoc is type hinted to take only an object of phpclass2 . Your wrapper1::add method takes an object of type wrapper2 and then passes it to the phpclass1::addDoc Based on your classes this is inconsistent as wrapper2 is not an instance of phpclass2 .

You need to change your typehint or allow the wrapper2 class to provide the phpclass2 object that it is wrapping or extending the wrapper2 so that it is an instance of phpclass2

更改public function add(wrapper2 $document)public function add($document) 类型提示是问题。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM