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
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
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: Thu Dec 26 12:01:30 2024 UTC