CODE – El contenido de un objeto se cambia después de ejecutar una función

El problema es que el contenido de $oldpop cambia mágicamente después de ejecutar la función func , mientras que la entrada de func es $matepop . Dentro de func , $oldpop no se usa (agregué la línea de comentarios para mostrar el lugar – ver el final del fragmento de código de MAIN.PHP ). A continuación, proporciono solo algunas partes principales del código. Tal vez, alguien podría sugerir la razón del problema?

Debo mencionar que no uso variables estáticas.

Archivo MAIN.PHP

 include_once 'func.php'; include_once 'select.php'; class Individual { private $genes; private $rank; public function __construct() { $this->genes = array(); $this->rank = 0; } public function setRank($val){ $this->rank = $val; } public function setGene($i,$val){ $this->genes[$i] = $val; } } class Population { private $ind; public function __construct() { $this->ind = array(); } public function addIndividual(Individual $ind) { $this->ind[] = $ind; } public function getIndividual($i){ return $this->ind[$i]; } } $oldpop = new Population(); for($i=0; $iaddIndividual(new Individual()); } $oldpop = func($oldpop,$popsize); for ($i = 0; $i < $gener; $i++) { $matepop = new Population(); $matepop = nselect($matepop,$oldpop,$popsize); // !!! Here the $oldpop content is correct (original) $matepop = func($matepop,$popsize); // !!!! Here the original content of $oldpop is magically changed } 

Archivo SELECT.PHP

 function nselect($matepop,$oldpop,$popsize) { $select = array(); //... $select[] = $oldpop->getIndividual($i); //... for ($i=0; $i addIndividual($select[$i]); } return $matepop; } 

Archivo FUNC.PHP

 function func($pop,$popsize) { //... $pop->getIndividual($i)->setRank($val); //... return $pop; } 

Las variables de objeto PHP no contienen una copia completa del objeto; más bien, contienen una referencia al objeto. Esto significa que cuando usaste

 $select[] = $oldpop->getIndividual($i); 

en su código, no hizo una nueva copia del objeto $i ; simplemente copió la referencia al objeto $i en la matriz $select . Esto significa que tanto $oldpop como $matepop contienen referencias a los mismos objetos en sus arrays $ind . Luego, cuando más tarde usaste

 $pop->getIndividual($i)->setRank($val); 

para establecer el rango de cada objeto de clase Individual en $matepop , también cambiaron para $oldpop .

En su función nselect() , obtiene individuos de $oldpop y luego los agrega a $matepop :

 $select[] = $oldpop->getIndividual($i); //... for ($i=0; $i < $popsize; $i++) { $matepop->addIndividual($select[$i]); } 

Cuando hace esto, esto no “crea una copia” del individual y agrega la copia; agrega una referencia al original. Entonces, cualquier cosa que le haga a cualquiera de las individuals agregadas a $matepop través de este método se actualizará en $oldpop también porque, bueno, son exactamente el mismo objeto.

Entonces, en su método func() , cuando establece el rango en los individuals en $matepop (y $matepop que esa es la única modificación individual que realiza en esa función) está modificando la única instancia de cada individual , que se hace referencia en $matepop y $oldpop . Es por eso que ves $oldpop modificado.

Para resolver un problema como este, deberá implementar algún tipo de clonación / copia en lugar de una referencia directa.