<?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 => 'pt_BR',
  ),
  'this' => 
  array (
    0 => 'language.oop5.property-hooks.php',
    1 => 'Ganchos de Propriedade',
    2 => 'Ganchos de Propriedade',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Classes e Objetos',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.properties.php',
    1 => 'Propriedades',
  ),
  'next' => 
  array (
    0 => 'language.oop5.constants.php',
    1 => 'Constantes de Classe',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'pt_BR',
    '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">Ganchos de Propriedade</h2>

 <p class="simpara">
  Ganchos de propriedade, também conhecidos como &quot;acessadores de propriedade&quot; em algumas outras linguagens,
  são uma forma de interceptar e substituir o comportamento de leitura e gravação de uma propriedade.
  Esta funcionalidade tem dois propósitos:
 </p>
 <ol type="1">
  <li class="listitem">
   <span class="simpara">
    Permite que as propriedades sejam usadas diretamente, sem os métodos &#039;get&#039; e &#039;set&#039;,
    deixando aberta a opção de incluir comportamento adicional no futuro.
    Isso torna desnecessários a maioria dos métodos &#039;get&#039;/&#039;set&#039; padronizados,
    mesmo sem usar ganchos.
   </span>
  </li>
  <li class="listitem">
   <span class="simpara">
    Permite propriedades que descrevem um objeto sem a necessidade de armazenar
    um valor diretamente.
   </span>
  </li>
 </ol>
 <p class="simpara">
  Existem dois ganchos disponíveis em propriedades não estáticas: <code class="literal">get</code> e <code class="literal">set</code>.
  Eles permitem substituir o comportamento de leitura e gravação de uma propriedade, respectivamente.
  Os ganchos estão disponíveis para propriedades tipadas e não tipadas.
 </p>
 <p class="simpara">
  Uma propriedade pode ser &quot;apoiada&quot; ou &quot;virtual&quot;.
  Uma propriedade apoiada é aquela que realmente armazena um valor.
  Qualquer propriedade que não tenha ganchos será apoiada.
  Uma propriedade virtual é aquela que possui ganchos e esses ganchos não interagem com a propriedade em si.
  Nesse caso, os ganchos são efetivamente iguais aos métodos,
  e o objeto não usa nenhum espaço para armazenar um valor para aquela propriedade.
 </p>
 <p class="simpara">
  Ganchos de propriedade são incompatíveis com propriedades <code class="literal">readonly</code> (somente-leitura).
  Se houver necessidade de restringir acesso a uma operação <code class="literal">get</code> ou <code class="literal">set</code>
  além de alterar seu comportamento, deve ser usada a
  <a href="language.oop5.visibility.php#language.oop5.visibility-members-aviz" class="link">visibilidade de propriedade assimétrica</a>.
 </p>

 <blockquote class="note"><p><strong class="note">Nota</strong>: 
  <strong>Informação de Versão</strong><br />
  <span class="simpara">
   Ganchos de Propriedade foram introduzidos no PHP 8.4.
  </span>
 </p></blockquote>

 <div class="sect2">
  <h3 class="title">Sintaxe Básica de Gancho</h3>
  <p class="simpara">
   A sintaxe geral para declarar um gancho é a seguinte.
  </p>
  <div class="example" id="example-1">
   <p><strong>Exemplo #1 Ganchos de propriedade (versão completa)</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">
   A propriedade <var class="varname">$foo</var> termina com <code class="literal">{}</code>, em vez de ponto e vírgula.
   Isso indica a presença de ganchos.
   Ambos os ganchos <code class="literal">get</code> e <code class="literal">set</code> são definidos,
   embora seja permitido definir apenas um ou outro.
   Ambos os ganchos possuem um corpo, indicado por <code class="literal">{}</code>, que pode conter código arbitrário.
  </p>
  <p class="simpara">
   O gancho <code class="literal">set</code> permite adicionalmente especificar o tipo e o nome de um valor recebido,
   usando a mesma sintaxe de um método.
   O tipo deve ser igual ao tipo da propriedade
   ou uma <a href="language.oop5.variance.php#language.oop5.variance.contravariance" class="link">contravariante</a> (mais amplo) a ela.
   Por exemplo, uma propriedade do tipo <span class="type"><a href="language.types.string.php" class="type string">string</a></span> poderia ter um
   gancho <code class="literal">set</code> que aceita <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>,
   mas não aquele que aceita apenas <span class="type"><a href="language.types.array.php" class="type array">array</a></span>.
  </p>
  <p class="simpara">
   Pelo menos um dos ganchos faz referência a <code class="code">$this-&gt;foo</code>, a própria propriedade.
   Isso significa que a propriedade será &quot;apoiada&quot;.
   Ao chamar <code class="code">$example-&gt;foo = &#039;changed&#039;</code>,
   a string fornecida será primeiro convertida em minúsculas e depois salva no valor de apoio.
   Ao ler a propriedade, o valor salvo anteriormente pode ser anexado condicionalmente
   com texto adicional.
  </p>
  <p class="simpara">
   Existem também várias variantes de sintaxe abreviada para lidar com casos comuns.
  </p>
  <p class="simpara">
   Se o gancho <code class="literal">get</code> for uma expressão única,
   <code class="literal">{}</code> poderá ser omitido e substituído por uma expressão de seta.
  </p>
  <div class="example" id="example-2">
   <p><strong>Exemplo #2 Expressão para leitura de propriedade</strong></p>
   <div class="example-contents"><p>
    Este exemplo é equivalente ao anterior.
   </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">
   Se o tipo de parâmetro do gancho <code class="literal">set</code> for igual ao tipo de propriedade (o que é típico),
   ele poderá ser omitido.  Nesse caso, o valor a ser definido recebe automaticamente o nome <var class="varname">$value</var>.
  </p>
  <div class="example" id="example-3">
   <p><strong>Exemplo #3 Padrão de definição de propriedade</strong></p>
   <div class="example-contents"><p>
    Este exemplo é equivalente ao anterior.
   </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">
   Se o gancho <code class="literal">set</code> estiver apenas definindo uma versão modificada do valor passado,
   então ele também poderá ser simplificado para uma expressão de seta.
   O valor avaliado pela expressão será definido no valor de apoio.
  </p>
  <div class="example" id="example-4">
   <p><strong>Exemplo #4 Expressão para definição de propriedade</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">
   Este exemplo não é exatamente equivalente ao anterior,
   pois também não modifica <code class="code">$this-&gt;modified</code>.
   Se várias instruções forem necessárias no corpo do gancho definido, use a versão entre chaves.
  </p>
  <p class="simpara">
   Uma propriedade pode implementar zero, um ou ambos os ganchos conforme a situação exigir.
   Todas as versões abreviadas são mutuamente independentes.
   Ou seja, usar um &#039;get&#039; curto com um &#039;set&#039; longo,
   ou um &#039;set&#039; curto com um tipo explícito, ou assim por diante, é válido.
  </p>
  <p class="simpara">
   Em uma propriedade apoiada, omitir um gancho <code class="literal">get</code> ou <code class="literal">set</code>
   significa que o comportamento padrão de leitura ou gravação será usado.
  </p>
  <blockquote class="note"><p><strong class="note">Nota</strong>: 
   <span class="simpara">
    Ganchos podem ser definidos ao usar
    <a href="language.oop5.decon.php#language.oop5.decon.constructor.promotion" class="link">promoção de propriedade de construtor</a>.
    No entanto, quando isso é feito, os valores fornecidos
    ao construtor precisam ter o tipo associado à propriedade correspondido,
    independentemente do que o gancho <code class="literal">set</code> possa permitir.
   </span>
   <span class="simpara">
    Considere o seguinte:
   </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">
    Internamente, o mecanismo decompõe para o seguinte:
   </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">
    Quaisquer tentativas de definir a propriedade fora do construtor
    permitirão valores do tipo <span class="type"><a href="language.types.string.php" class="type string">string</a></span> ou <span class="interfacename"><a href="class.datetimeinterface.php" class="interfacename">DateTimeInterface</a></span>
    mas o construtor permitirá apenas <span class="interfacename"><a href="class.datetimeinterface.php" class="interfacename">DateTimeInterface</a></span>.
    Isto acontece porque o tipo definido para a propriedade (<span class="interfacename"><a href="class.datetimeinterface.php" class="interfacename">DateTimeInterface</a></span>)
    é usado como o tipo do parâmetro dentro da assinatura do construtor, não importando o que
    o gancho <code class="literal">set</code> permite.
   </span>
   <span class="simpara">
    Se este tipo de comportamento do construtor for necessário, a promoção de
    propriedade no construtor não pode ser usada.
   </span>
  </p></blockquote>
 </div>
 <div class="sect2" id="language.oop5.property-hooks.virtual">
  <h3 class="title">Propriedades virtuais</h3>
  <p class="simpara">
   Propriedades virtuais são propriedades que não possuem valor de apoio.
   Uma propriedade é virtual se nem seu gancho <code class="literal">get</code>
   nem seu gancho <code class="literal">set</code> fizerem referência à própria propriedade usando sintaxe exata.
   Ou seja, uma propriedade chamada <code class="code">$foo</code> cujo gancho contém <code class="code">$this-&gt;foo</code> será apoiada.
   Mas a seguinte não é uma propriedade apoiada e causará erro:
  </p>
  <div class="example" id="example-5">
   <p><strong>Exemplo #5 Propriedade virtual inválida</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">// Não faz referência a $this-&gt;foo, por isso não é válida.<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 propriedades virtuais, se um gancho for omitido, essa operação
   não existe e tentar usá-la produzirá um erro.
   As propriedades virtuais não ocupam espaço de memória em um objeto.
   As propriedades virtuais são adequadas para propriedades &quot;derivadas&quot;,
   como aquelas que são a combinação de duas outras propriedades.
  </p>
  <div class="example" id="example-6">
   <p><strong>Exemplo #6 Propriedade virtual</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">// Uma propriedade 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">// exibe 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">// Erro, pois não há operação 'set' definida.<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
  <p class="simpara">
   Definir ambos os ganchos <code class="literal">get</code> e <code class="literal">set</code> em uma propriedade virtual também é permitido.
  </p>
 </div>
 <div class="sect2">
  <h3 class="title">Escopo</h3>
  <p class="simpara">
   Todos os ganchos operam no escopo do objeto que está sendo modificado.
   Isso significa que eles têm acesso a todos os métodos públicos, privados ou protegidos do objeto,
   bem como a quaisquer propriedades públicas, privadas ou protegidas,
   incluindo propriedades que possam ter seus próprios ganchos de propriedade.
   Acessar outra propriedade de dentro de um gancho não ignora os ganchos definidos nesta propriedade.
  </p>
  <p class="simpara">
   A implicação mais notável disso é que ganchos não triviais podem fazer subchamadas
   a um método arbitrariamente complexo, se desejarem.
  </p>
  <div class="example" id="example-7">
   <p><strong>Exemplo #7 Chamando um método a partir de um gancho</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">Referências</h3>
  <p class="simpara">
   Como a presença de ganchos intercepta o processo de leitura e gravação de propriedades,
   eles causam problemas ao adquirir uma referência a uma propriedade ou com modificação
   indireta, como <code class="code">$this-&gt;arrayProp[&#039;chave&#039;] = &#039;valor&#039;;</code>.
   Isso ocorre porque qualquer tentativa de modificação do valor por referência ignoraria um gancho &#039;set&#039;,
   se algum estiver definido.
  </p>
  <p class="simpara">
   No caso raro de ser necessário obter uma referência a uma propriedade que tenha ganchos definidos,
   o gancho <code class="literal">get</code> pode ser prefixado com <code class="literal">&amp;</code>
   para fazer com que ele retorne por referência.
   Definir <code class="literal">get</code> e <code class="literal">&amp;get</code> na
   mesma propriedade é um erro de sintaxe.
  </p>
  <p class="simpara">
   Não é permitido definir ganchos <code class="literal">&amp;get</code> e <code class="literal">set</code> em uma propriedade apoiada.
   Conforme observado acima, escrever no valor retornado por referência ignoraria o gancho <code class="literal">set</code>.
   Nas propriedades virtuais, não há nenhum valor comum necessário compartilhado entre os dois ganchos, portanto, é permitido definir ambos.
  </p>
  <p class="simpara">
   Escrever em um índice de uma propriedade de array também envolve uma referência implícita.
   Por esse motivo, gravar em uma propriedade de array apoiada com ganchos definidos é
   permitido se e somente se ela definir apenas um gancho <code class="literal">&amp;get</code>.
   Em uma propriedade virtual, escrever no array retornado de
   <code class="literal">get</code> ou <code class="literal">&amp;get</code> é legal,
   mas se isso terá algum impacto no objeto depende da implementação do gancho.
  </p>
  <p class="simpara">
   Substituir toda a propriedade do array é aceitável e se comporta da mesma forma que qualquer outra propriedade.
   Trabalhar apenas com elementos do array requer cuidados especiais.
  </p>
 </div>
 <div class="sect2">
  <h3 class="title">Herança</h3>
  <div class="sect3">
   <h4 class="title">Ganchos finais</h4>
   <p class="simpara">
    Um gancho pode também ser declarado como <a href="language.oop5.final.php" class="link">final</a>,
    neste caso ele não pode ser substituído.
   </p>
   <div class="example" id="example-8">
    <p><strong>Exemplo #8 Ganchos finais</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">User<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">string $username </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">User<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">string $username </span><span style="color: #007700">{<br />        </span><span style="color: #FF8000">// Isto é 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">username</span><span style="color: #007700">);<br /><br />        </span><span style="color: #FF8000">// Mas isto NÃO é permitido, porque 'set' é final na classe superior.<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">
    Uma propriedade também pode ser declarada como <a href="language.oop5.final.php" class="link">final</a>.
    Uma propriedade final não pode ser declarada novamente por uma classe filha de forma alguma,
    o que impede a alteração de ganchos ou a ampliação de seu acesso.
   </p>
   <p class="simpara">
    Declarar ganchos como finais em uma propriedade declarada como final é redundante
    e será silenciosamente ignorado.
    Este é o mesmo comportamento dos métodos finais.
   </p>
   <p class="simpara">
    Uma classe filha pode definir ou redefinir ganchos individuais em uma propriedade
    redefinindo a propriedade e apenas os ganchos que deseja substituir.
    Uma classe filha também pode adicionar ganchos a uma propriedade que não possui nenhum.
    Isto é, essencialmente, como se os ganchos fossem métodos.
   </p>
   <div class="example" id="example-9">
    <p><strong>Exemplo #9 Herança de gancho</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">'Muito pequeno'</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 gancho substitui as implementações pai independentemente umas das outras.
    Se uma classe filha adicionar ganchos, qualquer valor padrão definido na propriedade será removido e deverá ser declarado novamente.
    Isso é consistente com o modo como a herança funciona em propriedades sem gancho.
   </p>
  </div>
  <div class="sect3">
   <h4 class="title">Acessando ganchos pais</h4>
   <p class="simpara">
    Um gancho em uma classe filha pode acessar a propriedade da classe pai usando a
    palavra-chave <code class="code">parent::$prop</code>, seguida pelo gancho desejado.
    Por exemplo, <code class="code">parent::$propName::get()</code>.
    Pode ser lido como &quot;acessar a <var class="varname">prop</var> definida na classe pai
    e então executar sua operação &#039;get&#039;&quot; (ou operação &#039;set&#039;, conforme apropriado).
   </p>
   <p class="simpara">
    Se não for acessado dessa forma, o gancho da classe pai será ignorado.
    Esse comportamento é consistente com o funcionamento de todos os métodos.
    Isso também oferece uma maneira de acessar o armazenamento da classe pai, se houver.
    Se não houver gancho na propriedade pai,
    seu comportamento &#039;get&#039;/&#039;set&#039; padrão será usado.
    Os ganchos não podem acessar nenhum outro gancho, exceto seu próprio pai em sua própria propriedade.
   </p>
   <p class="simpara">
    O exemplo acima poderia ser reescrito da seguinte maneira, que permitiria que
    a classe <code class="literal">Point</code> adicionasse seu próprio grancho <code class="literal">set</code>
    no futuro sem problemas (no exemplo anterior, um gancho adicionado à
    classe pai seria ignorado na classe filha).
   </p>
   <div class="example" id="example-10">
    <p><strong>Exemplo #10 Acessando gancho pai (&#039;set&#039;)</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">'Muito pequeno'</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">
    Um exemplo de substituição apenas de um gancho &#039;get&#039; poderia ser:
   </p>
   <div class="example" id="example-11">
    <p><strong>Exemplo #11 Acessando gancho pai (&#039;get&#039;)</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">Serialização</h3>
  <p class="simpara">
   O PHP possui diversas maneiras diferentes pelas quais um objeto pode ser serializado,
   seja para consumo público ou para fins de depuração.
   O comportamento dos ganchos varia dependendo do caso de uso.
   Em alguns casos, o valor bruto de apoio de uma propriedade será usado,
   ignorando quaisquer ganchos.
   Em outros, a propriedade será lida ou escrita &quot;através&quot; do gancho,
   assim como qualquer outra ação normal de leitura/gravação.
  </p>
  <ul class="simplelist">
   <li><span class="function"><a href="function.var-dump.php" class="function">var_dump()</a></span>: Usa valor bruto</li>
   <li><span class="function"><a href="function.serialize.php" class="function">serialize()</a></span>: Usa valor bruto</li>
   <li><span class="function"><a href="function.unserialize.php" class="function">unserialize()</a></span>: Usa 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 customizada, usa gancho 'get'/'set'</li>
   <li>Conversão de array: Usa valor bruto</li>
   <li><span class="function"><a href="function.var-export.php" class="function">var_export()</a></span>: Usa gancho 'get'</li>
   <li><span class="function"><a href="function.json-encode.php" class="function">json_encode()</a></span>: Usa gancho 'get'</li>
   <li><span class="interfacename"><a href="class.jsonserializable.php" class="interfacename">JsonSerializable</a></span>: Lógica customizada, usa gancho 'get'</li>
   <li><span class="function"><a href="function.get-object-vars.php" class="function">get_object_vars()</a></span>: Usa gancho 'get'</li>
   <li><span class="function"><a href="function.get-mangled-object-vars.php" class="function">get_mangled_object_vars()</a></span>: Usa valor bruto</li>
  </ul>
 </div>
</div><?php manual_footer($setup); ?>