Php 是否可以从现有对象实例化?
我偶然发现了这一点,并想知道这是否是预期的行为:Php 是否可以从现有对象实例化?,php,oop,Php,Oop,我偶然发现了这一点,并想知道这是否是预期的行为: 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;
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=新狗编码代码>
我不希望通过从实例化中实例化来创建新对象。。。如果这有意义的话
这是预期的功能,还是只是一个愉快的意外
我在构建一个需要与几个不同的db表对话的模型时发现了这一点,我使用依赖项注入来传递数据库抽象:
class ShowConnectedTables {
public function __constructor($db) {
$this->modelOne = new ModelOne($db);
$this->modelTwo = new ModelTwo($db);
}
// ... snip ...
}
$table = new ShowConnectedTables(new Database);
有时,在一个循环取取模型中间的一个数据库调用ModelTwo,一个行可能会阻塞模型一行的取值。那么,这是否可以接受
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);
我从来没有见过这样或做过这样的事。因此,我可能会避免这样做:如果这会导致其他开发人员看到它并挠头(就像你做的那样),那么这可能是不值得的。毕竟,我看不出你为什么要这么做
Don't Panic指出,虽然没有明确的文档记录,但PHP文档中有一个这样做的例子
也就是说,没有克隆在进行:
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();
这不是创建对现有对象的新引用的问题。构造函数被执行,这意味着这是一个新对象。我已经厌倦了:
<?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;
使用clone
肯定更为传统-我认为在现有对象的基础上创建新对象,而不是在副本中表示其状态,这不是一种特别常见的情况。我也不知道这是可行的(显然是从PHP5第一次出现以来),所以谢谢你教我一些东西。看这里:显然,这个行为不是非常规的,从这个例子来看,@MarkBaker似乎是错误的,因为测试表明创建的对象是different@MarkBaker我认为这是指做$newObj=$existingObj
,而不是$newObj=*new*$existingObj
嗯,我也不知道你能这么做。我不会这么做,只是因为这很奇怪。如果我以后再看那段代码,我可能一开始都不会意识到发生了什么。是的,除非迫不得已,否则我也不会使用它。。但这是有用的!在代码中添加注释以防忘记的事情在某种程度上是有文档记录的。[,在例5中。虽然没有对它的任何描述。的确,文档中有它。但是很容易错过。get_class
是我正要尝试的东西,但我无意中发现了它。感谢您的输入;在接受答案之前,我会让它搁置一天。更新的链接:
<?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;