<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.oop5.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'fr',
  ),
  'this' => 
  array (
    0 => 'language.oop5.property-hooks.php',
    1 => 'Hooks de propri&eacute;t&eacute;',
    2 => 'Hooks de propri&eacute;t&eacute;',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Les classes et les objets',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.properties.php',
    1 => 'Propri&eacute;t&eacute;s',
  ),
  'next' => 
  array (
    0 => 'language.oop5.constants.php',
    1 => 'Constantes de classe',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'fr',
    'path' => 'language/oop5/property-hooks.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.oop5.property-hooks" class="sect1">
 <h2 class="title">Hooks de propriété</h2>

 <p class="simpara">
  Les hooks de propriété, également connus sous le nom d&#039;&quot;accesseurs de propriété&quot; dans d&#039;autres langages,
  sont une façon d&#039;intercepter et de remplacer le comportement de lecture et d&#039;écriture d&#039;une propriété.
  Cette fonctionnalité sert à deux fins :
 </p>
 <ol type="1">
  <li class="listitem">
   <span class="simpara">
    Elle permet d&#039;utiliser directement des propriétés, sans avoir besoin de méthodes get et set,
    tout en laissant la possibilité d&#039;ajouter un comportement supplémentaire à l&#039;avenir.
    Cela rend la plupart des méthodes get/set inutiles,
    même sans utiliser de hooks.
   </span>
  </li>
  <li class="listitem">
   <span class="simpara">
    Elle permet de définir des propriétés qui décrivent un objet sans stocker
    directement de valeur.
   </span>
  </li>
 </ol>
 <p class="simpara">
  Il existe deux hooks disponibles sur les propriétés non-statiques : <code class="literal">get</code> et <code class="literal">set</code>.
  Ils permettent de remplacer le comportement de lecture et d&#039;écriture d&#039;une propriété, respectivement.
  Les hooks sont disponibles pour les propriétés typées et non typées.
 </p>
 <p class="simpara">
  Une propriété peut être &quot;backed&quot; ou &quot;virtuelle&quot;.
  Une propriété &quot;backed&quot; est une propriété qui stocke effectivement une valeur.
  Toute propriété qui n&#039;a pas de hooks est &quot;backed&quot;.
  Une propriété virtuelle est une propriété qui a des hooks et ces hooks n&#039;interagissent pas avec la propriété elle-même.
  Dans ce cas, les hooks sont effectivement les mêmes que les méthodes,
  et l&#039;objet n&#039;utilise pas d&#039;espace pour stocker une valeur pour cette propriété.
 </p>
 <p class="simpara">
  Les hooks de propriété sont incompatibles avec les propriétés <code class="literal">readonly</code>.
  S&#039;il est nécessaire de restreindre l&#039;accès à une opération <code class="literal">get</code> ou <code class="literal">set</code>
  en plus de modifier son comportement, il convient d&#039;utiliser
  <a href="language.oop5.visibility.php#language.oop5.visibility-members-aviz" class="link">la visibilité asymétrique de propriété</a>.
 </p>

 <blockquote class="note"><p><strong class="note">Note</strong>: 
  <strong>Information de version</strong><br />
  <span class="simpara">
   Les hooks de propriété ont été introduits en PHP 8.4.
  </span>
 </p></blockquote>

 <div class="sect2">
  <h3 class="title">Syntaxe de base des hooks</h3>
  <p class="simpara">
   La syntaxe générale pour déclarer un hook est la suivante.
  </p>
  <div class="example" id="example-1">
   <p><strong>Exemple #1 Hooks de propriété (version complète)</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Example<br /></span><span style="color: #007700">{<br />    private </span><span style="color: #0000BB">bool $modified </span><span style="color: #007700">= </span><span style="color: #0000BB">false</span><span style="color: #007700">;<br /><br />    public </span><span style="color: #0000BB">string $foo </span><span style="color: #007700">= </span><span style="color: #DD0000">'default value' </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">get </span><span style="color: #007700">{<br />            if (</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">modified</span><span style="color: #007700">) {<br />                return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo </span><span style="color: #007700">. </span><span style="color: #DD0000">' (modified)'</span><span style="color: #007700">;<br />            }<br />            return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo</span><span style="color: #007700">;<br />        }<br />        </span><span style="color: #0000BB">set</span><span style="color: #007700">(</span><span style="color: #0000BB">string $value</span><span style="color: #007700">) {<br />            </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo </span><span style="color: #007700">= </span><span style="color: #0000BB">strtolower</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br />            </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">modified </span><span style="color: #007700">= </span><span style="color: #0000BB">true</span><span style="color: #007700">;<br />        }<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$example </span><span style="color: #007700">= new </span><span style="color: #0000BB">Example</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$example</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo </span><span style="color: #007700">= </span><span style="color: #DD0000">'changed'</span><span style="color: #007700">;<br />print </span><span style="color: #0000BB">$example</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
  <p class="simpara">
   La propriété <var class="varname">$foo</var> se termine par <code class="literal">{}</code>, plutôt qu&#039;un point-virgule.
   Cela indique la présence de hooks.
   Un hook <code class="literal">get</code> et un hook <code class="literal">set</code> sont définis,
   bien qu&#039;il soit possible de n&#039;en définir qu&#039;un seul.
   Les deux hooks ont un corps, indiqué par <code class="literal">{}</code>, qui peut contenir du code arbitraire.
  </p>
  <p class="simpara">
   Le hook <code class="literal">set</code> permet également de spécifier le type et le nom d&#039;une valeur entrante,
   en utilisant la même syntaxe qu&#039;une méthode.
   Le type doit être soit le même que le type de la propriété,
   ou <a href="language.oop5.variance.php#language.oop5.variance.contravariance" class="link">contravariant</a> (plus large) que celui-ci.
   Par exemple, une propriété de type <span class="type"><a href="language.types.string.php" class="type string">string</a></span> pourrait avoir
   un hook <code class="literal">set</code> qui accepte un <span class="type"><span class="type"><a href="language.types.string.php" class="type string">string</a></span>|<span class="type"><a href="class.stringable.php" class="type Stringable">Stringable</a></span></span>,
   mais pas un qui n&#039;accepte que <span class="type"><a href="language.types.array.php" class="type array">array</a></span>.
  </p>
  <p class="simpara">
   Au moins un des hooks fait référence à <code class="code">$this-&gt;foo</code>, la propriété elle-même.
   Cela signifie que la propriété sera &quot;backed&quot;.
   Lors de l&#039;appel <code class="code">$example-&gt;foo = &#039;changed&#039;</code>,
   la chaîne fournie sera d&#039;abord convertie en minuscules, puis enregistrée dans la valeur de sauvegarde.
   Lors de la lecture de la propriété, la valeur précédemment enregistrée peut conditionnellement être complétée
   avec du texte supplémentaire.
  </p>
  <p class="simpara">
   Il y a plusieurs variantes de syntaxe abrégée pour gérer les cas courants.
  </p>
  <p class="simpara">
   Si le hook <code class="literal">get</code> est une simple expression,
   alors les <code class="literal">{}</code> peuvent être omis et remplacés par une expression fléchée.
  </p>
  <div class="example" id="example-2">
   <p><strong>Exemple #2 Expression de propriété get</strong></p>
   <div class="example-contents"><p>
    Cet exemple est équivalent à l&#039;exemple précédent.
   </p></div>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Example<br /></span><span style="color: #007700">{<br />    private </span><span style="color: #0000BB">bool $modified </span><span style="color: #007700">= </span><span style="color: #0000BB">false</span><span style="color: #007700">;<br /><br />    public </span><span style="color: #0000BB">string $foo </span><span style="color: #007700">= </span><span style="color: #DD0000">'default value' </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">get </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo </span><span style="color: #007700">. (</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">modified </span><span style="color: #007700">? </span><span style="color: #DD0000">' (modified)' </span><span style="color: #007700">: </span><span style="color: #DD0000">''</span><span style="color: #007700">);<br /><br />        </span><span style="color: #0000BB">set</span><span style="color: #007700">(</span><span style="color: #0000BB">string $value</span><span style="color: #007700">) {<br />            </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo </span><span style="color: #007700">= </span><span style="color: #0000BB">strtolower</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br />            </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">modified </span><span style="color: #007700">= </span><span style="color: #0000BB">true</span><span style="color: #007700">;<br />        }<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
  <p class="simpara">
   Si le type du paramètre du hook <code class="literal">set</code> est le même que le type de la propriété (ce qui est typique),
   il peut être omis. Dans ce cas, la valeur à définir est automatiquement nommée <var class="varname">$value</var>.
  </p>
  <div class="example" id="example-3">
   <p><strong>Exemple #3 Paramètres par défaut de propriété</strong></p>
   <div class="example-contents"><p>
    Cet exemple est équivalent à l&#039;exemple précédent.
   </p></div>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Example<br /></span><span style="color: #007700">{<br />    private </span><span style="color: #0000BB">bool $modified </span><span style="color: #007700">= </span><span style="color: #0000BB">false</span><span style="color: #007700">;<br /><br />    public </span><span style="color: #0000BB">string $foo </span><span style="color: #007700">= </span><span style="color: #DD0000">'default value' </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">get </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo </span><span style="color: #007700">. (</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">modified </span><span style="color: #007700">? </span><span style="color: #DD0000">' (modified)' </span><span style="color: #007700">: </span><span style="color: #DD0000">''</span><span style="color: #007700">);<br /><br />        </span><span style="color: #0000BB">set </span><span style="color: #007700">{<br />            </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo </span><span style="color: #007700">= </span><span style="color: #0000BB">strtolower</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br />            </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">modified </span><span style="color: #007700">= </span><span style="color: #0000BB">true</span><span style="color: #007700">;<br />        }<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
  <p class="simpara">
   Si le hook <code class="literal">set</code> ne fait que définir une version modifiée de la valeur passée,
   il peut également être simplifié en une expression fléchée.
   La valeur à laquelle l&#039;expression est évaluée sera définie sur la valeur de sauvegarde.
  </p>
  <div class="example" id="example-4">
   <p><strong>Exemple #4 Expression de propriété set</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Example<br /></span><span style="color: #007700">{<br />    private </span><span style="color: #0000BB">bool $modified </span><span style="color: #007700">= </span><span style="color: #0000BB">false</span><span style="color: #007700">;<br /><br />    public </span><span style="color: #0000BB">string $foo </span><span style="color: #007700">= </span><span style="color: #DD0000">'default value' </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">get </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo </span><span style="color: #007700">. (</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">modified </span><span style="color: #007700">? </span><span style="color: #DD0000">' (modified)' </span><span style="color: #007700">: </span><span style="color: #DD0000">''</span><span style="color: #007700">);<br />        </span><span style="color: #0000BB">set </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">strtolower</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
  <p class="simpara">
   Cet exemple n&#039;est pas tout à fait équivalent au précédent,
   car il ne modifie pas non plus <code class="code">$this-&gt;modified</code>.
   Si plusieurs instructions sont nécessaires dans le corps du hook, utiliser la version avec des accolades.
  </p>
  <p class="simpara">
   Une propriété peut implémenter zéro, un ou les deux hooks selon la situation.
   Toutes les versions abrégées sont mutuellement indépendantes.
   C&#039;est-à-dire qu&#039;utiliser un raccourci pour obtenir une longue définition,
   ou un raccourci pour définir un type explicite, etc., est valide.
  </p>
  <p class="simpara">
   Sur une propriété &quot;backed&quot;, l&#039;omission d&#039;un hook <code class="literal">get</code> ou <code class="literal">set</code>
   signifie que le comportement de lecture ou d&#039;écriture par défaut sera utilisé.
  </p>
  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <span class="simpara">
    Les hooks peuvent être définis lors de l&#039;utilisation de la
    <a href="language.oop5.decon.php#language.oop5.decon.constructor.promotion" class="link">promotion de propriétés dans le constructeur</a>.
    Cependant, dans ce cas, les valeurs fournies
    au constructeur doivent correspondre au type associé à la propriété,
    indépendamment de ce que le hook <code class="literal">set</code> pourrait autoriser.
   </span>
   <span class="simpara">
    Considérez l&#039;exemple suivant :
   </span>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Example<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(<br />        public private(</span><span style="color: #0000BB">set</span><span style="color: #007700">) </span><span style="color: #0000BB">DateTimeInterface $created </span><span style="color: #007700">{<br />            </span><span style="color: #0000BB">set </span><span style="color: #007700">(</span><span style="color: #0000BB">string</span><span style="color: #007700">|</span><span style="color: #0000BB">DateTimeInterface $value</span><span style="color: #007700">) {<br />                if (</span><span style="color: #0000BB">is_string</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">)) {<br />                    </span><span style="color: #0000BB">$value </span><span style="color: #007700">= new </span><span style="color: #0000BB">DateTimeImmutable</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br />                }<br />                </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">created </span><span style="color: #007700">= </span><span style="color: #0000BB">$value</span><span style="color: #007700">;<br />            }<br />        },<br />    ) {<br />    }<br />}</span></span></code></div>
   </div>

   <span class="simpara">
    En interne, le moteur décompose cela de la manière suivante :
   </span>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Example<br /></span><span style="color: #007700">{<br />    public private(</span><span style="color: #0000BB">set</span><span style="color: #007700">) </span><span style="color: #0000BB">DateTimeInterface $created </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">set </span><span style="color: #007700">(</span><span style="color: #0000BB">string</span><span style="color: #007700">|</span><span style="color: #0000BB">DateTimeInterface $value</span><span style="color: #007700">) {<br />            if (</span><span style="color: #0000BB">is_string</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">)) {<br />                </span><span style="color: #0000BB">$value </span><span style="color: #007700">= new </span><span style="color: #0000BB">DateTimeImmutable</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br />            }<br />            </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">created </span><span style="color: #007700">= </span><span style="color: #0000BB">$value</span><span style="color: #007700">;<br />        }<br />    }<br /><br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(<br />        </span><span style="color: #0000BB">DateTimeInterface $created</span><span style="color: #007700">,<br />    ) {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">created </span><span style="color: #007700">= </span><span style="color: #0000BB">$created</span><span style="color: #007700">;<br />    }<br />}</span></span></code></div>
   </div>

   <span class="simpara">
    Toute tentative de définir la propriété en dehors du constructeur
    autorisera soit une <span class="type"><a href="language.types.string.php" class="type string">string</a></span> soit une valeur de type <span class="interfacename"><a href="class.datetimeinterface.php" class="interfacename">DateTimeInterface</a></span>,
    mais le constructeur n&#039;autorisera que <span class="interfacename"><a href="class.datetimeinterface.php" class="interfacename">DateTimeInterface</a></span>.
    Cela s&#039;explique par le fait que le type défini pour la propriété (<span class="interfacename"><a href="class.datetimeinterface.php" class="interfacename">DateTimeInterface</a></span>)
    est utilisé comme type de paramètre dans la signature du constructeur, indépendamment de ce que
    le hook <code class="literal">set</code> permet.
   </span>
   <span class="simpara">
    Si ce type de comportement est nécessaire depuis le constructeur, la promotion
    de propriétés dans le constructeur ne peut pas être utilisée.
   </span>
  </p></blockquote>
 </div>
 <div class="sect2" id="language.oop5.property-hooks.virtual">
  <h3 class="title">Propriétés virtuelles</h3>
  <p class="simpara">
   Les propriétés virtuelles sont des propriétés qui n&#039;ont pas de valeur de sauvegarde.
   Une propriété est virtuelle si ni son hook <code class="literal">get</code> ni son hook <code class="literal">set</code>
   ne fait référence à la propriété elle-même en utilisant une syntaxe exacte.
   C&#039;est-à-dire qu&#039;une propriété nommée <code class="code">$foo</code> dont le hook contient <code class="code">$this-&gt;foo</code> sera sauvegardée.
   Mais la propriété suivante n&#039;est pas une propriété sauvegardée, et générera une erreur :
  </p>
  <div class="example" id="example-5">
   <p><strong>Exemple #5 Propriété virtuelle invalide</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Example<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">string $foo </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">get </span><span style="color: #007700">{<br />            </span><span style="color: #0000BB">$temp </span><span style="color: #007700">= </span><span style="color: #0000BB">__PROPERTY__</span><span style="color: #007700">;<br />            return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">$temp</span><span style="color: #007700">; </span><span style="color: #FF8000">// Ne fait pas référence à $this-&gt;foo, donc cela ne compte pas.<br />        </span><span style="color: #007700">}<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
  <p class="simpara">
   Pour les propriétés virtuelles, si un hook est omis, alors cette opération
   n&#039;existe pas et essayer de l&#039;utiliser produira une erreur.
   Les propriétés virtuelles n&#039;occupent pas d&#039;espace mémoire dans un objet.
   Les propriétés virtuelles sont adaptées pour les propriétés &quot;dérivées&quot;,
   telles que celles qui sont la combinaison de deux autres propriétés.
  </p>
  <div class="example" id="example-6">
   <p><strong>Exemple #6 Propriété virtuelle</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Rectangle<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Une propriété virtuelle.<br />    </span><span style="color: #007700">public </span><span style="color: #0000BB">int $area </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">get </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">h </span><span style="color: #007700">* </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">w</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(public </span><span style="color: #0000BB">int $h</span><span style="color: #007700">, public </span><span style="color: #0000BB">int $w</span><span style="color: #007700">) {}<br />}<br /><br /></span><span style="color: #0000BB">$s </span><span style="color: #007700">= new </span><span style="color: #0000BB">Rectangle</span><span style="color: #007700">(</span><span style="color: #0000BB">4</span><span style="color: #007700">, </span><span style="color: #0000BB">5</span><span style="color: #007700">);<br />print </span><span style="color: #0000BB">$s</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">area</span><span style="color: #007700">; </span><span style="color: #FF8000">// affiche 20<br /></span><span style="color: #0000BB">$s</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">area </span><span style="color: #007700">= </span><span style="color: #0000BB">30</span><span style="color: #007700">; </span><span style="color: #FF8000">// Erreur, car il n'y a pas d'opération de définition.<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
  <p class="simpara">
   Définir à la fois un hook <code class="literal">get</code> et un hook <code class="literal">set</code> sur une propriété virtuelle est également autorisé.
  </p>
 </div>
 <div class="sect2">
  <h3 class="title">Portée</h3>
  <p class="simpara">
   Tous les hooks fonctionnent dans la portée de l&#039;objet modifié.
   Cela signifie qu&#039;ils ont accès à toutes les méthodes publiques, privées ou protégées de l&#039;objet,
   ainsi qu&#039;à toutes les propriétés publiques, privées ou protégées,
   y compris les propriétés qui peuvent avoir leurs propres hooks de propriété.
   Accéder à une autre propriété depuis un hook ne contourne pas les hooks définis sur cette propriété.
  </p>
  <p class="simpara">
   La conséquence la plus notable de cela est que les hooks non triviaux peuvent
   appeler une méthode arbitrairement complexe s&#039;ils le souhaitent.
  </p>
  <div class="example" id="example-7">
   <p><strong>Exemple #7 Appel d&#039;une méthode depuis un hook</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Person </span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">string $phone </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">set </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">sanitizePhone</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br />    }<br /><br />    private function </span><span style="color: #0000BB">sanitizePhone</span><span style="color: #007700">(</span><span style="color: #0000BB">string $value</span><span style="color: #007700">): </span><span style="color: #0000BB">string </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #0000BB">ltrim</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">, </span><span style="color: #DD0000">'+'</span><span style="color: #007700">);<br />        </span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #0000BB">ltrim</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">, </span><span style="color: #DD0000">'1'</span><span style="color: #007700">);<br /><br />        if (!</span><span style="color: #0000BB">preg_match</span><span style="color: #007700">(</span><span style="color: #DD0000">'/\d\d\d\-\d\d\d\-\d\d\d\d/'</span><span style="color: #007700">, </span><span style="color: #0000BB">$value</span><span style="color: #007700">)) {<br />            throw new </span><span style="color: #0000BB">\InvalidArgumentException</span><span style="color: #007700">();<br />        }<br />        return </span><span style="color: #0000BB">$value</span><span style="color: #007700">;<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </div>
 <div class="sect2">
  <h3 class="title">Références</h3>
  <p class="simpara">
   Parce que la présence de hooks intercepte le processus de lecture et d&#039;écriture des propriétés,
   ils posent des problèmes lors de l&#039;acquisition d&#039;une référence à une propriété ou avec une modification indirecte,
   telle que <code class="code">$this-&gt;arrayProp[&#039;key&#039;] = &#039;value&#039;;</code>.
   C&#039;est parce que toute tentative de modification de la valeur par référence contournerait un hook de définition
   s&#039;il en existe un.
  </p>
  <p class="simpara">
   Dans le cas rare où il est nécessaire d&#039;obtenir une référence à une propriété pour laquelle des hooks sont définis,
   le hook <code class="literal">get</code> peut être préfixé par <code class="literal">&amp;</code>
   pour qu&#039;il retourne par référence.
   Définir à la fois <code class="literal">get</code> et <code class="literal">&amp;get</code> sur la
   même propriété est une erreur de syntaxe.
  </p>
  <p class="simpara">
   Définir à la fois les hooks <code class="literal">&amp;get</code> et <code class="literal">set</code> sur une propriété &quot;backed&quot; n&#039;est pas autorisé.
   Comme indiqué ci-dessus, écrire dans la valeur retournée par référence contournerait le hook <code class="literal">set</code>.
   Sur les propriétés virtuelles, il n&#039;y a pas de valeur commune nécessaire partagée entre les deux hooks, donc définir les deux est autorisé.
  </p>
  <p class="simpara">
   Écrire dans un index d&#039;une propriété de tableau implique également une référence implicite.
   Pour cette raison, écrire dans une propriété de tableau &quot;backed&quot; avec des hooks définis est autorisé si et seulement si
   il ne définit qu&#039;un hook <code class="literal">&amp;get</code>.
   Sur une propriété virtuelle, écrire dans le tableau retourné par
   <code class="literal">get</code> ou <code class="literal">&amp;get</code> est légal,
   mais si cela a un impact sur l&#039;objet dépend de l&#039;implémentation du hook.
  </p>
  <p class="simpara">
   Surcharger l&#039;intégralité de la propriété de tableau est autorisé, et se comporte de la même manière que toute autre propriété.
   Ne travailler qu&#039;avec des éléments du tableau nécessite une attention particulière.
  </p>
 </div>
 <div class="sect2">
  <h3 class="title">Héritage</h3>
  <div class="sect3">
   <h4 class="title">Hooks finaux</h4>
   <p class="simpara">
    Les hooks peuvent également être déclarés <a href="language.oop5.final.php" class="link">final</a>,
    auquel cas ils ne peuvent pas être remplacés.
   </p>
   <div class="example" id="example-8">
   <p><strong>Exemple #8 Hooks finaux</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Utilisateur<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">string $identifiant </span><span style="color: #007700">{<br />        final </span><span style="color: #0000BB">set </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">strtolower</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">Responsable </span><span style="color: #007700">extends </span><span style="color: #0000BB">Utilisateur<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">string $identifiant </span><span style="color: #007700">{<br />        </span><span style="color: #FF8000">// Ceci est autorisé<br />        </span><span style="color: #0000BB">get </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">strtoupper</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">identifiant</span><span style="color: #007700">);<br /><br />        </span><span style="color: #FF8000">// Ceci n'est PAS autorisé, car set est final dans le parent.<br />        </span><span style="color: #0000BB">set </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">strtoupper</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
   <p class="simpara">
    Une propriété peut également être déclarée <a href="language.oop5.final.php" class="link">final</a>.
    Une propriété finale ne peut pas être redéclarée par une classe enfant de quelque manière que ce soit,
    ce qui exclut la modification des hooks ou l&#039;élargissement de son accès.
   </p>
   <p class="simpara">
    Déclarer des hooks finaux sur une propriété qui est déclarée finale est redondant,
    et sera silencieusement ignoré.
    C&#039;est le même comportement que pour les méthodes finales.
   </p>
   <p class="simpara">
    Une classe enfant peut définir ou redéfinir des hooks individuels sur une propriété
    en redéfinissant la propriété et uniquement les hooks qu&#039;elle souhaite remplacer.
    Une classe enfant peut également ajouter des hooks à une propriété qui n&#039;en avait pas.
    C&#039;est essentiellement la même chose que si les hooks étaient des méthodes.
   </p>
   <div class="example" id="example-9">
    <p><strong>Exemple #9 Héritage de hook</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Point<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">int $x</span><span style="color: #007700">;<br />    public </span><span style="color: #0000BB">int $y</span><span style="color: #007700">;<br />}<br /><br />class </span><span style="color: #0000BB">PositivePoint </span><span style="color: #007700">extends </span><span style="color: #0000BB">Point<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">int $x </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">set </span><span style="color: #007700">{<br />            if (</span><span style="color: #0000BB">$value </span><span style="color: #007700">&lt; </span><span style="color: #0000BB">0</span><span style="color: #007700">) {<br />                throw new </span><span style="color: #0000BB">\InvalidArgumentException</span><span style="color: #007700">(</span><span style="color: #DD0000">'Too small'</span><span style="color: #007700">);<br />            }<br />            </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">x </span><span style="color: #007700">= </span><span style="color: #0000BB">$value</span><span style="color: #007700">;<br />        }<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
   <p class="simpara">
    Chaque hook remplace les implémentations parentes indépendamment les unes des autres.
    Si une classe enfant ajoute des hooks, toute valeur par défaut définie sur la propriété est supprimée, et doit être redéclarée.
    Cela est cohérent avec le fonctionnement de l&#039;héritage sur les propriétés sans hooks.
   </p>
  </div>
  <div class="sect3">
   <h4 class="title">Accès aux hooks parentaux</h4>
   <p class="simpara">
    Un hook dans une classe enfant peut accéder à la propriété de la classe parente en utilisant le mot-clé
    <code class="code">parent::$prop</code>, suivi du hook désiré.
    Par exemple, <code class="code">parent::$propName::get()</code>.
    Cela peut être lu comme &quot;accéder à la propriété <var class="varname">prop</var> définie sur la classe parente,
    puis exécuter son opération get&quot; (ou set, selon le cas).
   </p>
   <p class="simpara">
    Si ce n&#039;est pas accédé de cette manière, le hook de la classe parente est ignoré.
    Ce comportement est cohérent avec le fonctionnement de toutes les méthodes.
    Cela offre également un moyen d&#039;accéder au stockage de la classe parente, le cas échéant.
    S&#039;il n&#039;y a pas de hook sur la propriété parente,
    son comportement par défaut get/set sera utilisé.
    Les hooks ne peuvent pas accéder à un autre hook que leur propre parent sur leur propre propriété.
   </p>
   <p class="simpara">
    L&#039;exemple ci-dessus pourrait être réécrit comme suit, ce qui permettrait à la
    classe <code class="literal">Point</code> d&#039;ajouter son propre hook <code class="literal">set</code>
    à l&#039;avenir sans problèmes (dans l&#039;exemple précédent, un hook ajouté à la
    classe parente serait ignoré dans la classe enfant).
   </p>
   <div class="example" id="example-10">
    <p><strong>Exemple #10 Accès aux hooks parentaux (set)</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Point<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">int $x</span><span style="color: #007700">;<br />    public </span><span style="color: #0000BB">int $y</span><span style="color: #007700">;<br />}<br /><br />class </span><span style="color: #0000BB">PositivePoint </span><span style="color: #007700">extends </span><span style="color: #0000BB">Point<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">int $x </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">set </span><span style="color: #007700">{<br />            if (</span><span style="color: #0000BB">$value </span><span style="color: #007700">&lt; </span><span style="color: #0000BB">0</span><span style="color: #007700">) {<br />                throw new </span><span style="color: #0000BB">\InvalidArgumentException</span><span style="color: #007700">(</span><span style="color: #DD0000">'Too small'</span><span style="color: #007700">);<br />            }<br />            </span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">$x</span><span style="color: #007700">::</span><span style="color: #0000BB">set</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">);<br />        }<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
   <p class="simpara">
    Un exemple de remplacement uniquement d&#039;un hook get pourrait être :
   </p>
   <div class="example" id="example-11">
    <p><strong>Exemple #11 Accès aux hooks parentaux (get)</strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Strings<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">string $val</span><span style="color: #007700">;<br />}<br /><br />class </span><span style="color: #0000BB">CaseFoldingStrings </span><span style="color: #007700">extends </span><span style="color: #0000BB">Strings<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">bool $uppercase </span><span style="color: #007700">= </span><span style="color: #0000BB">true</span><span style="color: #007700">;<br /><br />    public </span><span style="color: #0000BB">string $val </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">get </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">uppercase<br />            </span><span style="color: #007700">? </span><span style="color: #0000BB">strtoupper</span><span style="color: #007700">(</span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">$val</span><span style="color: #007700">::</span><span style="color: #0000BB">get</span><span style="color: #007700">())<br />            : </span><span style="color: #0000BB">strtolower</span><span style="color: #007700">(</span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">$val</span><span style="color: #007700">::</span><span style="color: #0000BB">get</span><span style="color: #007700">());<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
  </div>
 </div>
 <div class="sect2">
  <h3 class="title">Sérialisation</h3>
  <p class="simpara">
   PHP a plusieurs façons différentes de sérialiser un objet,
   que ce soit pour la consommation publique ou à des fins de débogage.
   Le comportement des hooks varie en fonction de l&#039;utilisation.
   Dans certains cas, la valeur de sauvegarde brute d&#039;une propriété sera utilisée,
   contournant tout hook.
   Dans d&#039;autres, la propriété sera lue ou écrite &quot;à travers&quot; le hook,
   comme toute autre action de lecture/écriture normale.
  </p>
  <ul class="simplelist">
   <li><span class="function"><a href="function.var-dump.php" class="function">var_dump()</a></span>: Utilise la valeur brute</li>
   <li><span class="function"><a href="function.serialize.php" class="function">serialize()</a></span>: Utilise la valeur brute</li>
   <li><span class="function"><a href="function.unserialize.php" class="function">unserialize()</a></span>: Utilise la valeur brute</li>
   <li><a href="language.oop5.magic.php#object.serialize" class="link">__serialize()</a>/<a href="language.oop5.magic.php#object.unserialize" class="link">__unserialize()</a>: Logique propre, utilise les hooks get/set</li>
   <li>Conversion en tableau : Utilise la valeur brute</li>
   <li><span class="function"><a href="function.var-export.php" class="function">var_export()</a></span>: Utilise le hook get</li>
   <li><span class="function"><a href="function.json-encode.php" class="function">json_encode()</a></span>: Utilise le hook get</li>
   <li><span class="interfacename"><a href="class.jsonserializable.php" class="interfacename">JsonSerializable</a></span>: Logique propre, utilise le hook get</li>
   <li><span class="function"><a href="function.get-object-vars.php" class="function">get_object_vars()</a></span>: Utilise le hook get</li>
   <li><span class="function"><a href="function.get-mangled-object-vars.php" class="function">get_mangled_object_vars()</a></span>: Utilise la valeur brute</li>
  </ul>
 </div>
</div><?php manual_footer($setup); ?>