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.