我偶然发现了这一点,并想知道这是否是预期的行为:
Interactive shell
php > class dog {
php { public $name='doggy';
php { public function speak() {
php { echo "bark, bark! (my name is " . $this->name . ")\n";
php { }
php { }
php >
php > $puppy = new dog;
php > $puppy->speak();
bark, bark! (my name is doggy)
php >
php > $taffy = new $puppy;
php > $taffy->speak();
bark, bark! (my name is doggy)
php >
php > $taffy->name = "Taffy";
php > $taffy->speak();
bark, bark! (my name is Taffy)
php >
php > $puppy->speak();
bark, bark! (my name is doggy)
php >
我的问题是关于这一行$taffy = new $puppy;
通常,我会编码$taffy = new dog;
我不希望通过实例化实例化来创建新对象......如果这有意义的话。
这是预期的功能,还是只是一次幸福的事故?
我在构建需要与几个不同的db表交谈的模型时发现了这一点,并且我使用依赖注入来传递数据库抽象:
class ShowConnectedTables {
public function __constructor($db) {
$this->modelOne = new ModelOne($db);
$this->modelTwo = new ModelTwo($db);
}
// ... snip ...
}
$table = new ShowConnectedTables(new Database);
但是,有时候,在循环中取出ModelOne的行时,对ModelTwo的数据库调用可能会破坏对ModelOne行的提取。
是否可以接受class ShowConnectedTables {
public function __constructor($db) {
$this->modelOne = new ModelOne($db);
$this->modelTwo = new ModelTwo(new $db); // note new abstraction
}
// ... snip ...
}
$table = new ShowConnectedTables(new Database);
答案 0 :(得分:2)
我从未见过这样或做过这件事。因此,我可能会避免它:如果它会导致其他开发人员看到它并刮擦他们的头(就像你一样),它可能是不值得的。毕竟,我看不出有什么理由让你特意这么做。
请不要恐慌地指出,虽然没有明确记录,但在PHP文档中有一个这样做的例子。 Example 5 on this page.
话虽如此,没有克隆人在进行:
class dog {
public $name='doggy';
public function speak() {
echo "bark, bark! (my name is " . $this->name . ")\n<br>";
}
public function __clone() {
print 'This is not called!';
parent::__clone();
}
}
$class = 'dog';
$puppy = new dog;
$puppy->name = 'Puppy';
$taffy = new $puppy;
if ( spl_object_hash( $taffy ) != spl_object_hash( $puppy ) )
print 'not the same object';
$taffy->speak();
如果执行上述操作,您会发现对象不相同,并且永远不会调用__clone方法。此外,您的太妃糖将使用doggy
的名称进行初始化,而不是Puppy
。这似乎是有效的简写:
$class = get_class( $puppy );
$taffy = new $class;
答案 1 :(得分:1)
这不是创建对现有对象的新引用的问题。构造函数被执行,这意味着,这是一个新对象。我已经厌倦了:
<?php
class dog {
public $name;
public function __construct($name = '') {
$this->name = $name ?: 'doggy';
}
public function speak() {
echo "bark, bark! (my name is " . $this->name . ")\n";
}
}
$puppy = new dog;
$puppy->speak(); #bark, bark! (my name is doggy)
$taffy = new $puppy('Snuffels');
$taffy->speak(); #bark, bark! (my name is Snuffels)
$taffy->name = "Taffy";
$taffy->speak(); #bark, bark! (my name is Taffy)
$puppy->speak(); #bark, bark! (my name is doggy)
echo $puppy;
IMO的原因是,您已经可以使用new self
或new parent
之类的内容,请参阅http://php.net/manual/en/language.oop5.basic.php
在类上下文中,可以通过
new self
和new parent
创建新对象。
我认为,他们在new
之后的事物中实现了类识别。但仍然是一个好的WTF:)