【问题标题】:Object assignments in PHPPHP 中的对象赋值
【发布时间】:2013-04-24 08:25:11
【问题描述】:

我是一名 PHP 学习者。请帮助我了解下面的 PHP OOP 代码:

class x{}
$x = new x; 
$x->name = "Chandan";

class y extends x {}  // Inheritance
$y = new y;

var_dump($x);   // object X; Shows Name property
var_dump($y);   // object y; Empty

$y = $x; 
var_dump($x);   // object X; name = chandan
var_dump($y);   // object X; name = chandan

$x->name = "Debasis";
var_dump($x);   // object X; name = debasis
var_dump($y);   // object X; name = debasis

问题:

  1. 当我们说 $x->name = "Chandan";它会创建公共属性吗?在 C++ 中从未见过这样的分配。

  2. 对 $x->name 的更改也反映在 $y 对象中。为什么? $y = $x 应该创建一个 $x 的副本。

【问题讨论】:

  • 1 -> 是,2 -> 不,不。
  • 对 2 的补充:注意两个 var_dump 之后的 #1。这是同一个对象。也许您想使用clone
  • X 是空类,所以 y 没有扩展任何内容。您动态地为对象赋值(类仍然为空)。你永远不会在 PHP 中看到这样的东西:D
  • 我认为1 也应该会导致某种可恢复的错误。这可能会让你感兴趣:php.net/manual/pl/language.oop5.magic.php

标签: php oop object


【解决方案1】:

如果要创建动态对象:

$obj = new STDClass(); //Just a simple container, pretty much like array
$obj->anyStuff = "string" ; //Declare some public variables outside the class.

否则你必须在你的类中显式声明变量。

另外,对象总是通过引用传递(或赋值),因为$obj 实际上并不是一个对象,它只是一个引用,一个指向它的链接。对象本身包含在内存中。

$another = $obj ; 只会创建对同一对象的另一个引用。

要克隆对象,您必须使用: $clone = clone $obj;

您还可以定义一个魔术方法__clone(),可以在克隆对象时执行。

更多信息http://php.net/manual/en/language.oop5.cloning.php

【讨论】:

    【解决方案2】:

    当我们说 $x->name = "Chandan";它会创建公共属性吗? 在 C++ 中从未见过这样的分配。

    当你表演时:

    $x = new x; 
    $x->name = "Chandan";
    

    它创建x 类的新实例。所以,$x->name 只分配给这个实例,而不是一个类。这是一个public 属性,但仅存在于$x 实例中。


    对 $x->name 的更改也反映在 $y 对象中。为什么? $y = $x 应该创建一个 $x 的副本。

    class y extends x {}  // Inheritance
    $y = new y;
    

    在第一行中,您声明了y 类,它扩展了xy 类从 x 获取了所有内容,但仍然无法访问 xs 私人成员。它没有继承$x->name,因为该属性存在于$x 实例中,但不存在于x 类中。

    $y = $x;
    

    $y 引用了$x。它不存储$x 的克隆,而是引用它存储的地方。这就是为什么$y 受此影响:

    $x->name = "Debasis";
    var_dump($x);   // object X; name = debasis
    var_dump($y);   // object X; name = debasis
    

    PHP 中的对象总是通过引用隐式传递。如果您需要克隆,则需要使用clone 关键字显式创建它:

    $y = clone $x;
    

    一些有用的链接:

    【讨论】:

      【解决方案3】:

      如果对象定义让您感到困惑,您可以采取不同的做法。我通常用其他语言来构造对象,唯一的区别是你不必定义类型:

      class MyClass { 
      
          // Can use private variables
          private $m_PrivateVar; 
          // Can use protected variables
          protected $m_ProtectedVar;
          // Can use public variables
          public $m_PublicVar
      
          function __construct()
          {
             // Constructor
          }    
          //etc
      }
      

      正如对问题 2 的回答:对象始终通过引用传递,因此当将它们传递给函数时,您不会为该函数创建副本,它是同一个对象(就像传递指向标准变量的指针一样)。赋值也是如此,你的新对象 $y 在执行$y = $x 之后实际上不再是新对象,它现在是指向 $x 的指针。如果您想制作副本,则必须在对象上手动创建复制/克隆功能。

      【讨论】:

      • 只是说,在PHP中有__construct()作为构造函数。
      • 请注意,通常没有人“手动创建[s]复制/克隆功能”他们使用语言clone function
      猜你喜欢
      • 2013-11-24
      • 2013-12-07
      • 1970-01-01
      • 2012-06-16
      • 2013-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-16
      相关资源
      最近更新 更多