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;