php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #47345 Cloning non-object does not throw exception?
Submitted: 2009-02-09 09:27 UTC Modified: 2013-08-06 09:33 UTC
Votes:2
Avg. Score:4.5 ± 0.5
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: alt dot e-mail at gmx dot de Assigned: yohgaki (profile)
Status: Closed Package: Class/Object related
PHP Version: 5.3.0beta1 OS: Irrelevant
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: alt dot e-mail at gmx dot de
New email:
PHP Version: OS:

 

 [2009-02-09 09:27 UTC] alt dot e-mail at gmx dot de
Description:
------------
Since v5.2.5, cloning a non-object results in a fatal error. In  my opinion that is the wrong behaviour!

It's not really a fatal error (as in DEATH, CORE-DUMP, END-OF-THE-WORLD) to clone a non-object. It's really just an exception (as in OOPS, HELP?, DO-WHAT-NOW?), that should be user-catchable.

A practical example:

I have an array where the values are strings or objects that can be cast to string with "__toString". If I want to create a copy of that array, I also need to clone the objects. 

Reproduce code:
---------------
<?php
class Color {
    // assume their values are between 0.0 and 1.0
    private $r, $g, $b;
    public function toString() {
        return sprintf("#%02X%02X%02X",
        (int)$this->r*255, (int)$this->g*255, (int)$this->b*255);
    }
}
// somewhere in your code you create an array of colors
$colors = array(
    "#FFF000", new Color( 0, 0, 1 ), // and many more
);
// somewhere else you want to copy that array
// this is the current way
$newColors = array();
foreach ( $colors as $color ) {
    if ( is_object( $color ) {
        try { $newColors[] = clone $color; }
        // do nothing, error in __clone-method or whatever
        catch ( MySomethingException $e ) {}
    }
    else { $newColors[] = $color; }
}
// this is the way it should be
$newColors = array();
foreach ( $colors as $color ) {
    try { $newColors[] = clone $color; }
    catch ( TypeException/*or something*/ $e ) { $newColors[] = $color; }
}


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-02-09 09:34 UTC] alt dot e-mail at gmx dot de
Addendum:

The code for my suggestion should really be:
$newColors = array();
foreach ( $colors as $color ) {
    try { $newColors[] = clone $color; }
    // do nothing, error in __clone-method or whatever
    catch ( MySomethingException $e ) {}
    // Not an object, can't be cloned, "TypeException" would be
    // the exception PHP throws for non-clonables.
    // Really do not care what that name is, just that there is one.
    catch ( TypeException $e ) { $newColors[] = $color; }
}
 [2011-04-08 20:42 UTC] jani@php.net
-Package: Feature/Change Request +Package: Class/Object related
 [2013-08-06 09:33 UTC] yohgaki@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: yohgaki
 [2013-08-06 09:33 UTC] yohgaki@php.net
It seems fixed.

[yohgaki@dev PHP-5.5]$ ./php-bin t.php
PHP Fatal error:  __clone method called on non-object in 
/home/yohgaki/ext/git/oss/php.net/PHP-5.5/t.php on line 28
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Dec 27 01:01:28 2024 UTC