<?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 => 'es',
  ),
  'this' => 
  array (
    0 => 'language.enumerations.backed.php',
    1 => 'Enumeraciones respaldadas',
    2 => 'Enumeraciones respaldadas',
  ),
  'up' => 
  array (
    0 => 'language.enumerations.php',
    1 => 'Enumeraciones',
  ),
  'prev' => 
  array (
    0 => 'language.enumerations.basics.php',
    1 => 'Enumeraciones b&aacute;sicas',
  ),
  'next' => 
  array (
    0 => 'language.enumerations.methods.php',
    1 => 'M&eacute;todos de enumeraci&oacute;n',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'es',
    '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">Enumeraciones respaldadas</h2>

  <p class="para">
   Por omisión, los Casos Enumerados no tienen equivalente escalar. Son simplemente objetos singleton. Sin embargo,
   hay amplios casos en los que un Caso Enumerado necesita poder hacer un viaje de ida y vuelta a una base de datos o
   un almacén de datos similar, por lo que tener un equivalente escalar integrado (y por lo tanto trivialmente serializable) definido
   intrínsecamente es útil.
  </p>

  <p class="para">Para definir un equivalente escalar para una Enumeración, la sintaxis es la siguiente:</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">Suit</span><span style="color: #007700">: </span><span style="color: #0000BB">string<br /></span><span style="color: #007700">{<br />    case </span><span style="color: #0000BB">Hearts </span><span style="color: #007700">= </span><span style="color: #DD0000">'H'</span><span style="color: #007700">;<br />    case </span><span style="color: #0000BB">Diamonds </span><span style="color: #007700">= </span><span style="color: #DD0000">'D'</span><span style="color: #007700">;<br />    case </span><span style="color: #0000BB">Clubs </span><span style="color: #007700">= </span><span style="color: #DD0000">'C'</span><span style="color: #007700">;<br />    case </span><span style="color: #0000BB">Spades </span><span style="color: #007700">= </span><span style="color: #DD0000">'S'</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
  </div>


  <p class="para">
   Un caso que tiene un equivalente escalar se denomina Caso Respaldado, ya que está &quot;respaldado&quot;
   por un valor más simple. Una enumeración que contiene todos los Casos Respaldados se denomina &quot;Enumeración Respaldada&quot;.
   Una Enumeración Respaldada solo puede contener Casos Respaldados. Una Enumeración Pura solo puede contener Casos Puros.
  </p>

  <p class="para">
   Una Enumeración Respaldada puede estar respaldada por tipos de <code class="literal">int</code> o <code class="literal">string</code>,
   y una enumeración dada admite solo un tipo a la vez (es decir, no hay unión de <code class="literal">int|string</code>).
   Si una enumeración está marcada como que tiene un equivalente escalar, entonces todos los casos deben tener un equivalente
   escalar único definido explícitamente. No hay equivalentes escalares generados automáticamente
   (por ejemplo, enteros secuenciales). Los casos respaldados deben ser únicos; dos casos de enumeración respaldados no pueden
   tener el mismo equivalente escalar. Sin embargo, una constante puede referirse a un caso, creando efectivamente
   un alias. Ver <a href="language.enumerations.constants.php" class="link">Constantes de enumeración</a>.
  </p>

  <p class="para">
   Los valores equivalentes pueden ser una expresión escalar constante.
   Antes de PHP 8.2.0, los valores equivalentes debían ser literales o expresiones literales.
   Esto significa que las constantes y expresiones constantes no estaban admitidas.
   Es decir, <code class="code">1 + 1</code> estaba permitido, pero <code class="code">1 + SOME_CONST</code> no.
  </p>

  <p class="para">
   Los Casos Respaldados tienen una propiedad adicional de solo lectura, <code class="literal">value</code>, que es el valor
   especificado en la definición.
  </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">Suit</span><span style="color: #007700">::</span><span style="color: #0000BB">Clubs</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">value</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// Imprime "C"<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
  </div>


  <p class="para">
   Para hacer cumplir la propiedad <code class="literal">value</code> como de solo lectura, una variable no puede
   ser asignada como referencia a ella. Es decir, lo siguiente genera un error:
  </p>

  <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$suit </span><span style="color: #007700">= </span><span style="color: #0000BB">Suit</span><span style="color: #007700">::</span><span style="color: #0000BB">Clubs</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$ref </span><span style="color: #007700">= &amp;</span><span style="color: #0000BB">$suit</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">value</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// Error: No se puede obtener una referencia a la propiedad Suit::$value<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
  </div>


  <p class="para">
   Las enumeraciones respaldadas implementan una interfaz interna <span class="interfacename"><a href="class.backedenum.php" class="interfacename">BackedEnum</a></span>,
   que expone dos métodos adicionales:
  </p>

  <ul class="simplelist">
   <li>
    <code class="literal">from(int|string): self</code> tomará un escalar y devolverá el Caso de Enumeración correspondiente.
    Si no se encuentra ninguno, lanzará un <span class="classname"><a href="class.valueerror.php" class="classname">ValueError</a></span>. Esto es principalmente
    útil en casos donde el escalar de entrada es confiable y un valor de enumeración faltante debería ser
    considerado un error que detiene la aplicación.
   </li>
   <li>
    <code class="literal">tryFrom(int|string): ?self</code> tomará un escalar y devolverá el
    Caso de Enumeración correspondiente. Si no se encuentra ninguno, devolverá <code class="literal">null</code>.
    Esto es principalmente útil en casos donde el escalar de entrada no es confiable y el llamador quiere
    implementar su propia lógica de manejo de errores o valores por omisión.
   </li>
  </ul>

  <p class="para">
   Los métodos <code class="literal">from()</code> y <code class="literal">tryFrom()</code> siguen las reglas estándar
   de tipado débil/fuerte. En modo de tipado débil, pasar un entero o string es admisible
   y el sistema coercionará el valor en consecuencia. Pasar un float también funcionará y será
   coercionado. En modo de tipado estricto, pasar un entero a <code class="literal">from()</code> en una
   enumeración respaldada por string (o viceversa) resultará en un <span class="classname"><a href="class.typeerror.php" class="classname">TypeError</a></span>,
   al igual que un float en todas las circunstancias. Todos los demás tipos de parámetros lanzarán un TypeError
   en ambos modos.
  </p>

  <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$record </span><span style="color: #007700">= </span><span style="color: #0000BB">get_stuff_from_database</span><span style="color: #007700">(</span><span style="color: #0000BB">$id</span><span style="color: #007700">);<br />print </span><span style="color: #0000BB">$record</span><span style="color: #007700">[</span><span style="color: #DD0000">'suit'</span><span style="color: #007700">];<br /><br /></span><span style="color: #0000BB">$suit </span><span style="color: #007700">=  </span><span style="color: #0000BB">Suit</span><span style="color: #007700">::</span><span style="color: #0000BB">from</span><span style="color: #007700">(</span><span style="color: #0000BB">$record</span><span style="color: #007700">[</span><span style="color: #DD0000">'suit'</span><span style="color: #007700">]);<br /></span><span style="color: #FF8000">// Datos no válidos lanzan un ValueError: "X" no es un valor escalar válido para la enumeración "Suit"<br /></span><span style="color: #007700">print </span><span style="color: #0000BB">$suit</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">value</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">$suit </span><span style="color: #007700">= </span><span style="color: #0000BB">Suit</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">Suit</span><span style="color: #007700">::</span><span style="color: #0000BB">Spades</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// Datos no válidos devuelven null, por lo que se usa Suit::Spades en su lugar.<br /></span><span style="color: #007700">print </span><span style="color: #0000BB">$suit</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 un método <code class="literal">from()</code> o <code class="literal">tryFrom()</code> en una Enumeración Respaldada resultará en un error fatal.</p>

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