如何在PHP中复制对象?

时间:2010-01-07 00:34:53

标签: php function reference object

我有一个包含width / height属性的简单'dimension'类和一个用于设置它们的构造函数。

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

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

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

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

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放在函数的开头。

但调用者的变量仍然被修改了!作业也可以参考吗?我的意思是......没有办法使赋值运算符重载,或者复制构造函数如此......我该怎么办?如果我想要一个副本,我必须每次显式初始化一个

5 个答案:

答案 0 :(得分:3)

认为很多人完全反对cloning,我全都是it

编辑:对象通过引用分配并通过引用传递。

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

答案 1 :(得分: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类通常不会用作“数据存储”实用程序,因为数组通常也可以正常工作。

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

答案 2 :(得分:1)

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

$return_dimensions = clone $dimensions;

答案 3 :(得分:1)

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

$newObject = clone $originalObject;

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

答案 4 :(得分:1)

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

但是对象变量只是指向实际对象的指针,所以改变它们的成员变量会影响原始对象是正确的。

如果要避免这种情况,则需要克隆对象。 PHP具有cloning功能,但请记住,默认情况下它会生成浅拷贝。因此,如果您的对象包含其他对象,您将无法获得这些对象的克隆;只是对原件的引用。您可能只想手动创建新对象并自行复制它们的值。