<?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 => 'es',
  ),
  'this' => 
  array (
    0 => 'language.oop5.property-hooks.php',
    1 => 'Hooks de propiedad',
    2 => 'Hooks de propiedad',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Clases y objetos',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.properties.php',
    1 => 'Propiedades',
  ),
  'next' => 
  array (
    0 => 'language.oop5.constants.php',
    1 => 'Constantes de clase',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'es',
    '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 propiedad</h2>

 <p class="simpara">
  Los hooks de propiedad, también conocidos como &quot;métodos de acceso de propiedad&quot; en otros lenguajes,
  son una forma de interceptar y reemplazar el comportamiento de lectura y escritura de una propiedad.
  Esta funcionalidad sirve a dos fines:
 </p>
 <ol type="1">
  <li class="listitem">
   <span class="simpara">
    Permite utilizar propiedades directamente, sin necesidad de métodos get y set,
    dejando la posibilidad de añadir un comportamiento adicional en el futuro.
    Esto hace que la mayoría de los métodos get/set sean innecesarios,
    incluso sin usar hooks.
   </span>
  </li>
  <li class="listitem">
   <span class="simpara">
    Permite definir propiedades que describen un objeto sin almacenar
    directamente un valor.
   </span>
  </li>
 </ol>
 <p class="simpara">
  Existen dos hooks disponibles en las propiedades no estáticas: <code class="literal">get</code> y <code class="literal">set</code>.
  Permiten reemplazar el comportamiento de lectura y escritura de una propiedad, respectivamente.
  Los hooks están disponibles para propiedades tipadas y no tipadas.
 </p>
 <p class="simpara">
  Un objeto puede ser &quot;backed&quot; o &quot;virtual&quot;.
  Una propiedad &quot;backed&quot; es una propiedad que almacena efectivamente un valor.
  Cualquier propiedad que no tenga hooks es &quot;backed&quot;.
  Una propiedad virtual es una propiedad que tiene hooks y estos hooks no interactúan con la propiedad misma.
  En este caso, los hooks son efectivamente los mismos que los métodos,
  y el objeto no utiliza espacio para almacenar un valor para esta propiedad.
 </p>
 <p class="simpara">
  Los hooks de propiedad son incompatibles con las propiedades <code class="literal">readonly</code>.
  Si es necesario restringir el acceso a una operación <code class="literal">get</code> o <code class="literal">set</code>
  además de modificar su comportamiento, utilice
  <a href="language.oop5.visibility.php#language.oop5.visibility-members-aviz" class="link">la visibilidad asimétrica de propiedad</a>.
 </p>

 <blockquote class="note"><p><strong class="note">Nota</strong>: 
  <strong>Información de versión</strong><br />
  <span class="simpara">
   Los hooks de propiedad fueron introducidos en PHP 8.4.
  </span>
 </p></blockquote>

 <div class="sect2">
  <h3 class="title">Sintaxis básica de los hooks</h3>
  <p class="simpara">
   La sintaxis general para declarar un hook es la siguiente.
  </p>
  <div class="example" id="example-1">
   <p><strong>Ejemplo #1 Hooks de propiedad (versión completa)</strong></p>
   <div class="example-contents">
<div class="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">'valor por omisión' </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">' (modificado)'</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">'cambiado'</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 propiedad <var class="varname">$foo</var> termina con <code class="literal">{}</code>, en lugar de un punto y coma.
   Esto indica la presencia de hooks.
   Se definen un hook <code class="literal">get</code> y un hook <code class="literal">set</code>,
   aunque es posible definir solo uno.
   Ambos hooks tienen un cuerpo, indicado por <code class="literal">{}</code>, que puede contener código arbitrario.
  </p>
  <p class="simpara">
   El hook <code class="literal">set</code> también permite especificar el tipo y el nombre de un valor entrante,
   utilizando la misma sintaxis que una método.
   El tipo debe ser el mismo que el tipo de la propiedad,
   o <a href="language.oop5.variance.php#language.oop5.variance.contravariance" class="link">contravariante</a> (más amplio) que este.
   Por ejemplo, una propiedad de tipo <span class="type"><a href="language.types.string.php" class="type string">string</a></span> podría tener
   un hook <code class="literal">set</code> que acepte 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>,
   pero no uno que acepte solo <span class="type"><a href="language.types.array.php" class="type array">array</a></span>.
  </p>
  <p class="simpara">
   Al menos uno de los hooks hace referencia a <code class="code">$this-&gt;foo</code>, la propiedad misma.
   Esto significa que la propiedad será &quot;backed&quot;.
   Cuando se llama a <code class="code">$example-&gt;foo = &#039;cambiado&#039;</code>,
   la cadena proporcionada se convertirá primero en minúsculas y luego se guardará en el valor de respaldo.
   Al leer la propiedad, el valor previamente guardado puede ser condicionalmente complementado
   con texto adicional.
  </p>
  <p class="simpara">
   Hay varias variantes de sintaxis abreviada para manejar los casos comunes.
  </p>
  <p class="simpara">
   Si el hook <code class="literal">get</code> es una simple expresión,
   entonces los <code class="literal">{}</code> pueden ser omitidos y reemplazados por una expresión flecha.
  </p>
  <div class="example" id="example-2">
   <p><strong>Ejemplo #2 Expresión de propiedad get</strong></p>
   <div class="example-contents"><p>
    Este ejemplo es equivalente al ejemplo anterior.
   </p></div>
   <div class="example-contents">
<div class="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">'valor por omisión' </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">' (modificado)' </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 el tipo del parámetro del hook <code class="literal">set</code> es el mismo que el tipo de la propiedad (lo cual es típico),
   puede ser omitido. En este caso, el valor a definir se nombra automáticamente <var class="varname">$value</var>.
  </p>
  <div class="example" id="example-3">
   <p><strong>Ejemplo #3 Parámetros por omisión de propiedad</strong></p>
   <div class="example-contents"><p>
    Este ejemplo es equivalente al ejemplo anterior.
   </p></div>
   <div class="example-contents">
<div class="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">'valor por omisión' </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">' (modificado)' </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 el hook <code class="literal">set</code> solo define una versión modificada del valor pasado,
   también puede simplificarse en una expresión flecha.
   El valor al que se evalúa la expresión se definirá en el valor de respaldo.
  </p>
  <div class="example" id="example-4">
   <p><strong>Ejemplo #4 Expresión de propiedad set</strong></p>
   <div class="example-contents">
<div class="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">'valor por omisión' </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">' (modificado)' </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">
   Este ejemplo no es completamente equivalente al anterior,
   ya que tampoco modifica <code class="code">$this-&gt;modified</code>.
   Si se necesitan múltiples instrucciones en el cuerpo del hook, utilice la versión con llaves.
  </p>
  <p class="simpara">
   Una propiedad puede implementar cero, uno o ambos hooks según la situación.
   Todas las versiones abreviadas son mutuamente independientes.
   Es decir, utilizar un atajo para obtener una definición larga,
   o un atajo para definir un tipo explícito, etc., es válido.
  </p>
  <p class="simpara">
   En una propiedad &quot;backed&quot;, omitir un hook <code class="literal">get</code> o <code class="literal">set</code>
   significa que se utilizará el comportamiento de lectura o escritura por omisión.
  </p>
  <blockquote class="note"><p><strong class="note">Nota</strong>: 
   <span class="simpara">
    Los hooks pueden ser definidos al utilizar la
    <a href="language.oop5.decon.php#language.oop5.decon.constructor.promotion" class="link">promoción de propiedades en el constructor</a>.
    Sin embargo, en este caso, los valores proporcionados
    al constructor deben coincidir con el tipo asociado a la propiedad,
    independientemente de lo que el hook <code class="literal">set</code> podría permitir.
   </span>
   <span class="simpara">
    Considere el siguiente ejemplo:
   </span>
   <div class="example-contents">
<div class="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">
    Internamente, el motor descompone esto de la siguiente manera:
   </span>
   <div class="example-contents">
<div class="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">
    Cualquier intento de definir la propiedad fuera del constructor
    permitirá un <span class="type"><a href="language.types.string.php" class="type string">string</a></span> o un valor de tipo <span class="interfacename"><a href="class.datetimeinterface.php" class="interfacename">DateTimeInterface</a></span>,
    pero el constructor solo permitirá <span class="interfacename"><a href="class.datetimeinterface.php" class="interfacename">DateTimeInterface</a></span>.
    Esto se debe a que el tipo definido para la propiedad (<span class="interfacename"><a href="class.datetimeinterface.php" class="interfacename">DateTimeInterface</a></span>)
    se utiliza como tipo de parámetro en la firma del constructor, independientemente de lo que
    el hook <code class="literal">set</code> permita.
   </span>
   <span class="simpara">
    Si este tipo de comportamiento es necesario desde el constructor, la promoción
    de propiedades en el constructor no puede ser utilizada.
   </span>
</p></blockquote>
 </div>
 <div class="sect2" id="language.oop5.property-hooks.virtual">
  <h3 class="title">Propiedades virtuales</h3>
  <p class="simpara">
   Las propiedades virtuales son propiedades que no tienen un valor de respaldo.
   Una propiedad es virtual si ni su hook <code class="literal">get</code> ni su hook <code class="literal">set</code>
   hace referencia a la propiedad misma utilizando una sintaxis exacta.
   Es decir, una propiedad nombrada <code class="code">$foo</code> cuyo hook contiene <code class="code">$this-&gt;foo</code> será respaldada.
   Pero la siguiente propiedad no es una propiedad respaldada, y generará un error:
  </p>
  <div class="example" id="example-5">
   <p><strong>Ejemplo #5 Propiedad virtual inválida</strong></p>
   <div class="example-contents">
<div class="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">// No se refiere a $this-&gt;foo, por lo que no cuenta.<br />        </span><span style="color: #007700">}<br />    }<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
  <p class="simpara">
   Para las propiedades virtuales, si se omite un hook, entonces esa operación
   no existe y tratar de utilizarla producirá un error.
   Las propiedades virtuales no ocupan espacio de memoria en un objeto.
   Las propiedades virtuales son adecuadas para las propiedades &quot;derivadas&quot;,
   tales como las que son la combinación de dos otras propiedades.
  </p>
  <div class="example" id="example-6">
   <p><strong>Ejemplo #6 Propiedad virtual</strong></p>
   <div class="example-contents">
<div class="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">// Una propiedad virtual.<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">// muestra 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">// Error, ya que no hay operación de definición.<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
  <p class="simpara">
   Definir tanto un hook <code class="literal">get</code> como un hook <code class="literal">set</code> en una propiedad virtual también está permitido.
  </p>
 </div>
 <div class="sect2">
  <h3 class="title">Alcance</h3>
  <p class="simpara">
   Todos los hooks funcionan en el alcance del objeto modificado.
   Esto significa que tienen acceso a todos los métodos públicos, privados o protegidos del objeto,
   así como a todas las propiedades públicas, privadas o protegidas,
   incluyendo las propiedades que pueden tener sus propios hooks de propiedad.
   Acceder a otra propiedad desde un hook no elude los hooks definidos en esa propiedad.
  </p>
  <p class="simpara">
   La consecuencia más notable de esto es que los hooks no triviales pueden
   llamar a un método arbitrariamente complejo si lo desean.
  </p>
  <div class="example" id="example-7">
   <p><strong>Ejemplo #7 Llamada a un método desde un hook</strong></p>
   <div class="example-contents">
<div class="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">Referencias</h3>
  <p class="simpara">
   Debido a que la presencia de hooks intercepta el proceso de lectura y escritura de las propiedades,
   plantean problemas al adquirir una referencia a una propiedad o con una modificación indirecta,
   tal como <code class="code">$this-&gt;arrayProp[&#039;key&#039;] = &#039;value&#039;;</code>.
   Esto se debe a que cualquier intento de modificar el valor por referencia eludiría un hook de definición
   si existiera uno.
  </p>
  <p class="simpara">
   En el caso raro en que sea necesario obtener una referencia a una propiedad para la cual se definen hooks,
   el hook <code class="literal">get</code> puede ser prefijado por <code class="literal">&amp;</code>
   para que devuelva por referencia.
   Definir tanto <code class="literal">get</code> como <code class="literal">&amp;get</code> en la
   misma propiedad es un error de sintaxis.
  </p>
  <p class="simpara">
   Definir tanto los hooks <code class="literal">&amp;get</code> como <code class="literal">set</code> en una propiedad &quot;backed&quot; no está permitido.
   Como se indicó anteriormente, escribir en el valor devuelto por referencia eludiría el hook <code class="literal">set</code>.
   En las propiedades virtuales, no hay un valor común necesario compartido entre los dos hooks, por lo que definir ambos está permitido.
  </p>
  <p class="simpara">
   Escribir en un índice de una propiedad de array implica también una referencia implícita.
   Por esta razón, escribir en una propiedad de array &quot;backed&quot; con hooks definidos está permitido si y solo si
   define solo un hook <code class="literal">&amp;get</code>.
   En una propiedad virtual, escribir en el array devuelto por
   <code class="literal">get</code> o <code class="literal">&amp;get</code> es legal,
   pero si esto tiene un impacto en el objeto depende de la implementación del hook.
  </p>
  <p class="simpara">
   Sobrecargar la propiedad de array completa está permitido, y se comporta de la misma manera que cualquier otra propiedad.
   Trabajar solo con elementos del array requiere atención especial.
  </p>
 </div>
 <div class="sect2">
  <h3 class="title">Herencia</h3>
  <div class="sect3">
   <h4 class="title">Hooks finales</h4>
   <p class="simpara">
    Los hooks también pueden ser declarados <a href="language.oop5.final.php" class="link">final</a>,
    en cuyo caso no pueden ser reemplazados.
   </p>
   <div class="example" id="example-8">
   <p><strong>Ejemplo #8 Hooks finales</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Utiliser<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">string $Utilisername </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">Manager </span><span style="color: #007700">extends </span><span style="color: #0000BB">Utiliser<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">string $Utilisername </span><span style="color: #007700">{<br />        </span><span style="color: #FF8000">// Esto está permitido<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">Utilisername</span><span style="color: #007700">);<br /><br />        </span><span style="color: #FF8000">// Esto NO está permitido, ya que set es final en el padre.<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">
    Una propiedad también puede ser declarada <a href="language.oop5.final.php" class="link">final</a>.
    Una propiedad final no puede ser redeclarada por una clase hija de ninguna manera,
    lo que excluye la modificación de los hooks o la ampliación de su acceso.
   </p>
   <p class="simpara">
    Declarar hooks finales en una propiedad que es declarada final es redundante,
    y será silenciosamente ignorado.
    Es el mismo comportamiento que para los métodos finales.
   </p>
   <p class="simpara">
    Una clase hija puede declarar o cambiar hooks individuales en una propiedad
    redefiniendo la propiedad y solo los hooks que desea reemplazar.
    Una clase hija también puede añadir hooks a una propiedad que no los tenía.
    Esto es esencialmente lo mismo que si los hooks fueran métodos.
   </p>
   <div class="example" id="example-9">
    <p><strong>Ejemplo #9 Herencia de hook</strong></p>
    <div class="example-contents">
<div class="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">
    Cada hook reemplaza las implementaciones parentales de manera independiente.
    Si una clase hija añade hooks, cualquier valor por omisión definido en la propiedad es eliminado, y debe ser redeclarado.
    Es la misma coherencia con el funcionamiento de la herencia en las propiedades sin hooks.
   </p>
  </div>
  <div class="sect3">
   <h4 class="title">Acceso a los hooks parentales</h4>
   <p class="simpara">
    Un hook en una clase hija puede acceder a la propiedad de la clase padre utilizando la palabra clave
    <code class="code">parent::$prop</code>, seguida del hook deseado.
    Por ejemplo, <code class="code">parent::$propName::get()</code>.
    Esto puede ser leído como &quot;acceder a la <var class="varname">prop</var> definida en la clase padre,
    luego ejecutar su operación get&quot; (o set, según el caso).
   </p>
   <p class="simpara">
    Si no se accede de esta manera, el hook de la clase padre es ignorado.
    Este comportamiento es coherente con el funcionamiento de todos los métodos.
    Esto también proporciona una manera de acceder al almacenamiento de la clase padre, si es necesario.
    Si no hay un hook en la propiedad padre,
    su comportamiento por omisión get/set será utilizado.
    Los hooks no pueden acceder a otro hook que no sea su propio padre en su propia propiedad.
   </p>
   <p class="simpara">
    El ejemplo anterior podría ser reescrito de la siguiente manera, lo que permitiría a la
    clase <code class="literal">Point</code> añadir su propio hook <code class="literal">set</code>
    en el futuro sin problemas (en el ejemplo anterior, un hook añadido a la
    clase padre sería ignorado en la clase hija).
   </p>
   <div class="example" id="example-10">
    <p><strong>Ejemplo #10 Acceso a los hooks parentales (set)</strong></p>
    <div class="example-contents">
<div class="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 ejemplo de reemplazo de solo un hook get podría ser:
   </p>
   <div class="example" id="example-11">
    <p><strong>Ejemplo #11 Acceso a los hooks parentales (get)</strong></p>
    <div class="example-contents">
<div class="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">Serialización</h3>
  <p class="simpara">
   PHP tiene varias formas diferentes de serializar un objeto,
   ya sea para consumo público o para fines de depuración.
   El comportamiento de los hooks varía según el uso.
   En algunos casos, el valor bruto de respaldo de una propiedad será utilizado,
   eludiendo cualquier hook.
   En otros, la propiedad será leída o escrita &quot;a través&quot; del hook,
   como cualquier otra acción de lectura/escritura normal.
  </p>
  <ul class="simplelist">
   <li><span class="function"><a href="function.var-dump.php" class="function">var_dump()</a></span>: Utiliza el valor bruto</li>
   <li><span class="function"><a href="function.serialize.php" class="function">serialize()</a></span>: Utiliza el valor bruto</li>
   <li><span class="function"><a href="function.unserialize.php" class="function">unserialize()</a></span>: Utiliza el valor bruto</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>: Lógica propia, utiliza los hooks de recuperación/definición</li>
   <li>Array casting: Utiliza el valor bruto</li>
   <li><span class="function"><a href="function.var-export.php" class="function">var_export()</a></span>: Utiliza el hook de recuperación</li>
   <li><span class="function"><a href="function.json-encode.php" class="function">json_encode()</a></span>: Utiliza el hook de recuperación</li>
   <li><span class="interfacename"><a href="class.jsonserializable.php" class="interfacename">JsonSerializable</a></span>: Lógica propia, utiliza el hook de recuperación</li>
   <li><span class="function"><a href="function.get-object-vars.php" class="function">get_object_vars()</a></span>: Utiliza el hook de recuperación</li>
   <li><span class="function"><a href="function.get-mangled-object-vars.php" class="function">get_mangled_object_vars()</a></span>: Utiliza el valor bruto</li>
  </ul>
 </div>
</div><?php manual_footer($setup); ?>