<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.enumerations.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'pt_BR',
  ),
  'this' => 
  array (
    0 => 'language.enumerations.backed.php',
    1 => 'Enumera&ccedil;&otilde;es Apoiadas',
    2 => 'Enumera&ccedil;&otilde;es Apoiadas',
  ),
  'up' => 
  array (
    0 => 'language.enumerations.php',
    1 => 'Enumera&ccedil;&otilde;es',
  ),
  'prev' => 
  array (
    0 => 'language.enumerations.basics.php',
    1 => 'Enumera&ccedil;&otilde;es B&aacute;sicas',
  ),
  'next' => 
  array (
    0 => 'language.enumerations.methods.php',
    1 => 'M&eacute;todos de enumera&ccedil;&otilde;es',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'pt_BR',
    'path' => 'language/enumerations.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.enumerations.backed" class="sect1">
  <h2 class="title">Enumerações Apoiadas</h2>

  <p class="para">
   Por padrão, os Casos não possuem um equivalente escalar. Eles são apenas objetos singleton. No entanto,
   existem muitos casos em que um Caso Enumerado precisa ser capaz de fazer fazer uma conversão de ida e volta para um banco de dados ou
   um armazenamento de dados semelhante, então ter um escalar embutido (e, portanto, trivialmente serializável) equivalente definido
   intrinsecamente é útil.
  </p>

  <p class="para">Para definir um equivalente escalar para uma Enumeração, a sintaxe é a seguinte:</p>

  <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">enum </span><span style="color: #0000BB">Naipe</span><span style="color: #007700">: </span><span style="color: #0000BB">string<br /></span><span style="color: #007700">{<br />    case </span><span style="color: #0000BB">Copas </span><span style="color: #007700">= </span><span style="color: #DD0000">'C'</span><span style="color: #007700">;<br />    case </span><span style="color: #0000BB">Ouros </span><span style="color: #007700">= </span><span style="color: #DD0000">'O'</span><span style="color: #007700">;<br />    case </span><span style="color: #0000BB">Paus </span><span style="color: #007700">= </span><span style="color: #DD0000">'P'</span><span style="color: #007700">;<br />    case </span><span style="color: #0000BB">Espadas </span><span style="color: #007700">= </span><span style="color: #DD0000">'E'</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
  </div>


  <p class="para">
   Um caso que possui um equivalente escalar é chamado de Caso Apoiado, sendo &quot;Apoiado&quot; no sentido de lastreado, suportado,
   por um valor mais simples. Uma enumeração que possui todos Casos Apoiados é chamada Enumeração Apoiada.
   Uma Enumeração Apoiada pode conter apenas Casos Apoiados. Uma Enumeração Pura pode conter apenas Casos Puros.
  </p>

  <p class="para">
   Uma Enumeração Apoiada pode associar valores de tipos <code class="literal">int</code> ou <code class="literal">string</code>,
   e uma determinada enumeração suporta apenas um único tipo de cada vez (isto é, sem união de <code class="literal">int|string</code>).
   Se uma enumeração for marcada como tendo um equivalente escalar, então todos os casos devem possuir um escalar equivalente
   único definido explicitamente. Não existem equivalentes escalares gerados automaticamente
   (p. ex.: inteiros sequenciais). Casos apoiados devem ser únicos; dois casos apoiados não podem
   ter o mesmo equivalente escalar. No entanto, uma constante pode se referir a um caso, efetivamente
   criando um apelido. Veja as <a href="language.enumerations.constants.php" class="link">constantes de enumeração</a>.
  </p>

  <p class="para">
   Valores equivalentes podem ser uma expressão escalar constante.
   Antes do PHP 8.2.0, os valores equivalentes deveriam ser literais ou expressões literais.
   Isto significa que constantes e expressões constantes não eram suportadas.
   Isto é, <code class="code">1 + 1</code> era permitido, mas <code class="code">1 + SOME_CONST</code> não era.
  </p>

  <p class="para">
   Casos Apoiados possuem uma propriedade somente leitura adicional, <code class="literal">value</code>, que é o valor
   especificado na definição.
  </p>

  <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">print </span><span style="color: #0000BB">Naipe</span><span style="color: #007700">::</span><span style="color: #0000BB">Paus</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">value</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// Imprime "P"<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
  </div>


  <p class="para">
   Para impor a propriedade <code class="literal">value</code> como somente leitura, uma variável não pode
   ser atribuída como uma referência para ela. Isto é, o seguinte lança um erro:
  </p>

  <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$naipe </span><span style="color: #007700">= </span><span style="color: #0000BB">Naipe</span><span style="color: #007700">::</span><span style="color: #0000BB">Paus</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$ref </span><span style="color: #007700">= &amp;</span><span style="color: #0000BB">$naipe</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">value</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// Error: Cannot acquire reference to property Naipe::$value<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
  </div>


  <p class="para">
   Enumerações Apoiadas implementam uma interface interna <span class="interfacename"><a href="class.backedenum.php" class="interfacename">BackedEnum</a></span>,
   que expõe dois métodos adicionais:
  </p>

  <ul class="simplelist">
   <li>
    <code class="literal">from(int|string): self</code> recebe um escalar e retornará o caso
    correspondente da enumeração. Se não for encontrado, ela lançará um <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span>. Isso é útil
    principalmente nas situações somente valores previstos são permitidos e um valor de enumeração ausente deve ser
    considerado um erro de interrupção de aplicação.
   </li>
   <li>
    <code class="literal">tryFrom(int|string): ?self</code> recebe uma escalar e retornará o
    caso de enumeração correspondente. Se um não for encontrado, ela retornará <code class="literal">null</code>.
    Isso é útil principalmente em casos onde o escalar de entrada não é confiável e o chamador quer
    implementar sua própria lógica de manipulação de erros ou de valor padrão.
   </li>
  </ul>

  <p class="para">
   Os métodos <code class="literal">from()</code> e <code class="literal">tryFrom()</code> seguem as regras
   padrão de tipagem fraca/forte. No modo de tipagem fraca, passar um inteiro ou string é aceitável
   e o sistema irá coagir o valor de acordo. Passar um float também irá funcionar e será
   convertido. No modo de tipagem estrita, passar um inteiro para <code class="literal">from()</code> em uma
   enumeração associada a strings (ou vice-versa) irá resultar em um <span class="classname"><a href="class.typeerror.php" class="classname">TypeError</a></span>,
   assim como um float irá lançar um erro em todas as circunstâncias. Todos os outros tipos de parâmetro lançarão um TypeError
   em ambos os modos.
  </p>

  <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$registro </span><span style="color: #007700">= </span><span style="color: #0000BB">obter_coisas_do_banco_de_dados</span><span style="color: #007700">(</span><span style="color: #0000BB">$id</span><span style="color: #007700">);<br />print </span><span style="color: #0000BB">$registro</span><span style="color: #007700">[</span><span style="color: #DD0000">'naipe'</span><span style="color: #007700">];<br /><br /></span><span style="color: #0000BB">$naipe </span><span style="color: #007700">= </span><span style="color: #0000BB">Naipe</span><span style="color: #007700">::</span><span style="color: #0000BB">from</span><span style="color: #007700">(</span><span style="color: #0000BB">$registro</span><span style="color: #007700">[</span><span style="color: #DD0000">'naipe'</span><span style="color: #007700">]);<br /></span><span style="color: #FF8000">// Dados inválidos lançam um ValueError: "X" is not a valid scalar value for enum "Naipe"<br /></span><span style="color: #007700">print </span><span style="color: #0000BB">$naipe</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">value</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">$naipe </span><span style="color: #007700">= </span><span style="color: #0000BB">Naipe</span><span style="color: #007700">::</span><span style="color: #0000BB">tryFrom</span><span style="color: #007700">(</span><span style="color: #DD0000">'A'</span><span style="color: #007700">) ?? </span><span style="color: #0000BB">Naipe</span><span style="color: #007700">::</span><span style="color: #0000BB">Espadas</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// Dados inválidos retornam null, então Naipe::Espadas em seu lugar.<br /></span><span style="color: #007700">print </span><span style="color: #0000BB">$naipe</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">value</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
  </div>


  <p class="para">Definir manualmente um método <code class="literal">from()</code> ou <code class="literal">tryFrom()</code> em uma Enumeração Apoiada irá resultar em um erro fatal.</p>

  </div><?php manual_footer($setup); ?>