Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[PHP]ArrayList clonen

Pagina: 1
Acties:

  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
Op het moment ben ik bezig met het clonen van een lijst. Ik heb een class ArrayList, welke kwa werking veel op die van .NET framework lijkt. Voor het voorbeeld heb ik heb even in het klein nagemaakt, maar de onderliggende werking is nog hetzelfde.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class ArrayList
{
    protected $_InnerList = array();
    
    public function Add($object)
    {
        $this->_InnerList[] = $object;
    }
    
    public function Item($index)
    {
        return $this->_InnerList[$index];
    }
    
    public function __clone()
    {
        $outputList = new ArrayList();
        
        foreach($this->_InnerList as $item)
            $outputList->Add(clone $item);
        
        return $outputList;
    }
}


Als test object heb ik de volgende class even gemaakt:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Object
{
    public $Name;
    
    public function __construct($name)
    {
        $this->Name = $name;
    }
    
    public function __clone()
    {
        return new Object($this->Name);
    }
}


Voordat ik naar het clonen van de ArrayList ga zal ik eerst even de stappen aangeven welke ik al heb getest om te laten zien dat opzichzelf alles wel werkt.

PHP:
1
2
3
4
5
6
$obj1 = new Object("Fiets");
$obj2 = clone $obj1;
$obj2->Name = "Trein";

printf('%s - %s' . PHP_EOL, str_pad($obj1->Name, 10), spl_object_hash($obj1));
printf('%s - %s' . PHP_EOL, str_pad($obj2->Name, 10), spl_object_hash($obj2));


Ik verwacht twee lines met Fiets en Trein, deze waardes worden gevolgd door een unieke code die de instantie vertegenwoordig.

code:
1
2
Fiets      - 000000006672dbdb0000000036b51097
Trein      - 000000006672dbd80000000036b51097

In het midden zit het verschil, dus dit werkt.

Volgende stap een lege ArrayList clonen en één object er in plaatsen.

PHP:
1
2
3
4
5
6
$list1 = new ArrayList();
$list2 = clone $list1;
$list2->Add(new Object('Trein'));

echo "List: " . spl_object_hash($list1) . PHP_EOL;
echo "List: " . spl_object_hash($list2) . PHP_EOL;


Verwacht, twee unieke codes, en dat krijg ik ook. Wanneer ik print_r uitvoer op de lijsten dan zie ik dat lijst 1 leeg is en lijst 2 heeft één object met als naam 'Trein'. Gevulde lijsten clonen en daarbij aan toevoegen zorgt er ook voor dat de ik verschillende lijsten zie.

Maar nu doe ik het volgende:
PHP:
1
2
3
4
5
$list3 = new ArrayList();
$list3->Add(new Object("Fiets"));

$cloneList = clone $list3;
$cloneList->Item(0)->Name = 'Trein';


Ik verwacht dat het object in de gekloonde lijst van naam veranderd. Maar om één of andere reden wijzigd hij de naam van het object in $list3 ook. Als ik nu de volgende code uitvoer:

PHP:
1
2
printf('%s - %s' . PHP_EOL, str_pad($list3->Item(0)->Name, 10), spl_object_hash($list3->Item(0)));
printf('%s - %s' . PHP_EOL, str_pad($cloneList->Item(0)->Name, 10), spl_object_hash($cloneList->Item(0)));


Zie ik ook dat de hashcodes van de objecten precies hetzelfde zijn. Als ik de ArrayList clone dan gaat hij daadwerkelijk naar Object::__clone, want als ik hier een 'throw new Exception' in gooi dan gaat hij keihard op zijn bek.

Wat doe ik verkeerd?

  • maxtz0r
  • Registratie: Februari 2007
  • Laatst online: 17-12-2022

Dying is God's way of telling you, you've been FIRED.


  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
In de functie __clone voer ik dit ook uit: $outputList->Add(clone $item); en de code komt ook in de __clone functie van de class Object uit, maar toch gaat er nog iets mis.

  • Tribits
  • Registratie: Augustus 2011
  • Laatst online: 02:56

Tribits

Onkruid vergaat niet

Je voorbeeld werkt volgens mij niet omdat __clone niet zo werkt. Die functie wordt aangeroepen nadat PHP een shallow copy heeft gemaakt en je kunt daarna een deep copy maken van bepaalde objecten. Volgens mij doet het onderstaande stukje code wel wat jij wil:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php 
class ArrayList 
{ 
    public $_InnerList = array();
     
    public function Add($object) 
    { 
        $this->_InnerList[] = $object; 
    } 
     
    public function Item($index) 
    { 
        return $this->_InnerList[$index]; 
    } 
     
    public function __clone() 
    { 
        $a=array();
        foreach($this->_InnerList as $item){
            $a[]=clone $item;
        }
        $this->_InnerList = $a; 
    } 
} 
?>

Master of questionable victories and sheer glorious defeats


  • hillbillie
  • Registratie: November 2010
  • Laatst online: 18-07-2022
Wat tribits zegt. Het heeft niets met de return value te maken (je returned nu een nieuw ArrayList ipv de shallow clone te bewerken).

  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
Dat is het hem inderdaad. Zal mij eens verdiepen in dat shallow en deep clonen van objecten. Bedankt!
Pagina: 1