Maison  >  Article  >  développement back-end  >  Comment comprendre les références d'objets, les copies superficielles et les copies profondes en PHP

Comment comprendre les références d'objets, les copies superficielles et les copies profondes en PHP

不言
不言original
2018-04-09 17:06:541412parcourir

Cet article vous explique comment comprendre les références d'objets, la copie superficielle et la copie profonde en PHP. Les amis dans le besoin peuvent s'y référer

De nombreux PHP débutants ne sont pas familiers avec la programmation oop. . Lorsque je lisais récemment le livre "Junior PHP Engineer", j'étais vague sur la partie référence des objets. Après avoir vérifié certaines informations et les avoir comprises, j'ai eu envie de faire un constat ici et de me dire qu'il fallait consolider ces fondations.

Article de référence : https://blog.csdn.net/hel12he/article/details/49617023

                                                                                     🎜>

Tout d'abord, nous devons comprendre comment l'espace mémoire est distribué en PHP. De manière générale, l'espace mémoire est divisé en

mémoire de tas, mémoire de pile, segment de données, segment de code , comme indiqué ci-dessous :

Alors, qu'est-ce qu'un référence d'objet ? Du drap de laine ?

Lorsque nous utilisons le mot-clé new pour instancier une classe, nous pouvons accéder aux propriétés et méthodes de la classe via cet objet. Et chaque objet est indépendant. Par exemple, une classe de voiture a des attributs tels que la taille, la couleur et les méthodes de conduite. Cette classe peut être instanciée en plusieurs objets, et les méthodes d'attribut de chaque objet peuvent être modifiées. possède son propre espace mémoire, qui contient les attributs et méthodes de la classe d'instance, ou en utilisant des alias, pointent en fait vers le même espace mémoire, par exemple :

<?php
  class One
{
    public $name;

    public function __construct($name)
    {
        $this->name = $name;
    }
}
//实例化,并且向构造函数传递参数
$o1 = new One(&#39;test1&#39;);
echo "对象1的name值为:".$o1->name."<br/>";
//引用
$o2 = $o1;
//打印对象2的$name属性
echo "对象2的name值为:".$o2->name."<br/>";
//修改对象$o2的$name属性
echo "修改对象2的name为test2"."<br/>";
$o2->name = &#39;test2&#39;;
//比较此时两个对象的$name值
echo "修改后对象1的name值为:".$o1->name."<br/>";
echo "修改后对象2的name值为:".$o2->name."<br/>";
Imprimer les résultats : <.>

On peut voir que la référence n'est essentiellement qu'un alias de l'objet. En fait, l'espace mémoire pointé par l'objet référencé et l'objet référençant est toujours le même. . (L'effet de $o2=&o1 ici est également le même).


Alors, qu'est-ce qu'une copie superficielle ?

Concept :

Utiliser le clone pour copier un objet. Ce type de copie est appelé "copie superficielle". Toutes les variables de l'objet attribué ont toujours la même valeur que l'objet d'origine, et toutes les références aux autres. objets Les deux pointent toujours vers l’objet d’origine.

C'est-à-dire qu'une copie superficielle ne copie que l'objet considéré, pas les objets auxquels il fait référence.

Utilisons le même exemple et changeons $o2=$o1 en $o2=clone $o1. Le résultat de l'impression est le suivant :


Comme vous pouvez le voir, lorsque nous modifions uniquement la valeur de objet 2, l'objet 1 n'a pas changé, car l'utilisation du mot-clé clone génère une copie de l'objet. Cette copie possède également son propre espace mémoire, et elles étaient auparavant indépendantes l'une de l'autre. Mais dans une copie superficielle, l’objet auquel il fait référence n’est pas copié.


前面说的东西都是内容只有数值的情况,当内容中也有引用的对象那就不一样了,也就引出了深复制的概念。

深复制概念:被复制的对象的所有的变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。也就是说深复制把要复制的对象所引用的对象都复制了一遍。

两种方法:

利用__clone魔术方法

public function __clone()
{
    $this->obj = new Obj();
}


利用串行化

$t = serialize($o1);
$o2 = unserialize($t);


举个栗子:

<?php
header("Content-type:text/html;charset=utf-8");
class TvControl{
}
class Tv{
    private $color;
    private $tvControl;
    function __construct(){
        $this->color = "black";
        $this->tvControl = new TvControl();
    }
    
    function getTvControl(){
        return $this->tvControl;
    }
}
		$tv1 = new Tv();
		$tvControl1 = $tv1->getTvControl();
		echo "原始类:"."<br/>";
		var_dump($tv1);
		echo "<br/>";
		$tv2 = $tv1;
		echo "引用类:"."<br/>";
		var_dump($tv2);
		echo "<br/>";
		$tv3 = clone $tv1;
		echo "克隆(浅复制):"."<br/>";
		var_dump($tv3);
		echo "<br/>";
		$tv4 = unserialize(serialize($tv1));
		echo "深复制:"."<br/>";
		var_dump($tv4);

打印结果:


深复制获取到的对象也是一个全新的对象。

那么如何比较两个对象是否引用于同一个对象呢?

Nous pouvons utiliser "===" pour comparer si deux objets font référence au même objet initial. Et "==" ne peut comparer que si deux objets ont la même classe et les mêmes attributs.

Recommandations associées :

Compréhension approfondie de la fonction de comptage des tableaux PHP

Compréhension approfondie des instructions de boucle php


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn