【问题标题】:How to Copy an Object in PHP?如何在 PHP 中复制对象?
【发布时间】:2011-01-02 07:27:09
【问题描述】:

我有一个简单的“维度”类,其中包含一个宽度/高度属性和一个用于设置它们的构造函数。

我有一个函数(重新调整尺寸),它需要两个维度对象——一个要重新调整大小,一个包含最大大小。它应该减少第一个参数中的尺寸,以便它们“适合”第二个参数。

然后它返回第一个新调整大小的。

调用者传入维度对象并将返回值放入另一个对象——因为它必须保留原始对象。但是传递给函数的那个​​会被修改。

这很令人惊讶,因为我没有参考它:

private function scale_image_dimensions(Dimensions $dimensions, Dimensions $max_size) {

    if( $dimensions->width > $max_size->width ) {
        $dimensions->height = $dimensions->height / ($dimensions->width / $max_size->width);
        $dimensions->width = $max_size->width;
    }

    if( $dimensions->height > $max_size->height ) {
        $dimensions->width = $dimensions->width / ($dimensions->height / $max_size->height);
        $dimensions->height = $max_size->height;
    }

    return $dimensions;
}

如何指定我希望函数复制传递给它的对象,然后返回其中一个?

更新

似乎还有其他问题——我将参数从$dimensions 更改为$adimensions,并将$dimensions = $adimensions 放在函数的开头。

但是调用者的变量仍然被修改了!分配是否也可以通过引用进行?我的意思是...没有办法使赋值运算符重载或复制构造函数,所以...我该怎么办?如果我想要一份副本,我必须每次显式初始化一个?

【问题讨论】:

    标签: php function reference object


    【解决方案1】:

    以为很多人完全反对cloning,我完全赞成it

    编辑:对象是通过引用分配的,也是通过引用传递的。

    如果您需要一个对象的深度克隆,请使用$cloned = clone $dimensions 中的clone 关键字,并在Dimensions 类中定义魔术方法__clone(),以确保Dimensions 中的任何对象引用实际上是也被克隆了。

    【讨论】:

    • 当我发现第一个链接是一篇关于生物克隆的文章时,我真的很高兴。
    • 我会用这个答案来解释“深”和“浅”克隆之间的区别,并描述如何进行深度克隆
    【解决方案2】:

    默认情况下,所有对象都称为引用。为了制作对象的副本,您必须使用 clone 关键字克隆它。

    private function scale_image_dimensions(Dimensions $dimensions, Dimensions $max_size) {
        $old_dimensions = $dimensions;
        $dimensions = clone $dimensions;
    
        if( $dimensions->width > $max_size->width ) {
            $dimensions->height = $dimensions->height / ($dimensions->width / $max_size->width);
            $dimensions->width = $max_size->width;
        }
    
        if( $dimensions->height > $max_size->height ) {
            $dimensions->width = $dimensions->width / ($dimensions->height / $max_size->height);
            $dimensions->height = $max_size->height;
        }
    
        return $dimensions;
    }
    

    这可以防止 PHP 生成大量对象,并且通常人们希望对象通过引用传递。

    PHP 类并不经常用作“数据存储”实用程序,因为数组通常也可以正常工作。

    但是,如果您要使用另一种确实使用许多类来存储数据的语言,我可以看到这将是一个大问题。

    【讨论】:

    • 当每个人都赞成所有与您的完全相同但不是您的答案的所有其他答案时,一定会喜欢!
    • 我正在阅读并发表评论,抱歉。哈哈,这是一次糟糕的经历
    • ps。我为构造函数使用了一个类,因为应用程序的其余部分都是类,而且我不知道这个克隆问题。
    【解决方案3】:

    the clone keyword 可能是您要找的吗?

    $return_dimensions = clone $dimensions;
    

    【讨论】:

      【解决方案4】:

      PHP5 自动将参数作为引用处理。您可以使用 clone 关键字克隆对象。

      $newObject = clone $originalObject;
      

      您应该关注的一件事是克隆时完整副本和浅表副本之间的区别。默认情况下,clone 只会做一个浅拷贝。

      【讨论】:

        【解决方案5】:

        从某种意义上说,参数是按值传递的,因为您可以重新分配 $dimensions 而不会影响原始参数。

        但对象变量只是指向实际对象的指针,因此更改其成员变量会影响原始对象是正确的。

        如果您想避免这种情况,您需要克隆对象。 PHP 有一个cloning 特性,但请记住它默认生成浅拷贝。因此,如果您的对象包含其他对象,您将不会获得这些对象的克隆;只是参考原件。您可能只想手动创建新对象并自己复制它们的值。

        【讨论】:

          猜你喜欢
          • 2015-02-06
          • 1970-01-01
          • 1970-01-01
          • 2012-03-10
          • 2010-09-12
          • 2010-10-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多