{"id":43518,"date":"2021-09-16T11:09:56","date_gmt":"2021-09-16T09:09:56","guid":{"rendered":"https:\/\/kinsta.com\/?p=101567"},"modified":"2023-08-23T11:38:02","modified_gmt":"2023-08-23T09:38:02","slug":"php-8-1","status":"publish","type":"post","link":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/","title":{"rendered":"Novedades de PHP 8.1: Caracter\u00edsticas, Cambios, Mejoras y Mucho M\u00e1s"},"content":{"rendered":"<p>Lanzado el 25 de noviembre de 2021, <a href=\"https:\/\/wiki.php.net\/todo\/php81\">PHP 8.1 est\u00e1 finalmente aqu\u00ed<\/a>, con varias caracter\u00edsticas interesantes.<\/p>\n<p>En este art\u00edculo, cubriremos en detalle las novedades de PHP 8.1. Desde sus nuevas caracter\u00edsticas y mejoras de rendimiento hasta los cambios significativos y las desaprobaciones, los revisaremos todos en profundidad.<\/p>\n<p>\u00a1Si\u00e9ntate bien!<\/p>\n<div><\/div><kinsta-auto-toc heading=\"Table of Contents\" exclude=\"last\" list-style=\"arrow\" selector=\"h2\" count-number=\"-1\"><\/kinsta-auto-toc>\n<h2>Nuevas caracter\u00edsticas de PHP 8.1<\/h2>\n<p>Empecemos por cubrir todas las nuevas caracter\u00edsticas de PHP 8.1. Es una lista bastante grande.<\/p>\n<div><\/div><kinsta-auto-toc list-style=\"disc\" selector=\"h3\" count-number=\"20\" sub-toc=\"true\"><\/kinsta-auto-toc>\n<aside role=\"note\" class=\"wp-block-kinsta-notice is-style-info\">\n            <h3>Info<\/h3>\n        <p>PHP 8.1 ya est\u00e1 disponible en Kinsta para todos los entornos. Por favor, consulta nuestra <a href=\"https:\/\/kinsta.com\/es\/changelog\/php-8-1\/\">actualizaci\u00f3n de caracter\u00edsticas de PHP 8.1<\/a> para obtener m\u00e1s informaci\u00f3n.<\/p>\n<\/aside>\n\n\n<h3>Tipos de intersecci\u00f3n puros<\/h3>\n<p>PHP 8.1 a\u00f1ade soporte para tipos de intersecci\u00f3n. Es similar a los <a href=\"https:\/\/kinsta.com\/es\/blog\/php-8\/#union-types-2-0\">tipos de uni\u00f3n<\/a> introducidos en PHP 8.0, pero su uso previsto es exactamente el opuesto.<\/p>\n<p>Para entender mejor su uso, vamos a refrescar nuestra memoria para saber c\u00f3mo funcionan las declaraciones de tipo en PHP.<\/p>\n<p>Esencialmente, puedes a\u00f1adir declaraciones de tipo a los argumentos de las funciones, a los valores de retorno y a las propiedades de las clases. Esta asignaci\u00f3n se llama \u00abtype hinting\u00bb y asegura que el valor es del tipo correcto en el momento de la llamada. De lo contrario, lanza un <a href=\"https:\/\/www.php.net\/manual\/en\/class.typeerror.php\">TypeError<\/a> de inmediato. A su vez, esto te ayuda a depurar mejor el c\u00f3digo.<\/p>\n<p>Sin embargo, declarar un solo tipo tiene sus limitaciones. Los tipos de uni\u00f3n te ayudan a superar eso al permitirte declarar un valor con m\u00faltiples tipos, y la entrada tiene que satisfacer al menos uno de los tipos declarados.<\/p>\n<p>Por otro lado, el <a href=\"https:\/\/wiki.php.net\/rfc\/pure-intersection-types\">RFC<\/a> describe los tipos de intersecci\u00f3n como:<\/p>\n<blockquote><p><em>Un \u00abtipo de intersecci\u00f3n\u00bb requiere que un valor satisfaga varias restricciones de tipo en lugar de una sola.<\/em><\/p>\n<p><em>&#8230;los tipos de intersecci\u00f3n puros se especifican utilizando la sintaxis T1&#038;T2&#038;&#8230; y pueden utilizarse en todas las posiciones en las que se aceptan actualmente los tipos&#8230;<\/em><\/p><\/blockquote>\n<p>Obs\u00e9rvese el uso del operador <code>&<\/code> (AND) para declarar tipos de intersecci\u00f3n. En cambio, utilizamos el operador <code>|<\/code> (OR) para declarar tipos de uni\u00f3n.<\/p>\n<p>El uso de la mayor\u00eda de los tipos est\u00e1ndar en un tipo de intersecci\u00f3n dar\u00e1 lugar a un tipo que nunca puede cumplirse (por ejemplo, entero y cadena). Por lo tanto, los tipos de intersecci\u00f3n solo pueden incluir tipos de clase (es decir, interfaces y nombres de clase).<\/p>\n<p>Aqu\u00ed hay un c\u00f3digo de ejemplo de c\u00f3mo se pueden utilizar los tipos de intersecci\u00f3n:<\/p>\n<pre><code class=\"language-php\">class A {\n\u00a0 \u00a0 private Traversable&Countable $countableIterator;\n \n\u00a0 \u00a0 public function setIterator(Traversable&Countable $countableIterator): void {\n\u00a0 \u00a0 \u00a0 \u00a0 $this-&gt;countableIterator = $countableIterator;\n\u00a0 \u00a0 }\n \n\u00a0 \u00a0 public function getIterator(): Traversable&Countable {\n\u00a0 \u00a0 \u00a0 \u00a0 return $this-&gt;countableIterator;\n\u00a0 \u00a0 }\n}<\/code><\/pre>\n<p>En el c\u00f3digo anterior, hemos definido una variable <strong>countableIterator <\/strong>como una intersecci\u00f3n de dos tipos: <strong>Traversable <\/strong>y <strong>Countable<\/strong>. En este caso, los dos tipos declarados son interfaces.<\/p>\n<p>Los tipos de intersecci\u00f3n tambi\u00e9n se ajustan a las reglas de varianza est\u00e1ndar de PHP ya utilizadas para la comprobaci\u00f3n de tipos y la herencia. Pero hay dos reglas adicionales sobre c\u00f3mo los tipos de intersecci\u00f3n interact\u00faan con la subtipificaci\u00f3n. Puedes leer m\u00e1s sobre <a href=\"https:\/\/wiki.php.net\/rfc\/pure-intersection-types#variance\">las reglas de variaci\u00f3n de los tipos de intersecci\u00f3n<\/a> en su RFC.<\/p>\n<p>En algunos lenguajes de programaci\u00f3n, se pueden combinar Tipos Uni\u00f3n y Tipos Intersecci\u00f3n en la misma declaraci\u00f3n. Pero PHP 8.1 lo proh\u00edbe. Por lo tanto, su implementaci\u00f3n se llama tipos de intersecci\u00f3n \u00abpure\u00bb. Sin embargo, el RFC menciona que \u00abse deja como una caracter\u00edstica futura\u00bb.<\/p>\n<h3>Enums<\/h3>\n<p>PHP 8.1 finalmente a\u00f1ade soporte para enums (tambi\u00e9n llamados enumeraciones o tipos enumerados). Son un tipo de datos definido por el usuario que consiste en un conjunto de valores posibles.<\/p>\n<p>El ejemplo de enums m\u00e1s com\u00fan en los lenguajes de programaci\u00f3n es el tipo <strong>booleano<\/strong>, con <code>true<\/code> y <code>false<\/code> como dos valores posibles. Es tan com\u00fan que est\u00e1 incorporado en muchos <a href=\"https:\/\/kinsta.com\/es\/blog\/mejor-lenguaje-de-programacion-para-aprender\/\">lenguajes de programaci\u00f3n modernos<\/a>.<\/p>\n<p>Seg\u00fan <a href=\"https:\/\/wiki.php.net\/rfc\/enumerations\">el RFC<\/a>, los enums en PHP estar\u00e1n restringidos a \u00abenumeraciones unitarias\u00bb al principio:<\/p>\n<blockquote><p><em>El alcance de esta RFC se limita a las \u00abenumeraciones unitarias\u00bb, es decir, a las enumeraciones que son en s\u00ed mismas un valor, en lugar de una simple sintaxis de fantas\u00eda para una constante primitiva, y que no incluyen informaci\u00f3n adicional asociada. Esta capacidad ofrece un soporte muy ampliado para el modelado de datos, las definiciones de tipos personalizados y el comportamiento de tipo m\u00f3nada. Los Enums permiten la t\u00e9cnica de modelado de \u00abhacer irrepresentables los estados no v\u00e1lidos\u00bb, lo que conduce a un c\u00f3digo m\u00e1s robusto con menos necesidad de pruebas exhaustivas.<\/em><\/p><\/blockquote>\n<p>Para llegar a este punto, el equipo de PHP estudi\u00f3 muchos lenguajes que ya soportan las enumeraciones. <a href=\"https:\/\/github.com\/Crell\/enum-comparison\">Su estudio<\/a> encontr\u00f3 que se pueden categorizar las enumeraciones en tres grupos generales: Constantes extravagantes, Objetos extravagantes, y Tipos de datos algebraicos (ADTs) completos. Es una lectura interesante.<\/p>\n<p>PHP implementa los enums \u00abFancy Objects\u00bb, con planes de extenderlo a ADTs completos en el futuro. Est\u00e1 modelado conceptual y sem\u00e1nticamente despu\u00e9s de los tipos enumerados en Swift, Rust y Kotlin, aunque no est\u00e1 modelado directamente en ninguno de ellos.<\/p>\n<p>El RFC utiliza la famosa analog\u00eda de los palos de una baraja para explicar c\u00f3mo funcionar\u00e1:<\/p>\n<pre><code class=\"language-php\">enum Suit {\n\u00a0 case Hearts;\n\u00a0 case Diamonds;\n\u00a0 case Clubs;\n\u00a0 case Spades;\n}<\/code><\/pre>\n<p>En este caso, el enunciado <strong>Suit <\/strong>define cuatro valores posibles: <strong>Hearts<\/strong>, <strong>Diamonds<\/strong>, <strong>Clubs <\/strong>y <strong>Spades<\/strong>. Puedes acceder a estos valores directamente utilizando la sintaxis: <code>Suit::Hearts<\/code>, <code>Suit::Diamonds<\/code>, <code>Suit::Clubs<\/code>, y <code>Suit::Spades<\/code>.<\/p>\n<p>Este uso puede parecer familiar, ya que los enums se construyen sobre clases y objetos. Se comportan de forma similar y tienen casi los mismos requisitos. Los enums comparten los mismos espacios de nombres que las clases, las interfaces y los traits.<\/p>\n<p>Los enums mencionados anteriormente se denominan <strong>Pure Enums<\/strong>.<\/p>\n<p>Tambi\u00e9n puedes definir <strong>Backed <\/strong><strong>Enums <\/strong>si quieres dar un valor equivalente a un escalar a cualquier caso. Sin embargo, los enums respaldados solo pueden tener un tipo, ya sea <code>int<\/code> o <code>string<\/code> (nunca ambos).<\/p>\n<pre><code class=\"language-php\">enum Suit: string {\n\u00a0 case Hearts = 'H';\n\u00a0 case Diamonds = 'D';\n\u00a0 case Clubs = 'C';\n\u00a0 case Spades = 'S';\n}<\/code><\/pre>\n<p>Adem\u00e1s, todos los casos diferentes de un enum respaldado deben tener un valor \u00fanico. Y nunca puedes mezclar enums puros y respaldados.<\/p>\n<p>El RFC profundiza en los m\u00e9todos enum, los m\u00e9todos est\u00e1ticos, las constantes, las expresiones constantes y mucho m\u00e1s. Cubrirlos todos est\u00e1 m\u00e1s all\u00e1 del alcance de este art\u00edculo. Puedes consultar la documentaci\u00f3n para familiarizarte con todas sus pros.<\/p>\n<h3><strong>El tipo de devoluci\u00f3n <\/strong><code>never<\/code><\/h3>\n<p>PHP 8.1 a\u00f1ade una nueva pista de tipo de retorno llamada <code>never<\/code>. Es s\u00faper \u00fatil para usar en funciones que siempre <code>throw<\/code> o\u00a0<code>exit<\/code>.<\/p>\n<p>Seg\u00fan su <a href=\"https:\/\/wiki.php.net\/rfc\/noreturn_type\">RFC<\/a>, las funciones de redirecci\u00f3n de URL que siempre <code>exit<\/code> (expl\u00edcita o impl\u00edcitamente) son un buen ejemplo para su uso:<\/p>\n<pre><code class=\"language-php\">function redirect(string $uri): never {\n\u00a0 \u00a0 header('Location: ' . $uri);\n\u00a0 \u00a0 exit();\n}\n \nfunction redirectToLoginPage(): never {\n\u00a0 \u00a0 redirect('\/login');\n}<\/code><\/pre>\n<p>Una funci\u00f3n <code>never<\/code>-declarada debe cumplir tres condiciones:<\/p>\n<ul>\n<li>No deber\u00eda tener la declaraci\u00f3n de\u00a0<code>return<\/code> definida expl\u00edcitamente.<\/li>\n<li>No deber\u00eda tener la sentencia de <code>return<\/code> definida impl\u00edcitamente (por ejemplo, sentencias <strong>if-else<\/strong>).<\/li>\n<li>Debe terminar su ejecuci\u00f3n con una sentencia de <code>exit<\/code> (expl\u00edcita o impl\u00edcitamente).<\/li>\n<\/ul>\n<p>El ejemplo de <a href=\"https:\/\/kinsta.com\/es\/docs\/alojamiento-wordpress\/reglas-de-redireccionamiento\/\">redirecci\u00f3n de URL<\/a> anterior muestra el uso tanto expl\u00edcito como impl\u00edcito del tipo de <code>never<\/code> retorno.<\/p>\n<p>El tipo de devoluci\u00f3n <code>never<\/code> comparte muchas similitudes con el tipo de retorno <code>void<\/code>. Ambos aseguran que la funci\u00f3n o el m\u00e9todo no devuelve un valor. Sin embargo, difiere en que impone reglas m\u00e1s estrictas. Por ejemplo, una funci\u00f3n declarada como <code>void<\/code> puede seguir <code>return<\/code> sin un valor expl\u00edcito, pero no se puede hacer lo mismo con una funci\u00f3n declarada como <code>never<\/code>.<\/p>\n<p>Como regla general, utiliza\u00a0 <code>void<\/code> cuando esperas que PHP contin\u00fae ejecut\u00e1ndose despu\u00e9s de la llamada a la funci\u00f3n. Usa <code>never<\/code> cuando quieras lo contrario.<\/p>\n<p>Adem\u00e1s, <code>never<\/code> se define como un tipo \u00abinferior\u00bb. Por lo tanto, cualquier m\u00e9todo de la clase declarado <code>never<\/code> puede \u00abnunca\u00bb cambiar su tipo de retorno a otra cosa. Sin embargo, puedes extender un m\u00e9todo declarado <code>void<\/code> con un m\u00e9todo declarado <code>never<\/code>.<\/p>\n<aside role=\"note\" class=\"wp-block-kinsta-notice is-style-info\">\n            <h3>Info<\/h3>\n        <p>La RFC original lista el tipo de retorno <code>never<\/code> como <code>noreturn<\/code>, que era un tipo de retorno ya soportado por dos herramientas de an\u00e1lisis est\u00e1tico de PHP, a saber, Psalm y PHPStan. Como esto fue propuesto por los propios autores de Psalm y PHPStan, mantuvieron su terminolog\u00eda. Sin embargo, debido a las convenciones de nomenclatura, el equipo de PHP llev\u00f3 a cabo una encuesta sobre <code>noreturn<\/code> frente a <code>never<\/code>, resultando <code>never<\/code> el ganador definitivo. Por lo tanto, para las versiones de PHP 8.1+, sustituya siempre <code>noreturn<\/code> por <code>never<\/code>.<\/p>\n<\/aside>\n\n<h3>Fiber<\/h3>\n<p>Hist\u00f3ricamente, el c\u00f3digo PHP ha sido casi siempre c\u00f3digo s\u00edncrono. La ejecuci\u00f3n del c\u00f3digo se detiene hasta que se devuelve el resultado, incluso para las operaciones de E\/S. Puedes imaginar por qu\u00e9 este proceso puede hacer que la ejecuci\u00f3n del c\u00f3digo sea m\u00e1s lenta.<\/p>\n<p>Existen m\u00faltiples soluciones de terceros para superar este obst\u00e1culo y permitir a los desarrolladores escribir c\u00f3digo PHP de forma as\u00edncrona, especialmente para operaciones de E\/S concurrentes. Algunos ejemplos populares son <a href=\"https:\/\/amphp.org\/\">amphp<\/a>, <a href=\"https:\/\/reactphp.org\/\">ReactPHP<\/a> y <a href=\"https:\/\/guzzlephp.org\/\">Guzzle<\/a>.<\/p>\n<p>Sin embargo, no hay una manera est\u00e1ndar de manejar tales instancias en PHP. Adem\u00e1s, tratar el c\u00f3digo s\u00edncrono y as\u00edncrono en la misma pila de llamadas <a href=\"https:\/\/journal.stuffwithstuff.com\/2015\/02\/01\/what-color-is-your-function\/\">conduce a otros problemas<\/a>.<\/p>\n<p>Los fibers son la forma en que PHP maneja el paralelismo a trav\u00e9s de hilos virtuales (o <a href=\"https:\/\/en.wikipedia.org\/wiki\/Green_threads\">hilos verdes<\/a>). Busca eliminar la diferencia entre el c\u00f3digo s\u00edncrono y el as\u00edncrono permitiendo que las funciones de PHP se interrumpan sin afectar a toda la pila de llamadas.<\/p>\n<p>Esto es lo que <em>promete <\/em><a href=\"https:\/\/wiki.php.net\/rfc\/fibers\">el RFC<\/a>:<\/p>\n<ul>\n<li>A\u00f1adir soporte para Fibers a PHP.<\/li>\n<li>Introducci\u00f3n de una nueva clase Fiber y la correspondiente clase de reflexi\u00f3n ReflectionFiber.<\/li>\n<li>A\u00f1adir clases de excepci\u00f3n FiberError y FiberExit para representar errores.<\/li>\n<li>Los fibers permiten implementaciones transparentes de E\/S sin bloqueo de las interfaces existentes (PSR-7, Doctrine ORM, etc.). Esto se debe a que se elimina el objeto marcador de posici\u00f3n (promesa). En su lugar, las funciones pueden declarar el tipo de resultado de E\/S en lugar de un objeto marcador de posici\u00f3n que no puede especificar un tipo de resoluci\u00f3n porque PHP no soporta gen\u00e9ricos.<\/li>\n<\/ul>\n<p>Puede usar Fibers para desarrollar funciones PHP interrumpibles de pila completa, que luego puede usar para implementar la multitarea cooperativa en PHP. Como Fibers pone en pausa toda la pila de <a href=\"https:\/\/kinsta.com\/es\/docs\/alojamiento-wordpress\/monitorizacion-wordpress\/herramienta-apm\/#stack-trace\">ejecuci\u00f3n<\/a>, puedes estar tranquilo sabiendo que no da\u00f1ar\u00e1 el resto de tu c\u00f3digo.<\/p>\n<figure id=\"attachment_110018\" aria-describedby=\"caption-attachment-110018\" style=\"width: 1100px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/kinsta.com\/wp-content\/uploads\/2021\/08\/PHP-8.1-fiber-flow.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-110018 size-full\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2021\/08\/PHP-8.1-fiber-flow-e1637845079600.png\" alt=\"Gr\u00e1fico que ilustra el flujo de ejecuci\u00f3n del c\u00f3digo PHP con Fibers (Fuente: PHP.net).\" width=\"1100\" height=\"894\"><\/a><figcaption id=\"caption-attachment-110018\" class=\"wp-caption-text\">Gr\u00e1fico que ilustra el flujo de ejecuci\u00f3n del c\u00f3digo PHP con Fibers (Fuente: PHP.net).<\/figcaption><\/figure>\n<p>Para ilustrar el uso de los fibers, su RFC utiliza este sencillo ejemplo:<\/p>\n<pre><code class=\"language-php\">$fiber = new Fiber(function (): void {\n\u00a0 \u00a0 $value = Fiber::suspend('fiber');\n\u00a0 \u00a0 echo \"Value used to resume fiber: \", $value, \"\\n\";\n});\n \n$value = $fiber-&gt;start();\n \necho \"Value from fiber suspending: \", $value, \"\\n\";\n \n$fiber-&gt;resume('test');<\/code><\/pre>\n<p>Est\u00e1s creando una \u00abfier\u00bb en el c\u00f3digo anterior e inmediatamente la suspendes con la cadena <code>fiber<\/code>. La declaraci\u00f3n de <code>eco<\/code> sirve como una se\u00f1al visual para la reanudaci\u00f3n de la fibra.<\/p>\n<p>Puedes recuperar este valor de cadena desde la llamada a <code>$fiber-&gt;start()<\/code>.<\/p>\n<p>A continuaci\u00f3n, se reanuda el fiber con la cadena \u00abtest\u00bb, que se devuelve de la llamada a <code>Fiber::suspend()<\/code>. La ejecuci\u00f3n completa del c\u00f3digo da como resultado una salida que dice:<\/p>\n<pre><code class=\"language-php\">Value from fiber suspending: fiber\nValue used to resume fiber: test<\/code><\/pre>\n<p>Ese es el ejemplo de libro de texto de PHP Fibers en el trabajo. <a href=\"https:\/\/github.com\/nox7\/async-php-8-io-http\">Aqu\u00ed hay otro ejemplo de Fibers<\/a> para realizar siete peticiones GET as\u00edncronas.<\/p>\n<p>Con todo lo dicho, la mayor\u00eda de los desarrolladores de PHP nunca tratar\u00e1n con laos fibers directamente. Y el RFC incluso sugiere lo mismo:<\/p>\n<blockquote><p><em>Los fibers son una caracter\u00edstica avanzada que la mayor\u00eda de los usuarios no utilizar\u00e1n directamente. Esta caracter\u00edstica est\u00e1 dirigida principalmente a los autores de bibliotecas y marcos de trabajo para proporcionar un bucle de eventos y una API de programaci\u00f3n as\u00edncrona. Los fibers permiten integrar la ejecuci\u00f3n de c\u00f3digo as\u00edncrono sin problemas en el c\u00f3digo s\u00edncrono en cualquier punto, sin necesidad de modificar la pila de llamadas de la aplicaci\u00f3n o a\u00f1adir c\u00f3digo repetitivo.<\/em><\/p>\n<p><em>No se espera que la API del fiber se utilice directamente en el c\u00f3digo de la aplicaci\u00f3n. Los fibers proporcionan una API de control de flujo b\u00e1sica y de bajo nivel para crear abstracciones de mayor nivel que luego se utilizan en el c\u00f3digo de la aplicaci\u00f3n.<\/em><\/p><\/blockquote>\n<p>Teniendo en cuenta sus ventajas de rendimiento, es de esperar que las bibliotecas y los frameworks de PHP aprovechen esta nueva caracter\u00edstica. Ser\u00e1 interesante ver c\u00f3mo implementan Fibers dentro de su ecosistema.<\/p>\n<h3><strong>Nuevas propiedades de<\/strong>\u00a0<code>readonly<\/code><\/h3>\n<p>PHP 8.1 a\u00f1ade soporte para propiedades <code>readonly<\/code> . Solo pueden ser inicializadas una vez desde el \u00e1mbito donde se declaran. Una vez inicializadas, no se puede modificar su valor nunca. Si lo hicieras, se producir\u00eda una excepci\u00f3n de <strong>error<\/strong>.<\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/readonly_properties_v2\">Su RFC<\/a> dice:<\/p>\n<blockquote><p><em>Una propiedad <strong>readonly<\/strong><strong>\u00a0<\/strong>solo puede ser inicializada una vez, y solo desde el \u00e1mbito donde ha sido declarada. Cualquier otra asignaci\u00f3n o modificaci\u00f3n de la propiedad dar\u00e1 lugar a una excepci\u00f3n de error.<\/em><\/p><\/blockquote>\n<p>Aqu\u00ed tienes un ejemplo de c\u00f3mo puedes utilizarlo:<\/p>\n<pre><code class=\"language-php\">class Test {\n\u00a0 \u00a0 public readonly string $kinsta;\n \n\u00a0 \u00a0 public function __construct(string $kinsta) {\n\u00a0 \u00a0 \u00a0 \u00a0 \/\/ Legal initialization.\n\u00a0 \u00a0 \u00a0 \u00a0 $this-&gt;kinsta = $kinsta;\n\u00a0 \u00a0 }\n}<\/code><\/pre>\n<p>Una vez inicializado, no hay vuelta atr\u00e1s. Tener esta caracter\u00edstica incorporada en PHP reduce en gran medida el c\u00f3digo repetitivo que a menudo se utiliza para activar esta funcionalidad.<\/p>\n<p>La propiedad <code>readonly<\/code> ofrece una fuerte garant\u00eda de inmutabilidad, tanto dentro como fuera de la clase. No importa el c\u00f3digo que se ejecute en el medio. Llamar a una propiedad <code>readonly<\/code> siempre devolver\u00e1 el mismo valor.<\/p>\n<p>Sin embargo, el uso de la propiedad <code>readonly<\/code> puede no ser ideal en casos de uso espec\u00edficos. Por ejemplo, solo se puede utilizar junto a una <a href=\"https:\/\/kinsta.com\/es\/blog\/php-7-4\/#typed-properties\">propiedad tipificada<\/a> porque las declaraciones sin tipo son impl\u00edcitamente <code>null<\/code> y no pueden ser <code>readonly<\/code>.<\/p>\n<p>Adem\u00e1s, establecer una propiedad <code>readonly<\/code> no hace que los objetos sean inmutables. La propiedad <code>readonly<\/code> mantendr\u00e1 el mismo objeto, pero ese objeto en s\u00ed mismo puede cambiar.<\/p>\n<p>Otro problema menor de esta propiedad es que no se puede clonar. Ya existe una <a href=\"https:\/\/stitcher.io\/blog\/cloning-readonly-properties-in-php-81\">soluci\u00f3n para este caso particular<\/a>. Invest\u00edgalo si es necesario.<\/p>\n<h3><strong>Definir las constantes<\/strong>\u00a0<code>final<\/code> <strong>de la clase<\/strong><\/h3>\n<p>A partir de PHP 8.0, puedes anular las constantes de las clases con sus sub-clases . Esto se debe a la forma en que se implementa la herencia en PHP.<\/p>\n<p>Este es un ejemplo de c\u00f3mo se puede anular el valor de una constante previamente declarada:<\/p>\n<pre><code class=\"language-php\">class Moo\n{\n\u00a0 \u00a0 public const M = \"moo\";\n}\n \nclass Meow extends Moo\n{\n\u00a0 \u00a0 public const M = \"meow\";\n}\u00a0\u00a0<\/code><\/pre>\n<p>Ahora, si las vacas quieren ser m\u00e1s estrictas con el comportamiento de los gatos (al menos con las constantes), pueden hacerlo con el nuevo modificador <code>final<\/code> de PHP 8.1.<\/p>\n<p>Una vez que has declarado una constante como <code>final<\/code>, significa que.<\/p>\n<pre><code class=\"language-php\">class Moo\n{\n\u00a0 \u00a0 final public const M = \"moo\";\n}\n \nclass Meow extends Moo\n{\n\u00a0 \u00a0 public const M = \"meow\";\n}\n \n\/\/ Fatal error: Meow::M cannot override final constant Moo::M<\/code><\/pre>\n<p>Puedes leer m\u00e1s sobre esto en las <a href=\"https:\/\/wiki.php.net\/rfc\/final_class_const\">constantes final de clase<\/a> PHP RFC.<\/p>\n<h3>Nuevas funciones <code>fsync()<\/code> y <code>fdatasync()<\/code><\/h3>\n<p>PHP 8.1 a\u00f1ade dos nuevas funciones del sistema de archivos llamadas <code>fsync()<\/code> y <code>fdatasync()<\/code>. Parecer\u00e1n familiares para aquellos acostumbrados a <a href=\"https:\/\/linux.die.net\/man\/2\/fsync\">las funciones de Linux del mismo nombre<\/a>. Eso es porque est\u00e1n relacionadas, solo que implementadas para PHP.<\/p>\n<p>De hecho, esta adici\u00f3n ha sido muy esperada. PHP es uno de los pocos lenguajes de programaci\u00f3n importantes que a\u00fan no implementaron <a href=\"https:\/\/wiki.php.net\/rfc\/fsync_function\">fsync() y fdatasync()<\/a> &#8211; es decir, <a href=\"https:\/\/wiki.php.net\/rfc\/fsync_function\">hasta PHP 8.1<\/a>.<\/p>\n<p>La funci\u00f3n <code>fsync()<\/code> es similar a la funci\u00f3n <code>fflush()<\/code> de PHP, pero difiere significativamente en un aspecto. Mientras que <code>fflush()<\/code> vac\u00eda los b\u00faferes internos de la aplicaci\u00f3n al sistema operativo, <code>fsync()<\/code> va un paso m\u00e1s all\u00e1 y asegura que los b\u00faferes internos sean vaciados al <a href=\"https:\/\/kinsta.com\/es\/blog\/que-es-ssd\/\">almacenamiento f\u00edsico<\/a>. Esto asegura una escritura completa y persistente para que pueda recuperar los datos incluso despu\u00e9s de una ca\u00edda de la aplicaci\u00f3n o del sistema.<\/p>\n<p>Aqu\u00ed tienes un ejemplo de c\u00f3mo puedes utilizarlo.<\/p>\n<pre><code class=\"language-php\">$doc = 'kinsta.txt';\n\n$kin = fopen($doc, 'ki');\nfwrite($kin, 'doc info');\nfwrite($kin, \"\\r\\n\");\nfwrite($kin, 'more info');\n\nfsync($kin);\nfclose($kin);<\/code><\/pre>\n<p>A\u00f1adir la llamada <code>fsync()<\/code> al final asegura que cualquier dato retenido en el b\u00fafer interno de PHP o del sistema operativo se escriba en el almacenamiento. Todas las dem\u00e1s ejecuciones de c\u00f3digo se bloquean hasta entonces.<\/p>\n<p>Su funci\u00f3n relacionada es <code>fdatasync()<\/code>. Se utiliza para sincronizar datos pero no necesariamente metadatos. Para los datos cuyos metadatos no son esenciales, esta llamada a la funci\u00f3n hace que el proceso de escritura sea un poco m\u00e1s r\u00e1pido.<\/p>\n<p>Sin embargo, debes tener en cuenta que PHP 8.1 a\u00fan no soporta <code>fdatasync()<\/code> completamente en Windows. Simplemente act\u00faa como un alias de <code>fsync()<\/code>. En POSIX, <code>fdatasync()<\/code> est\u00e1 correctamente implementada.<\/p>\n<h3><strong>Nueva funci\u00f3n<\/strong>\u00a0<code>array_is_list()<\/code><\/h3>\n<p>Los arrays de PHP pueden contener claves tanto enteras como de cadena. Esto significa que puedes usarlos para varias cosas, incluyendo listas, tablas hash, diccionarios, colecciones, pilas, colas y mucho m\u00e1s. Incluso puede tener arrays dentro de arrays, creando arrays multidimensionales.<\/p>\n<p>Se puede comprobar eficazmente si una entrada concreta es un array, pero no es tan f\u00e1cil comprobar si le faltan desplazamientos de array, claves desordenadas, etc. En resumen, no puedes verificar r\u00e1pidamente si un array es una lista.<\/p>\n<p>La <a href=\"https:\/\/wiki.php.net\/rfc\/is_list\" target=\"_blank\" rel=\"noopener noreferrer\">array_is_list() function<\/a> comprueba si las claves de un array est\u00e1n en orden secuencial empezando por <code>0<\/code>, y sin espacios. Si se cumplen todas las condiciones, devolver\u00e1 <code>true<\/code>. Por defecto, tambi\u00e9n devuelve <code>true<\/code> para arrays vac\u00edos.<\/p>\n<p>Aqu\u00ed hay algunos ejemplos de su uso con condiciones <code>true<\/code> y\u00a0<code>false<\/code> :<\/p>\n<pre><code class=\"language-php\">\/\/ true array_is_list() examples\narray_is_list([]); \/\/ true\narray_is_list([1, 2, 3]); \/\/ true\narray_is_list(['cats', 2, 3]); \/\/ true\narray_is_list(['cats', 'dogs']); \/\/ true\narray_is_list([0 =&gt; 'cats', 'dogs']); \/\/ true\narray_is_list([0 =&gt; 'cats', 1 =&gt; 'dogs']); \/\/ true \n\n\/\/ false array_is_list() examples \narray_is_list([1 =&gt; 'cats', 'dogs']); \/\/ as first key isn't 0\narray_is_list([1 =&gt; 'cats', 0 =&gt; 'dogs']); \/\/ keys are out of order\narray_is_list([0 =&gt; 'cats', 'bark' =&gt; 'dogs']); \/\/ non-integer keys\narray_is_list([0 =&gt; 'cats', 2 =&gt; 'dogs']); \/\/ gap in between keys <\/code><\/pre>\n<p>Una lista de array de PHP con claves fuera de orden es <a href=\"https:\/\/kinsta.com\/es\/blog\/seguridad-wordpress\/#2-use-latest-php-version\">una fuente potencial de errores<\/a>. El uso de esta funci\u00f3n para imponer una estricta adherencia a los requisitos de la <strong>lista<\/strong> antes de avanzar en la ejecuci\u00f3n del c\u00f3digo es una gran adici\u00f3n a PHP.<\/p>\n<h3>Nuevas funciones Sodium XChaCha20<\/h3>\n<p>Sodium es una biblioteca criptogr\u00e1fica moderna y f\u00e1cil de usar para el cifrado, descifrado, hash de <a href=\"https:\/\/kinsta.com\/es\/blog\/administradores-contrasenas\/\">contrase\u00f1as<\/a>, firmas y m\u00e1s. El <a href=\"https:\/\/pecl.php.net\/package\/libsodium\">paquete PECL libsodium<\/a> a\u00f1ade una envoltura para Sodium para que los desarrolladores de PHP puedan utilizarla.<\/p>\n<p>Incluso <a href=\"https:\/\/doc.libsodium.org\/libsodium_users\">empresas tecnol\u00f3gicas l\u00edderes<\/a> como Facebook, Discord, Malwarebytes y Valve utilizan libsodium para asegurar a sus usuarios con conexiones r\u00e1pidas y seguras.<\/p>\n<p>libsodium soporta el <a href=\"https:\/\/www.cryptopp.com\/wiki\/XChaCha20\">algoritmo de cifrado XChaCha20<\/a> para cifrar y descifrar datos, especialmente para el cifrado de flujos. Asimismo, la extensi\u00f3n PECL libsodium ya soporta XChaCha20, pero solo con el c\u00f3digo de autenticaci\u00f3n de mensajes Poly1305.<\/p>\n<p>Muchas aplicaciones PHP utilizan XChaCha20 directamente para el cifrado de flujos. Para facilitar las cosas, a partir de PHP 8.1, tendr\u00e1s tres nuevas funciones para cifrar o descifrar datos con XChaCha20 sin autenticaci\u00f3n de por medio. Este modo se llama \u00abdetached mode\u00bb.<\/p>\n<p>Las nuevas funciones de XChaCha20 son:<\/p>\n<ul>\n<li><code>sodium_crypto_stream_xchacha20_keygen<\/code>: Devuelve una clave aleatoria segura para su uso con sodium_crypto_stream_xchacha20.<\/li>\n<li><code>sodium_crypto_stream_xchacha20<\/code>: Expande la clave y el nonce en un keystream de bytes pseudoaleatorios.<\/li>\n<li><code>sodium_crypto_stream_xchacha20_xor<\/code>: Encripta un mensaje utilizando un nonce y una clave secreta (sin autenticaci\u00f3n).<\/li>\n<\/ul>\n<p>Adem\u00e1s, hay dos nuevas constantes PHP definidas en el espacio de nombres global:<\/p>\n<ul>\n<li><code>SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES<\/code> (asignado <strong>32<\/strong>)<\/li>\n<li><code>SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES<\/code> (asignado <strong>24<\/strong>)<\/li>\n<\/ul>\n<p>Sin embargo, util\u00edzalo con precauci\u00f3n. Como no hay autenticaci\u00f3n, la operaci\u00f3n de descifrado es vulnerable a los ataques comunes de texto cifrado.<\/p>\n<p>Puedes leer m\u00e1s sobre su uso y requisitos en la <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6868\">p\u00e1gina de GitHub<\/a>.<\/p>\n<h3>Nueva clase IntlDatePatternGenerator<\/h3>\n<p>La biblioteca ICU subyacente de PHP soporta la creaci\u00f3n de <a href=\"https:\/\/kinsta.com\/es\/blog\/plugin-calendario-wordpress\/\">formatos de fecha y hora<\/a> localizados, pero no es totalmente personalizable.<\/p>\n<p>Por ejemplo, si quieres crear datos y formatos de hora espec\u00edficos para cada localidad hasta PHP 8.0, puedes utilizar la <a href=\"https:\/\/www.php.net\/manual\/en\/class.intldateformatter.php\">constante predefinida IntlDateFormatter<\/a> para hacerlo de 6 maneras:<\/p>\n<ul>\n<li><strong><code>IntlDateFormatter::LONG<\/code>:<\/strong> M\u00e1s largo, como el <strong>10 de noviembre de 2017 <\/strong>o <strong>las 23:22:33<\/strong><\/li>\n<li><strong><code>IntlDateFormatter::MEDIUM<\/code>:<\/strong> Un poco m\u00e1s corto, como el <strong>10 de noviembre de 2017<\/strong><\/li>\n<li><strong><code>IntlDateFormatter::SHORT<\/code>:<\/strong> Solo num\u00e9rico, como <strong>10\/11\/17 <\/strong>o <strong>11:22pm<\/strong><\/li>\n<\/ul>\n<p>Cada uno de ellos tiene tambi\u00e9n sus propias variantes <code>RELATIVE_<\/code>, que establece el formato de la fecha dentro de un rango limitado antes o despu\u00e9s de la fecha actual. En PHP, los valores son <strong>ayer<\/strong>, <strong>hoy <\/strong>y <strong>ma\u00f1ana<\/strong>.<\/p>\n<p>Digamos que quieres usar la versi\u00f3n larga para el a\u00f1o y la versi\u00f3n corta para el mes, como <strong>10\/11\/2017<\/strong>. A partir de PHP 8.0, no se puede.<\/p>\n<p>En PHP 8.1+, puedes especificar qu\u00e9 formatos usar para la fecha, el mes y la hora con la nueva clase <strong>IntlDatePatternGenerator<\/strong>. Puedes dejar el orden exacto de estos componentes al formateador.<\/p>\n<p>Debes tener en cuenta que aunque esta clase solo tiene la palabra <strong>Date <\/strong>en ella, es consistente con el <strong>DateTimePatternGenerator <\/strong>de ICU. Esto significa que tambi\u00e9n puedes usarlo para crear formatos de tiempo flexibles. Para simplificar la nomenclatura, el equipo de PHP ha optado por el t\u00e9rmino m\u00e1s corto <strong>IntlDatePatternGenerator<\/strong>.<\/p>\n<p>He aqu\u00ed un ejemplo extra\u00eddo directamente de <a href=\"https:\/\/wiki.php.net\/rfc\/intldatetimepatterngenerator\">su RFC<\/a>:<\/p>\n<pre><code class=\"language-php\">$skeleton = \"YYYYMMdd\";\n \n$today = \\DateTimeImmutable::createFromFormat('Y-m-d', '2021-04-24');\n \n$dtpg = new \\IntlDatePatternGenerator(\"de_DE\");\n$pattern = $dtpg-&gt;getBestPattern($skeleton);\necho \"de: \", \\IntlDateFormatter::formatObject($today, $pattern, \"de_DE\"), \"\\n\";\n \n$dtpg = new \\IntlDatePatternGenerator(\"en_US\");\n$pattern = $dtpg-&gt;getBestPattern($skeleton), \"\\n\";\necho \"en: \", \\IntlDateFormatter::formatObject($today, $pattern, \"en_US\"), \"\\n\";\n \n\/*\nde: 24.04.2021\nen: 04\/24\/2021\n*\/<\/code><\/pre>\n<p>En el c\u00f3digo anterior, la variable <strong>skeleton <\/strong>define los formatos particulares de fecha u hora a utilizar. Sin embargo, el formateador maneja el orden del resultado final.<\/p>\n<h3>Compatibilidad con el formato de imagen AVIF<\/h3>\n<p>El AVIF, o Formato de Archivo de Imagen AV1, es un <a href=\"https:\/\/kinsta.com\/es\/blog\/tipos-de-archivos-de-imagen\/\">formato de imagen<\/a> relativamente nuevo y libre de derechos basado en el formato de codificaci\u00f3n de v\u00eddeo AV1. Adem\u00e1s de ofrecer una mayor compresi\u00f3n (y, por tanto, un menor tama\u00f1o de los archivos), tambi\u00e9n admite varias funciones, como la transparencia y el HDR, entre otras.<\/p>\n<p>El formato AVIF ha sido <a href=\"https:\/\/aomediacodec.github.io\/av1-avif\/\">estandarizado recientemente<\/a> (8 de junio de 2021). Esto ha allanado el camino para que los navegadores, como Chrome 85+ y Firefox 86+, a\u00f1adan compatibilidad con las im\u00e1genes AVIF.<\/p>\n<p>La extensi\u00f3n de procesamiento de im\u00e1genes y GD de PHP 8.1 a\u00f1ade soporte para im\u00e1genes AVIF.<\/p>\n<p>Sin embargo, para incluir esta funcionalidad, necesitas compilar la extensi\u00f3n GD con soporte AVIF. Puedes hacerlo ejecutando los siguientes comandos.<\/p>\n<p>Para Debian\/Ubuntu:<\/p>\n<pre><code class=\"language-bash\">apt install libavif-dev<\/code><\/pre>\n<p>Para Fedora\/RHEL:<\/p>\n<pre><code class=\"language-bash\">dnf install libavif-devel<\/code><\/pre>\n<p>Eso instalar\u00e1 todas las dependencias m\u00e1s recientes. A continuaci\u00f3n, puedes compilar el soporte de AVIF ejecutando la bandera <code>--with-avif<\/code> con el script <code>. \/configure<\/code>.<\/p>\n<pre><code class=\"language-bash\">.\/buildconf --force\n.\/configure --enable-gd --with-avif<\/code><\/pre>\n<p>Si est\u00e1s empezando un nuevo entorno desde cero, tambi\u00e9n puedes habilitar otras extensiones de PHP aqu\u00ed.<\/p>\n<p>Una vez instalado, puedes comprobar si el soporte de AVIF est\u00e1 activado ejecutando el siguiente comando en tu terminal de PHP:<\/p>\n<pre><code class=\"language-bash\">php -i | grep AVIF<\/code><\/pre>\n<p>Si has instalado AVIF correctamente, ver\u00e1s el siguiente resultado:<\/p>\n<pre><code class=\"language-bash\">AVIF Support =&gt; enabled<\/code><\/pre>\n<p>Tambi\u00e9n puedes utilizar la llamada <code>gd_info()<\/code> para obtener una lista de las caracter\u00edsticas de GD, incluyendo si la funcionalidad de<strong> soporte AVIF <\/strong>est\u00e1 activada.<\/p>\n<p>Esta extensi\u00f3n GD de PHP 8.1 actualizada tambi\u00e9n a\u00f1ade dos nuevas funciones para trabajar con im\u00e1genes AVIF: <code>imagecreatefromavif<\/code> y\u00a0<code>imageavif<\/code>. Funcionan de forma similar a sus hom\u00f3logas JPEG y PNG.<\/p>\n<p>La funci\u00f3n <code>imagecreatefromavif<\/code> devuelve una instancia de GdImage a partir de una imagen AVIF dada. A continuaci\u00f3n, puedes utilizar esta instancia para editar o convertir la imagen.<\/p>\n<p>La otra funci\u00f3n <code>imageavif<\/code> produce el archivo de imagen AVIF. Por ejemplo, puede utilizarla para convertir un JPEG en AVIF:<\/p>\n<pre><code class=\"language-php\">$image = imagecreatefromjpeg('image.jpeg');\nimageavif($image, 'image.avif');<\/code><\/pre>\n<p>Puedes leer m\u00e1s sobre esta nueva funci\u00f3n en <a href=\"https:\/\/github.com\/php\/php-src\/pull\/7026\">su p\u00e1gina de GitHub<\/a>.<\/p>\n<h3><strong>Nueva clave<\/strong>\u00a0<code>$_FILES: full_path<\/code> <strong>para subir directorios<\/strong><\/h3>\n<p>PHP mantiene un gran n\u00famero de variables predefinidas para controlar varias cosas. Una de ellas es la <a href=\"https:\/\/www.php.net\/manual\/en\/reserved.variables.files.php\">variable $_FILES<\/a> que contiene una matriz asociativa de elementos cargados a trav\u00e9s del m\u00e9todo HTTP POST.<\/p>\n<p>La mayor\u00eda de los navegadores modernos soportan la <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Element\/input\/file#htmlattrdefwebkitdirectory_non-standard_inline\">carga de un directorio completo<\/a> con campos de <a href=\"https:\/\/kinsta.com\/es\/blog\/como-subir-un-archivo-html-a-wordpress\/\">carga de archivos HTML<\/a>. Incluso PHP &lt;8.1 soportaba esta funcionalidad, pero con una gran advertencia. No se pod\u00eda subir una carpeta con su estructura exacta de directorios o rutas relativas porque PHP no pasaba esta informaci\u00f3n al array <code>$_FILES<\/code>.<\/p>\n<p>Esto cambia en PHP 8.1 con la adici\u00f3n de una nueva clave llamada <code>full_path<\/code> al array <code>$_FILES<\/code>. Usando estos nuevos datos, puedes almacenar rutas relativas o duplicar la estructura exacta de directorios en el servidor.<\/p>\n<p>Puedes comprobar esta informaci\u00f3n mostrando la matriz <code>$FILES<\/code> mediante el comando <code>var_dump($_FILES)<\/code>;.<\/p>\n<p>Sin embargo, procede con precauci\u00f3n si utilizs esta funci\u00f3n. Aseg\u00farate de protegerte contra <a href=\"https:\/\/php.watch\/versions\/8.1\/$_FILES-full-path#security-hardening\">los ataques est\u00e1ndar de carga de archivos<\/a>.<\/p>\n<h3>Soporte de desempaquetado de matrices para String-Keyed Arrays<\/h3>\n<p>PHP 7.4 ha a\u00f1adido <a href=\"https:\/\/kinsta.com\/es\/blog\/php-7-4\/#array-spread-operator\">soporte para el desempaquetado de arrays<\/a> con el operador de dispersi\u00f3n de arrays (<strong>&#8230; <\/strong>). Act\u00faa como una alternativa m\u00e1s r\u00e1pida al uso de la funci\u00f3n <code>array_merge()<\/code>. Sin embargo, esta caracter\u00edstica estaba limitada a arrays con claves num\u00e9ricas, ya que desempaquetar arrays con claves de cadena causaba conflictos al fusionar arrays con claves duplicadas.<\/p>\n<p>Sin embargo, PHP 8 a\u00f1adi\u00f3 <a href=\"https:\/\/kinsta.com\/es\/blog\/php-8\/#named-arguments\">soporte para argumentos con nombre<\/a>, eliminando esta limitaci\u00f3n. Por lo tanto, el desempaquetado de arrays ahora tambi\u00e9n soportar\u00e1 \u00a0stringed-key arrays utilizando la misma sintaxis:<\/p>\n<pre><code class=\"language-php\">$array = [...$array1, ...$array2];<\/code><\/pre>\n<p>Este <a href=\"https:\/\/wiki.php.net\/rfc\/array_unpacking_string_keys\">ejemplo RFC<\/a> ilustra c\u00f3mo se maneja la fusi\u00f3n de arrays con claves de cadena duplicadas en PHP 8.1:<\/p>\n<pre><code class=\"language-php\">$array1 = [\"a\" =&gt; 1];\n$array2 = [\"a\" =&gt; 2];\n$array = [\"a\" =&gt; 0, ...$array1, ...$array2];\nvar_dump($array); \/\/ [\"a\" =&gt; 2]<\/code><\/pre>\n<p>Aqu\u00ed, la clave de la cadena \u00aba\u00bb aparece tres veces antes de la fusi\u00f3n a trav\u00e9s de la descomposici\u00f3n de la matriz. Pero solo gana su \u00faltimo valor perteneciente a <code>$array2<\/code>.<\/p>\n<h3>Notaci\u00f3n expl\u00edcita de n\u00fameros octales<\/h3>\n<p>PHP soporta varios sistemas num\u00e9ricos, incluyendo el decimal (base-10), el binario (base-2), el octal (base-8) y el hexadecimal (base-16). El sistema num\u00e9rico decimal es el predeterminado.<\/p>\n<p>Si quieres utilizar cualquier otro sistema num\u00e9rico, tendr\u00e1s que anteponer a cada n\u00famero un prefijo est\u00e1ndar:<\/p>\n<ul>\n<li><strong>Hex: <\/strong>prefijo <code>0x<\/code> (por ejemplo 17 = <code>0x11<\/code>)<\/li>\n<li><strong>Binary: <\/strong>prefijo <code>0b<\/code> (por ejemplo 3 = <code>0b11<\/code>)<\/li>\n<li><strong>Octal: <\/strong>prefijo\u00a0<code>0<\/code> (por ejemplo 9 = <code>011<\/code>)<\/li>\n<\/ul>\n<p>Puedes ver c\u00f3mo el prefijo del sistema num\u00e9rico octal var\u00eda del resto. Para estandarizar esta cuesti\u00f3n, muchos lenguajes de programaci\u00f3n est\u00e1n a\u00f1adiendo soporte para una notaci\u00f3n num\u00e9rica octal expl\u00edcita: <code>0o<\/code> o <code>0O<\/code>.<\/p>\n<p>A partir de PHP 8.1, puedes escribir el ejemplo mostrado arriba (es decir, el n\u00famero 9 en base-10) en el sistema num\u00e9rico octal como <code>0o11<\/code> o <code>0O11<\/code>.<\/p>\n<pre><code class=\"language-php\">0o16 === 14; \/\/ true\n0o123 === 83; \/\/ true\n \n0O16 === 14; \/\/ true\n0O123 === 83; \/\/ true\n \n016 === 0o16; \/\/ true\n016 === 0O16; \/\/ true<\/code><\/pre>\n<p>Adem\u00e1s, esta nueva caracter\u00edstica tambi\u00e9n funciona con el <a href=\"https:\/\/wiki.php.net\/rfc\/numeric_literal_separator\">separador num\u00e9rico literal de gui\u00f3n bajo <\/a>introducido en PHP 7.4.<\/p>\n<p>Lee m\u00e1s sobre esta nueva caracter\u00edstica de PHP 8.1 en <a href=\"https:\/\/wiki.php.net\/rfc\/explicit_octal_notation\">su RFC<\/a>.<\/p>\n<h3>Soporte de los algoritmos Hash MurmurHash3 y xxHash<\/h3>\n<p>PHP 8.1 a\u00f1ade soporte para los algoritmos de hash MurmurHash3 y xxHash. No est\u00e1n dise\u00f1ados para su uso criptogr\u00e1fico, pero a\u00fan as\u00ed proporcionan una impresionante aleatoriedad, dispersi\u00f3n y unicidad de salida.<\/p>\n<p>Estos <a href=\"https:\/\/php.watch\/articles\/php-hash-benchmark\">nuevos algoritmos de hashing son m\u00e1s r\u00e1pidos<\/a> que la mayor\u00eda de los algoritmos de hashing existentes en PHP. De hecho, algunas de las variantes de estos algoritmos hash son m\u00e1s r\u00e1pidas que el rendimiento de la memoria RAM.<\/p>\n<p>Como PHP 8.1 tambi\u00e9n a\u00f1ade soporte para declarar par\u00e1metros <code>$options<\/code> espec\u00edficos para cada algoritmo, puede hacer lo mismo con estos nuevos algoritmos. El valor por defecto de este nuevo argumento es <code>[]<\/code>. Por lo tanto, no afectar\u00e1 a ninguna de nuestras funciones hash existentes.<\/p>\n<p>Puedes leer m\u00e1s sobre estas nuevas caracter\u00edsticas de PHP 8.1 en sus p\u00e1ginas de GitHub: <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6059\">MurmurHash3<\/a>, <a href=\"https:\/\/php.watch\/versions\/8.1\/xxHash\">xxHash<\/a>, <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6400\">Algorithm-specific $options<\/a>.<\/p>\n<h3>Soporte de DNS sobre HTTPS (DoH)<\/h3>\n<p>DNS-over-HTTPS (DoH) es un protocolo para la resoluci\u00f3n de <a href=\"https:\/\/kinsta.com\/es\/blog\/que-es-dns\/\">DNS<\/a> a trav\u00e9s del protocolo HTTPS. Al utilizar HTTPS para cifrar los datos entre el cliente y el resolvedor de DNS, DoH aumenta la privacidad y la seguridad del usuario al evitar los ataques MitM.<\/p>\n<p>A partir de PHP 8.1, puedes <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6612\">utilizar la extensi\u00f3n Curl para especificar un servidor DoH<\/a>. Requiere que PHP sea compilado con versiones <strong>libcurl <\/strong>7.62+. Esto no es un problema para los sistemas operativos m\u00e1s populares, incluyendo las distros de Linux, ya que suelen incluir Curl 7.68+.<\/p>\n<p>Puedes configurar la URL del servidor de DoH especificando la opci\u00f3n <code>CURLOPT_DOH_URL<\/code>.<\/p>\n<pre><code class=\"language-php\">$doh = curl_init('https:\/\/kinsta.com');\ncurl_setopt($doh, CURLOPT_DOH_URL, 'https:\/\/dns.google\/dns-query');\ncurl_exec($doh);<\/code><\/pre>\n<p>En el ejemplo anterior, hemos utilizado el servidor DNS p\u00fablico de Google. Adem\u00e1s, observa el uso de <code>https:\/\/<\/code> en todas las URLs utilizadas. Aseg\u00farete de configurar esto perfectamente, ya que no hay ning\u00fan servidor DNS por defecto al que recurrir en Curl.<\/p>\n<p>Tambi\u00e9n puedes elegir de <a href=\"https:\/\/github.com\/curl\/curl\/wiki\/DNS-over-HTTPS\">una lista de servidores DoH p\u00fablicos<\/a> incluidos en la documentaci\u00f3n de Curl.<\/p>\n<p>Adem\u00e1s, la <a href=\"https:\/\/curl.se\/libcurl\/c\/CURLOPT_DOH_URL.html\">referencia CURLOPT_DOH_URL<\/a> de la documentaci\u00f3n de Curl explica detalladamente c\u00f3mo utilizar sus distintos argumentos.<\/p>\n<h3>Subida de archivos desde Stringscon CURLStringFile<\/h3>\n<p>La extensi\u00f3n Curl de PHP soporta peticiones <a href=\"https:\/\/kinsta.com\/es\/blog\/redireccion-http-a-https\/\">HTTP(S<\/a>) con carga de archivos. Para ello utiliza la clase <strong>CURLFile<\/strong>, que acepta una URI o una ruta de archivo, un tipo mime y el nombre final del archivo.<\/p>\n<p>Sin embargo, con la clase <strong>CURLFile<\/strong>, solo se puede aceptar la ruta del archivo o URI, pero no el contenido del propio archivo. En los casos en los que ya se ten\u00eda el archivo que se cargaba en la memoria (por ejemplo, im\u00e1genes procesadas, documentos XML, PDF), hab\u00eda que utilizar <code>data:\/\/<\/code> URI con codificaci\u00f3n Base64.<\/p>\n<p>Pero <strong>libcurl <\/strong>ya soporta una forma m\u00e1s sencilla de aceptar el contenido del archivo. La nueva clase <strong>CURLStringFile <\/strong>a\u00f1ade soporte precisamente para eso.<\/p>\n<p>Puedes <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6456\">leer su p\u00e1gina de GitHub<\/a> para saber m\u00e1s sobre c\u00f3mo est\u00e1 implementado en PHP 8.1.<\/p>\n<h3><strong>Nueva constante<\/strong>\u00a0<code>MYSQLI_REFRESH_REPLICA<\/code><\/h3>\n<p>La extensi\u00f3n <strong>mysqli <\/strong>de PHP 8.1 a\u00f1ade una nueva constante llamada <code>MYSQLI_REFRESH_REPLICA<\/code>. Es equivalente a la constante existente <code>MYSQLI_REFRESH_SLAVE<\/code>.<\/p>\n<p>Este cambio fue bienvenido en <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6632\">MySQL 8.0.23<\/a> para abordar la insensibilidad racial en el vocabulario t\u00e9cnico (los ejemplos m\u00e1s comunes incluyen \u00abesclavo\u00bb y \u00abmaestro\u00bb).<\/p>\n<p>Hay que tener en cuenta que la constante m\u00e1s antigua no est\u00e1 siendo eliminada o desaprobada. Los desarrolladores y las aplicaciones pueden seguir utiliz\u00e1ndola. Esta nueva constante no es m\u00e1s que una opci\u00f3n para los desarrolladores y empresas que deseen dejar atr\u00e1s dicha terminolog\u00eda.<\/p>\n<h3>Mejoras de rendimiento con Inheritance Cache<\/h3>\n<p><a href=\"https:\/\/github.com\/php\/php-src\/commit\/4b79dba93202ed5640dff317046ce2fdd42e1d82\">Inheritance Cache<\/a> es una nueva adici\u00f3n a opcache que elimina la sobrecarga de la herencia de clases de PHP.<\/p>\n<p>Las clases de PHP son compiladas y almacenadas <a href=\"https:\/\/kinsta.com\/es\/blog\/que-es-la-cache\/\">en cach\u00e9<\/a> por opcache por separado. Sin embargo, ya est\u00e1n enlazadas en tiempo de ejecuci\u00f3n en cada petici\u00f3n. Este proceso puede implicar varias comprobaciones de compatibilidad y el pr\u00e9stamo de m\u00e9todos\/propiedades\/constantes de las clases padre y los traits.<\/p>\n<p>En consecuencia, se tarda mucho tiempo en ejecutarlo, aunque el resultado sea el mismo para cada solicitud.<\/p>\n<p>Inheritance Cache enlaza todas las clases dependientes \u00fanicas (padre, interfaces, rasgos, tipos de propiedades, m\u00e9todos) y almacena los resultados en la memoria compartida opcache. Como ahora esto solo ocurre una vez, la herencia requiere menos instrucciones.<\/p>\n<p>Adem\u00e1s, elimina las limitaciones de las clases inmutables, como las constantes no resueltas, las propiedades tipadas y las comprobaciones de tipos covariantes. As\u00ed, todas las clases almacenadas en opcache son inmutables, lo que reduce a\u00fan m\u00e1s el n\u00famero de instrucciones necesarias.<\/p>\n<p>En definitiva, promete importantes beneficios de rendimiento. <a href=\"https:\/\/github.com\/dstogov\">Dimitry Stogov<\/a>, el autor de este parche, descubri\u00f3 que mostraba una mejora del 8% en el programa base de Symfony \u00abHello, World!\u00bb. No podemos esperar a probarlo en nuestros siguientes <a href=\"https:\/\/kinsta.com\/es\/blog\/puntos-de-referencia-php\/\">benchmarks de PHP<\/a>.<\/p>\n<h3>Sintaxis de llamada de primera clase<\/h3>\n<p>PHP 8.1 a\u00f1ade una sintaxis de llamada de primera clase para reemplazar las codificaciones existentes que utilizan cadenas y arrays. Adem\u00e1s de crear un <strong>Closure <\/strong>m\u00e1s limpio, esta nueva sintaxis tambi\u00e9n es accesible por las <a href=\"https:\/\/kinsta.com\/es\/blog\/herramientas-de-revision-de-codigo\/\">herramientas de an\u00e1lisis<\/a> est\u00e1tico y respeta el \u00e1mbito declarado.<\/p>\n<p>He aqu\u00ed algunos ejemplos extra\u00eddos <a href=\"https:\/\/wiki.php.net\/rfc\/first_class_callable_syntax\">del RFC<\/a>:<\/p>\n<pre><code class=\"language-php\">$fn = Closure::fromCallable('strlen');\n$fn = strlen(...);\n \n$fn = Closure::fromCallable([$this, 'method']);\n$fn = $this-&gt;method(...)\n \n$fn = Closure::fromCallable([Foo::class, 'method']);\n$fn = Foo::method(...);<\/code><\/pre>\n<p>Aqu\u00ed, todos los pares de expresiones son equivalentes. La sintaxis de triple punto (<strong>&#8230;<\/strong>) es similar a la sintaxis de desempaquetado de argumentos (<code>...$args<\/code>). Excepto que aqu\u00ed, los argumentos a\u00fan no est\u00e1n rellenados.<\/p>\n<h2>Cambios en PHP 8.1<\/h2>\n<p>PHP 8.1 tambi\u00e9n incluye cambios en su sintaxis y caracter\u00edsticas existentes. Vamos a discutirlos:<\/p>\n<div><\/div><kinsta-auto-toc list-style=\"disc\" selector=\"h3\" count-number=\"7\" sub-toc=\"true\"><\/kinsta-auto-toc>\n<h3>El shell interactivo de PHP requiere la extensi\u00f3n readline<\/h3>\n<p>La extensi\u00f3n <strong>readline <\/strong>de PHP permite funciones <a href=\"https:\/\/kinsta.com\/es\/blog\/guia-desarrollador-usar-ssh\/\">interactivas del shell como<\/a> la navegaci\u00f3n, el autocompletado, la edici\u00f3n y otras. Aunque viene incluida en PHP, no est\u00e1 activada por defecto.<\/p>\n<p>Puedes acceder al shell interactivo de PHP usando la opci\u00f3n de l\u00ednea de comandos <code>-a<\/code> de PHP CLI:<\/p>\n<pre><code class=\"language-php\">php -a\n\nInteractive shell\n\nphp &gt;\nphp &gt; echo \"Hello\";\nHello\nphp &gt; function test() {\nphp { echo \"Hello\";\nphp { }\nphp &gt; test();\nHello<\/code><\/pre>\n<p>Antes de PHP 8.1, se pod\u00eda abrir el shell interactivo usando PHP CLI incluso sin la extensi\u00f3n <strong>readline <\/strong>habilitada. Como era de esperar, las caracter\u00edsticas interactivas del shell no funcionaban, haciendo que la opci\u00f3n <code>-a<\/code> no tuviera sentido.<\/p>\n<p>En PHP 8.1 CLI, el shell interactivo sale con un mensaje de error si <a href=\"https:\/\/github.com\/php\/php-src\/commit\/959e5787bdf7c088a57dce5f4f7570abd7fe35f8\">no se ha habilitado la extensi\u00f3n readline<\/a>.<\/p>\n<pre><code class=\"language-php\">php -a\nInteractive shell (-a) requires the readline extension.<\/code><\/pre>\n<h3>El modo de error por defecto de MySQLi es el de las excepciones<\/h3>\n<p>Antes de PHP 8.1, <a href=\"https:\/\/kinsta.com\/es\/blog\/que-es-mysql\/\">MySQLi<\/a> silenciaba por defecto los errores. Este comportamiento a menudo conduc\u00eda a c\u00f3digo que no segu\u00eda un manejo estricto de Errores\/Excepciones. Los desarrolladores ten\u00edan que implementar sus propias funciones expl\u00edcitas de manejo de errores.<\/p>\n<p>PHP 8.1 cambia este comportamiento estableciendo el modo de reporte de errores por defecto de MySQLi para lanzar una excepci\u00f3n.<\/p>\n<pre><code class=\"language-php\">Fatal error: Uncaught mysqli_sql_exception: Connection refused in ...:...<\/code><\/pre>\n<p>Como se trata de un cambio de ruptura, para las versiones de PHP &lt;8.1, debe establecer expl\u00edcitamente el modo de manejo de errores utilizando la funci\u00f3n <code>mysqli_report<\/code> antes de realizar la primera conexi\u00f3n de MySQLi. Alternativamente, puede hacer lo mismo seleccionando el valor de reporte de errores al instanciar una instancia de <code>mysqli_driver<\/code>.<\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/mysqli_default_errmode\">La RFC<\/a> sigue un <a href=\"https:\/\/wiki.php.net\/rfc\/pdo_default_errmode\">cambio similar introducido en PHP 8.0<\/a>.<\/p>\n<h3>Finales de l\u00ednea personalizables para las funciones de escritura de CSV<\/h3>\n<p>Antes de PHP 8.1, las funciones de escritura <a href=\"https:\/\/kinsta.com\/changelog\/export-redirects-csv\/\">CSV<\/a> incorporadas en PHP, <code>fputcsv<\/code> y <code>SplFileObject::fputcsv<\/code>, estaban codificadas para a\u00f1adir <code>\\n<\/code> (o el car\u00e1cter Line-Feed) al final de cada l\u00ednea.<\/p>\n<p>PHP 8.1 a\u00f1ade soporte para un nuevo par\u00e1metro llamado <code>eol<\/code> a estas funciones. Puedes usarlo para pasar un car\u00e1cter de fin de l\u00ednea configurable.\u00a0 Por defecto, sigue utilizando el car\u00e1cter <code>\\n<\/code>. Por lo tanto, puede continuar us\u00e1ndolo en su c\u00f3digo existente.<\/p>\n<p>Para utilizar los caracteres de fin de l\u00ednea se aplican las reglas est\u00e1ndar de escape de caracteres. Si deseas utilizar <code>\\r<\/code>, <code>\\n<\/code>, o <code>\\r\\n<\/code> como caracteres EOL, debes encerrarlos entre comillas dobles.<\/p>\n<p>Aqu\u00ed est\u00e1 <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6403\">la p\u00e1gina de GitHub<\/a> que sigue este nuevo cambio.<\/p>\n<h3><strong>Nuevas restricciones del operador<\/strong>\u00a0<code>version_compare<\/code><\/h3>\n<p>La funci\u00f3n <code>version_compare()<\/code> de PHP compara dos cadenas de n\u00fameros de versi\u00f3n. Esta funci\u00f3n acepta un tercer argumento opcional llamado <code>operator<\/code> para probar una relaci\u00f3n particular.<\/p>\n<p>Aunque no est\u00e1 cubierto expl\u00edcitamente en la documentaci\u00f3n, antes de PHP 8.1, se pod\u00eda establecer este par\u00e1metro a un valor parcial (por ejemplo, <code>g<\/code>, <code>l<\/code>, <code>n<\/code>) sin encontrar un error.<\/p>\n<p>PHP 8.1 a\u00f1ade restricciones m\u00e1s estrictas al argumento <code>operator<\/code> de la funci\u00f3n <code>version_compare()<\/code> para superar esta situaci\u00f3n. Los \u00fanicos operadores que se pueden usar ahora son:<\/p>\n<ul>\n<li><strong>==<\/strong>, <strong>=<\/strong>, y <strong>eq<\/strong><\/li>\n<li><strong>!=<\/strong>, <strong>&lt;&gt;<\/strong>, y <strong>ne<\/strong><\/li>\n<li><strong>&gt;<\/strong> y <strong>gt<\/strong><\/li>\n<li><strong>&gt;=<\/strong> y <strong>ge<\/strong><\/li>\n<li><strong>&lt;<\/strong> y <strong>lt<\/strong><\/li>\n<li><strong>&lt;=<\/strong> y <strong>le<\/strong><\/li>\n<\/ul>\n<p><a href=\"https:\/\/github.com\/php\/php-src\/pull\/6510\">Se acabaron los valores parciales de los operadores<\/a>.<\/p>\n<h3><strong>Las funciones de codificaci\u00f3n y descodificaci\u00f3n de HTML utilizan ahora<\/strong>\u00a0<code>ENT_QUOTES | ENT_SUBSTITUTE<\/code><\/h3>\n<p>Las entidades HTML son representaciones textuales de caracteres que de otro modo se interpretar\u00edan como HTML. Piensa en caracteres como <code>&lt;<\/code> y <code>&gt;<\/code> utilizados para <a href=\"https:\/\/kinsta.com\/es\/blog\/mejores-practicas-html\/\">definir etiquetas HTML<\/a> (por ejemplo, <code>&lt;a&gt;<\/code>, <code>&lt;h3&gt;<\/code>, <code>&lt;script&gt;<\/code>).<\/p>\n<p>La entidad HTML para <code>&lt;<\/code> es <code>&lt<\/code>; (s\u00edmbolo menor que) y <code>&gt;<\/code> es <code>&gt<\/code>; (s\u00edmbolo mayor que).<\/p>\n<p><strong>Nota:<\/strong> Elimina el espacio entre \u00ab&#038;\u00bb y \u00abamp\u00bb.<\/p>\n<p>Puedes utilizar estas entidades HTML de forma segura en un documento HTML sin activar el motor de renderizado del navegador.<\/p>\n<p>Por ejemplo, <code>& lt;script&gt<\/code>; se mostrar\u00e1 como <code>&lt;script&gt;<\/code> en el navegador, en lugar de ser interpretado como una etiqueta HTML.<\/p>\n<p>Antes de PHP 8.1, las funciones <a href=\"https:\/\/www.php.net\/manual\/function.htmlspecialchars.php\">htmlspecialchars()<\/a> y <a href=\"https:\/\/www.php.net\/manual\/en\/function.htmlentities.php\">htmlentities()<\/a> convert\u00edan s\u00edmbolos como <code><strong>\"<\/strong><\/code>, <code>&lt;<\/code> , <code>&gt;<\/code> , y <code>&<\/code> a sus respectivas entidades HTML. Pero no convert\u00edan el car\u00e1cter de comilla simple (<code><strong>'<\/strong><\/code>) a su entidad HTML por defecto. Adem\u00e1s, devolv\u00edan una cadena vac\u00eda si hab\u00eda un UTF-8 malformado en el texto.<\/p>\n<p>En PHP 8.1., estas funciones de codificaci\u00f3n y decodificaci\u00f3n HTML (y sus funciones relacionadas) tambi\u00e9n <a href=\"https:\/\/github.com\/php\/php-src\/commit\/50eca61f68815005f3b0f808578cc1ce3b4297f0\">convertir\u00e1n los caracteres de comillas simples<\/a> a su entidad HTML por defecto.<\/p>\n<p>Y si el texto dado tiene caracteres inv\u00e1lidos, las funciones los sustituir\u00e1n con un car\u00e1cter de sustituci\u00f3n Unicode (\ufffd) en lugar de devolver una cadena vac\u00eda. PHP 8.1 logra esto cambiando las firmas de estas funciones a <code>ENT_QUOTES | ENT_SUBSTITUTE<\/code> en lugar de <code>ENT_COMPAT<\/code> por defecto.<\/p>\n<p>La mayor\u00eda de los frameworks ya utilizan <code>ENT_QUOTES<\/code> como valor de bandera por defecto. Por lo tanto, no ver\u00e1s mucha diferencia debido a este cambio. Sin embargo, la nueva bandera <code>ENT_SUBSTITUTE<\/code> no es tan utilizada. PHP 8.1 har\u00e1 que los caracteres UTF-8 inv\u00e1lidos sean sustituidos por el car\u00e1cter \ufffd en lugar de devolver una cadena vac\u00eda.<\/p>\n<h3>Advertencia sobre llamadas a funciones compactas ilegales<\/h3>\n<p>La funci\u00f3n <code>compact()<\/code> de PHP es muy \u00fatil. Puedes usarla para crear un array con variables usando sus nombres y valores.<\/p>\n<p>Por ejemplo, considere el siguiente c\u00f3digo:<\/p>\n<pre><code class=\"language-php\">$animal = 'Cat';\n$sound = 'Meow';\n$region = 'Istanbul';\ncompact('animal', 'sound', 'region');\n\/\/ ['animal' =&gt; \"Cat\", 'sound' =&gt; \"Meow\", 'region' =&gt; \"Istanbul\"]<\/code><\/pre>\n<p>La <a href=\"https:\/\/www.php.net\/manual\/en\/function.compact.php\">documentaci\u00f3n de la funci\u00f3n compacta<\/a> indica que solo aceptar\u00e1 par\u00e1metros de cadena o valores de matriz con valores de cadena. Sin embargo, antes de PHP 7.3, cualquier cadena que no se establezca ser\u00e1 omitida silenciosamente.<\/p>\n<p>PHP 7.3 modific\u00f3 la funci\u00f3n <code>compact()<\/code> para lanzar un aviso si se utilizan variables no definidas. <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6921\">PHP 8.1 da un paso m\u00e1s<\/a> y lanza una advertencia.<\/p>\n<p>Puedes <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6921\">leer su p\u00e1gina de GitHub<\/a> para entender c\u00f3mo se produjo este cambio.<\/p>\n<h3>Nuevas migraciones de recursos a objetos de clase<\/h3>\n<p>Uno de los objetivos a largo plazo de PHP es alejarse <a href=\"https:\/\/php.watch\/articles\/resource-object\">de los recursos hacia los objetos de clase est\u00e1ndar<\/a>.<\/p>\n<p>Debido a razones hist\u00f3ricas, los objetos de recursos se utilizan ampliamente en las aplicaciones PHP. Por lo tanto, la migraci\u00f3n de recursos a objetos de clase debe ser lo menos perjudicial posible. PHP 8.1 migra cinco de estos recursos:<\/p>\n<h4><strong>El recurso<\/strong>\u00a0<code>file_info<\/code> <strong>migrado a los objetos<\/strong>\u00a0<code>finfo<\/code><\/h4>\n<p>La clase <a href=\"https:\/\/www.php.net\/manual\/en\/class.finfo.php\">finfo<\/a> de PHP ofrece una interfaz <a href=\"https:\/\/kinsta.com\/es\/blog\/programacion-orientada-objetos-python\/#what-is-objectoriented-programming-in-python\">orientada a objetos<\/a> para las funciones <code>fileinfo<\/code>. Sin embargo, el uso de las funciones <code>finfo<\/code> devuelve objetos de <code>resource<\/code> con el tipo <code>file_info<\/code> en lugar de una instancia de la propia clase <code>finfo<\/code>.<\/p>\n<p><a href=\"https:\/\/github.com\/php\/php-src\/pull\/5987\">PHP 8.1 corrige esta anomal\u00eda<\/a>.<\/p>\n<h4>Recursos IMAP migrados a objetos de clase <code>IMAP\\Connection<\/code><\/h4>\n<p>En l\u00ednea con el objetivo de migraci\u00f3n de recursos a objetos, la nueva clase <code>IMAP\\Connection<\/code> minimiza los posibles cambios de ruptura cuando PHP modifique eventualmente los detalles de implementaci\u00f3n de la clase.<\/p>\n<p>Esta nueva clase tambi\u00e9n est\u00e1 declarada como <code>final<\/code>, por lo que no se puede <code>extend<\/code>.<\/p>\n<p>Lee m\u00e1s sobre su implementaci\u00f3n en <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6418\">su p\u00e1gina de GitHub<\/a>.<\/p>\n<h4>Los recursos de conexi\u00f3n FTP son ahora objetos de clase <code>FTP\\Connection<\/code><\/h4>\n<p>En PHP &lt;8.1, si crea una <a href=\"https:\/\/kinsta.com\/es\/blog\/mejores-clientes-ftp\/\">conexi\u00f3n FTP<\/a> con las funciones <code>ftp_connect()<\/code> o <code>ftp_ssl_connect()<\/code>, obtendr\u00e1 un objeto <strong>recurso <\/strong>de tipo <strong>ftp<\/strong>.<\/p>\n<p>PHP 8.1 a\u00f1ade la nueva clase <code>FTP\\Connection<\/code> para rectificar eso. Y al igual que la clase <code>IMAPConnection<\/code>, tambi\u00e9n se declara <code>final<\/code> para evitar que se extienda.<\/p>\n<p>Lee m\u00e1s sobre esta migraci\u00f3n en <a href=\"https:\/\/github.com\/php\/php-src\/commit\/bc40bce868e208fa2d7af950845759d3ef498b5d\">su p\u00e1gina de GitHub<\/a>.<\/p>\n<h4>Identificadores de fuentes migrados a los objetos de la clase <code>GdFont<\/code><\/h4>\n<p>La extensi\u00f3n GD de PHP proporciona la <a href=\"https:\/\/www.php.net\/manual\/en\/function.imageloadfont.php\">funci\u00f3n imageloadfont()<\/a> para cargar un mapa de bits definido por el usuario y devolver su identificador de fuente (un entero).<\/p>\n<p>En PHP 8.1, esta funci\u00f3n devolver\u00e1 una instancia de la clase <strong>GdFont<\/strong>. Adem\u00e1s, para facilitar la migraci\u00f3n, todas las funciones que antes aceptaban un ID de recurso de<code> imageloadfont()<\/code> ahora tomar\u00e1n los nuevos objetos de la clase <strong>GdFont<\/strong>.<\/p>\n<p>Lee m\u00e1s sobre esta migraci\u00f3n en <a href=\"https:\/\/github.com\/php\/php-src\/commit\/bc40bce868e208fa2d7af950845759d3ef498b5d\">su p\u00e1gina de GitHub<\/a>.<\/p>\n<h4>Recursos LDAP migrados a objetos<\/h4>\n<p><a href=\"https:\/\/www.php.net\/manual\/en\/intro.ldap.php\">LDAP<\/a>, o Protocolo Ligero de Acceso a Directorios, se utiliza para acceder a los \u00abServidores de Directorio\u00bb. Al igual que una estructura de directorios en el disco duro, es una base de datos \u00fanica que contiene datos en una estructura de \u00e1rbol.<\/p>\n<p>PHP incluye una extensi\u00f3n LDAP que aceptaba o devolv\u00eda objetos de <strong>recursos <\/strong>antes de PHP 8.1. Sin embargo, ahora todos han migrado sin problemas a nuevas instancias de clase. Los tipos de recursos que han sido transicionados son:<\/p>\n<ul>\n<li>Recurso de <code>ldap link<\/code> a objeto de clase \u00a0<code>\\LDAP\\Connection<\/code><\/li>\n<li>Recurso de <code>ldap result<\/code> a objeto de clase <code>\\LDAP\\Result<\/code><\/li>\n<li>Recurso de <code>ldap result entry<\/code> a objeto de clase <code>\\LDAP\\ResultEntry<\/code><\/li>\n<\/ul>\n<p>Consulta <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6770\">su p\u00e1gina de GitHub<\/a> para entender mejor esta migraci\u00f3n.<\/p>\n<h4>Los recursos de Pspell son ahora objetos de clase<\/h4>\n<p>La <a href=\"https:\/\/www.php.net\/manual\/en\/intro.pspell.php\">extensi\u00f3n Pspell<\/a> de PHP permite comprobar la ortograf\u00eda y las sugerencias de palabras.<\/p>\n<p>PHP &lt;8.1 utilizaba los tipos de objetos de recurso <code>pspell<\/code> y <code>pspell config<\/code> con un identificador entero. Estos dos objetos de recurso son ahora reemplazados por objetos de clase <code>PSpell\\Dictionary<\/code> y <code>PSpell\\Config<\/code>.<\/p>\n<p>Al igual que las migraciones anteriores, <a href=\"https:\/\/php.watch\/versions\/8.1\/PSpell-resource#PSpell-Dictionary\">todas las funciones de Pspell<\/a> que antes aceptaban o devolv\u00edan identificadores de objetos de recursos tomar\u00e1n las nuevas instancias de objetos de clase.<\/p>\n<p>Consulta <a href=\"https:\/\/github.com\/php\/php-src\/commit\/bd12c94f46438dad03d1d3c02fff37b9b950ae6f\">su p\u00e1gina de GitHub<\/a> para obtener m\u00e1s informaci\u00f3n.<\/p>\n<h2>Desaprobaciones en PHP 8.1<\/h2>\n<p>PHP 8.1 deja de lado muchas de sus caracter\u00edsticas anteriores. La siguiente lista ofrece un breve resumen de las funcionalidades que han sido desaprobadas en PHP 8.1:<\/p>\n<div><\/div><kinsta-auto-toc list-style=\"disc\" selector=\"h3\" count-number=\"10\" sub-toc=\"true\"><\/kinsta-auto-toc>\n<h3>No se puede pasar <code>null<\/code> a par\u00e1metros de funciones internas no anulables<\/h3>\n<p>A partir de PHP 8.0, sus funciones internas aceptan silenciosamente valores <code>null<\/code> incluso para argumentos no anulables. Lo mismo no ocurre con las funciones definidas por el usuario: s\u00f3lo aceptan <code>null<\/code> para argumentos anulables.<\/p>\n<p>Por ejemplo, considere este uso:<\/p>\n<pre><code class=\"language-php\">var_dump(<strong>str_contains<\/strong>(\"foobar\", null));\n\/\/ bool(<strong>true<\/strong>)<\/code><\/pre>\n<p>Aqu\u00ed, el valor <code>null<\/code> se convierte silenciosamente en una cadena vac\u00eda. As\u00ed, el resultado devuelve <code>true<\/code>.<\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/deprecate_null_to_scalar_internal_arg\">Esta RFC<\/a> pretende sincronizar el comportamiento de las funciones internas lanzando una advertencia de desaprobaci\u00f3n en PHP 8.1.<\/p>\n<pre><code class=\"language-php\">var_dump(str_contains(\"foobar\", null));\n\/\/ Deprecated: Passing null to argument of type string is deprecated<\/code><\/pre>\n<p>La desaprobaci\u00f3n se convertir\u00e1 en un TypeError en la pr\u00f3xima versi\u00f3n mayor de PHP (es decir, PHP &gt;=9.0), haciendo que el comportamiento de las funciones internas sea consistente con las funciones definidas por el usuario.<\/p>\n<h3>Uso restringido de <code>$GLOBALS<\/code><\/h3>\n<p>La variable <code>$GLOBALS<\/code> de PHP proporciona una referencia directa a su tabla de s\u00edmbolos interna. Soportar esta funcionalidad es complejo y afecta al rendimiento de las operaciones de array. Adem\u00e1s, rara vez se utiliza.<\/p>\n<p>Seg\u00fan <a href=\"https:\/\/wiki.php.net\/rfc\/restrict_globals_usage\">la RFC<\/a>, ya no se permite modificar indirectamente <code>$GLOBALS<\/code>. Este cambio es incompatible con el pasado.<\/p>\n<p>El impacto de este cambio es relativamente bajo:<\/p>\n<blockquote><p><em>En los 2k paquetes m\u00e1s importantes de Composer he encontrado <\/em><a href=\"https:\/\/gist.github.com\/nikic\/9fd95866f9811b349b947f63214ad7a9\"><em>23 casos que utilizan $GLOBALS<\/em><\/a> <em>sin desferenciarlo directamente. Basado en una inspecci\u00f3n superficial, solo hay dos casos en los que <strong>$GLOBALS <\/strong>no se utiliza de forma de solo lectura.<\/em><\/p><\/blockquote>\n<p>Sin embargo, el uso de solo lectura de <code>$GLOBALS<\/code> sigue funcionando como siempre. Lo que ya no est\u00e1 soportado es la escritura en <code>$GLOBALS<\/code> como un todo. Como resultado, puede esperar un ligero <a href=\"https:\/\/kinsta.com\/es\/blog\/herramientas-pruebas-rendimiento\/\">aumento de rendimiento<\/a>, especialmente cuando se trabaja con matrices ordinarias de PHP.<\/p>\n<h3>Declaraciones de tipos de retorno para funciones internas<\/h3>\n<p>PHP 8.0 permiti\u00f3 a los desarrolladores declarar par\u00e1metros y tipos de retorno para la mayor\u00eda de las funciones y m\u00e9todos internos. Fue posible gracias a varias RFCs como <a href=\"https:\/\/kinsta.com\/es\/blog\/php-8\/#type-errors-internal-functions\">Consistent type errors for internal functions<\/a>, <a href=\"https:\/\/kinsta.com\/es\/blog\/php-8\/#union-types-2-0\">Union Types 2.0<\/a>, y <a href=\"https:\/\/wiki.php.net\/rfc\/mixed_type_v2\">Mixed Type v2<\/a>.<\/p>\n<p>Sin embargo, hay muchos casos en los que puede faltar informaci\u00f3n de tipo. Algunos de ellos incluyen un tipo con recursos, par\u00e1metros <strong>fuera<\/strong> de pass-by-ref, tipo de retorno de m\u00e9todos no finales, y funciones o m\u00e9todos que no analizan los par\u00e1metros seg\u00fan las reglas generales. Puedes leer los detalles exactos en <a href=\"https:\/\/wiki.php.net\/rfc\/internal_method_return_types\">su RFC<\/a>.<\/p>\n<p>Esta RFC solo aborda el problema del tipo de retorno de los m\u00e9todos no finales. Sin embargo, en lugar de eliminarlo por completo inmediatamente, el equipo de PHP proporciona una ruta de migraci\u00f3n gradual para actualizar sus bases de c\u00f3digo con los tipos de retorno de m\u00e9todos relevantes.<\/p>\n<p><em>Los tipos de retorno de m\u00e9todos internos no finales &#8211; cuando son posibles &#8211; se declaran de forma tentativa en PHP 8.1, y se har\u00e1n efectivos en PHP 9.0. Significa que en las versiones de PHP 8.x, se levanta un aviso de \u00abobsoleto\u00bb durante las comprobaciones de herencia cuando un m\u00e9todo interno es sobrescrito de forma que los tipos de retorno son incompatibles, y PHP 9.0 har\u00e1 que estos sean un error fatal.<\/em><\/p>\n<p>Si ves este aviso de desaprobaci\u00f3n despu\u00e9s de actualizar a PHP 8.1, aseg\u00farate de actualizar los tipos de retorno de sus m\u00e9todos.<\/p>\n<h3>Interfaz serializable desaprobada<\/h3>\n<p>PHP 7.4 introdujo el <a href=\"https:\/\/kinsta.com\/es\/blog\/php-7-4\/#serialization\">mecanismo de serializaci\u00f3n de objetos personalizado<\/a> con dos nuevos m\u00e9todos m\u00e1gicos: <code>__serialize()<\/code> y <code>__unserialize()<\/code>. Estos nuevos m\u00e9todos tienen como objetivo reemplazar la interfaz <strong>Serializable <\/strong>rota eventualmente.<\/p>\n<p>Esta <a href=\"https:\/\/wiki.php.net\/rfc\/phase_out_serializable\">RFC propone<\/a> finalizar esa decisi\u00f3n estableciendo un plan para la eventual eliminaci\u00f3n de <strong>Serializable<\/strong>.<\/p>\n<p>En PHP 8.1, si se implementa la interfaz <strong>Serializable <\/strong>sin implementar los m\u00e9todos <code>__serialize()<\/code> y <code>__unserialize()<\/code>, PHP lanzar\u00e1 una advertencia de \u00abDeprecated\u00bb.<\/p>\n<pre><code class=\"language-php\">Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in ... on line ...<\/code><\/pre>\n<p>Si est\u00e1s soportando <strong>PHP &lt;7.4 <\/strong>y <strong>PHP &gt;=7.4<\/strong>, deber\u00edas implementar tanto la interfaz <strong>Serializable <\/strong>como los nuevos m\u00e9todos m\u00e1gicos. En versiones de PHP <strong>&gt;=7.4<\/strong>, los m\u00e9todos m\u00e1gicos tendr\u00e1n prioridad.<\/p>\n<h3>Conversiones de <code>float<\/code> a <code>int<\/code> no compatibles, desaprobadas<\/h3>\n<p>PHP es un lenguaje din\u00e1micamente tipado. Como tal, hay muchos casos en los que la coerci\u00f3n de tipos ocurre naturalmente. La mayor\u00eda de estas coerciones son inofensivas y s\u00faper convenientes.<\/p>\n<p>Sin embargo, cuando un n\u00famero <strong>flotante <\/strong>se convierte en un n\u00famero <strong>entero<\/strong>, a menudo supone una p\u00e9rdida de datos. Por ejemplo, cuando el flotante <strong>3,14 <\/strong>se convierte en un entero <strong>3<\/strong>, pierde su valor fraccionario.<\/p>\n<p>Lo mismo ocurre cuando el flotador est\u00e1 fuera del rango de enteros de la plataforma, o cuando una cadena de flotadores se convierte en un entero.<\/p>\n<p>PHP 8.1 rectifica este comportamiento y pone su coerci\u00f3n de tipos din\u00e1micos m\u00e1s en l\u00ednea con la mayor\u00eda de los lenguajes de programaci\u00f3n modernos. El objetivo es que dichas coacciones sean predecibles e intuitivas.<\/p>\n<p>En PHP 8.1, ver\u00e1s un aviso de desaprobaci\u00f3n cuando un <strong>float <\/strong>no compatible es coaccionado impl\u00edcitamente a un <strong>int<\/strong>. \u00bfPero qu\u00e9 es un flotador compatible con enteros? <a href=\"https:\/\/wiki.php.net\/rfc\/implicit-float-int-deprecate\">La RFC<\/a> responde a esto:<\/p>\n<p><em>Se dice que un flotador es compatible con los enteros si posee las siguientes caracter\u00edsticas:<\/em><\/p>\n<ul>\n<li><em>Es un n\u00famero (es decir, no es NaN o Infinito)<\/em><\/li>\n<li><em>Est\u00e1 en el rango de un entero PHP (depende de la plataforma)<\/em><\/li>\n<li><em>No tiene parte fraccionaria<\/em><\/li>\n<\/ul>\n<p>Este aviso de desaprobaci\u00f3n se actualizar\u00e1 a un <strong>TypeError <\/strong>en la pr\u00f3xima versi\u00f3n mayor de PHP (es decir, PHP 9.0).<\/p>\n<h3>El m\u00e9todo <code>mysqli::get_client_info<\/code> y <code>mysqli_get_client_info($param)<\/code> est\u00e1n desaprobados<\/h3>\n<p>La API del cliente de MySQL define dos constantes: <code>client_info<\/code> (una cadena) y <code>client_version<\/code> (un int). El controlador nativo de MySQL (MySQLnd) es parte del c\u00f3digo fuente oficial de PHP y vincula estas constantes a la versi\u00f3n de PHP. En libmysql, representan la versi\u00f3n de la biblioteca cliente en el momento de la compilaci\u00f3n.<\/p>\n<p>Antes de PHP 8.1, mysqli expon\u00eda estas constantes de 4 maneras: propiedades de <code>mysqli_driver<\/code>, <strong>propiedades de <\/strong><code>mysqli<\/code>, funci\u00f3n <code>mysqli_get_client_info()<\/code>, y m\u00e9todo <code>mysqli::get_client_info<\/code>. Sin embargo, no hay un m\u00e9todo para <code>client_version<\/code>.<\/p>\n<p>MySQLnd expone estas constantes de 2 maneras a PHP: una constante y una llamada a una funci\u00f3n. Para unificar los m\u00e9todos de acceso de mysqli con estas mismas dos opciones, PHP 8.1 est\u00e1 dejando de lado estas otras dos opciones:<\/p>\n<ul>\n<li><code>get_client_info<\/code> en la clase <strong>mysqli<\/strong>. En su lugar, puede utilizar la funci\u00f3n<code> mysqli_get_client_info()<\/code>.<\/li>\n<li><code>mysqli_get_client_info()<\/code> con par\u00e1metros. Llame a la funci\u00f3n sin ning\u00fan par\u00e1metro para evitar el aviso de desaprobaci\u00f3n.<\/li>\n<\/ul>\n<p>Lee m\u00e1s sobre esta eliminaci\u00f3n en <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6777\">su p\u00e1gina de GitHub<\/a>.<\/p>\n<h3>Todas las funciones <code>mhash*()<\/code> (extensi\u00f3n hash) est\u00e1n desaprobadas<\/h3>\n<p>PHP 5.3 integr\u00f3 las funciones <code>mhash*()<\/code> en <code>ext\/hash<\/code> como una capa de compatibilidad para <code>ext\/mhash<\/code>. Posteriormente, PHP 7.0 elimin\u00f3 <code>ext\/mhash<\/code>.<\/p>\n<p>A diferencia de las funciones <code>hash_*()<\/code>, las funciones <code>mhash*()<\/code> no est\u00e1n siempre disponibles. Tienes que habilitarlas por separado mientras configura PHP.<\/p>\n<p>En PHP 7.4, la extensi\u00f3n hash fue incluida junto con PHP, haci\u00e9ndola una extensi\u00f3n por defecto para PHP. Sin embargo, todav\u00eda soportaba la opci\u00f3n <code>--enable-mhash<\/code> por razones de compatibilidad.<\/p>\n<p>El equipo de PHP ha decidido <a href=\"https:\/\/wiki.php.net\/rfc\/deprecations_php_8_1#mhash_function_family\">desaprobar las funciones mhash*()<\/a> en PHP 8.1, y eliminarlas por completo en PHP 9.0. Las funciones obsoletas son <code>mhash()<\/code>, <code>mhash_keygen_s2k()<\/code>, <code>mhash_count()<\/code>, <code>mhash_get_block_size()<\/code> y <code>mhash_get_hash_name()<\/code>. Puedes utilizar la funcionalidad est\u00e1ndar de <code>ext\/hash<\/code> en lugar de ellas.<\/p>\n<h3>Ajustes INI <code>filter.default<\/code> y <code>filter.default_options<\/code> desaprobados<\/h3>\n<p>La configuraci\u00f3n INI <code>filter.default<\/code> de PHP permite aplicar un filtro a todos los superglobales de PHP, es decir, a los datos de GPCRS (<code>$_GET<\/code>, <code>$_POST<\/code>, <code>$_COOKIE<\/code>, <code>$_REQUEST<\/code>, y <code>$_SERVER<\/code>).<\/p>\n<p>Por ejemplo, puedes establecer <code>filter.default=magic_quotes<\/code> o f<code>ilter.default=add_slashes<\/code> (seg\u00fan la versi\u00f3n de PHP) para resucitar la <a href=\"https:\/\/en.wikipedia.org\/wiki\/Magic_quotes\">controvertida e insegura funci\u00f3n de comillas m\u00e1gicas<\/a> de PHP (eliminada en PHP 5.4).<\/p>\n<p>El ajuste INI <code>filter.default<\/code> proporciona una funcionalidad adicional al permitir muchos m\u00e1s filtros, lo que lo hace a\u00fan peor. Por ejemplo, su otra opci\u00f3n &#8211; <code>filter.default=special_chars<\/code> &#8211; permite las comillas m\u00e1gicas solo para HTML. Hay mucho menos conocimiento de estos ajustes.<\/p>\n<p>PHP 8.1 <a href=\"https:\/\/wiki.php.net\/rfc\/deprecations_php_8_1#filterdefault_ini_setting\">lanzar\u00e1 una advertencia de desaprobaci\u00f3n<\/a> si <code>filter.default<\/code> se establece a cualquier valor que no sea u<code>nsafe_raw<\/code> (el predeterminado). No ver\u00e1s ning\u00fan aviso de desaprobaci\u00f3n separado para <code>filter.default_options<\/code>, pero PHP 9.0 eliminar\u00e1 ambas configuraciones INI.<\/p>\n<p>Como alternativa, puedes empezar a utilizar la funci\u00f3n <a href=\"https:\/\/www.php.net\/manual\/en\/function.filter-var.php\">filter_var()<\/a>. \u00c9sta filtra las variables con el filtro especificado.<\/p>\n<h3>Desaprobar la <code>autovivification<\/code> en falso<\/h3>\n<p>PHP permite la autovivencia (autocreaci\u00f3n de arrays a partir de valores falsos). Esta caracter\u00edstica es s\u00faper \u00fatil si la variable es indefinida.<\/p>\n<p>Sin embargo, no es ideal autocrear un array cuando el valor es falso o nulo.<\/p>\n<p>Esta <a href=\"https:\/\/wiki.php.net\/rfc\/autovivification_false\">RFC desestima la autovivencia<\/a> a partir de valores falsos. Sin embargo, ten en cuenta que la autovivencia a partir de variables indefinidas y nulas sigue estando permitida.<\/p>\n<p>En PHP 8.1, a\u00f1adir a una variable de tipo false emitir\u00e1 un aviso de desaprobaci\u00f3n:<\/p>\n<pre><code class=\"language-php\">Deprecated: Automatic conversion of false to array is deprecated in<\/code><\/pre>\n<p>PHP 9.0 lanzar\u00e1 un error fatal por lo mismo, que es id\u00e9ntico a otros tipos escalares.<\/p>\n<h3>La propiedad <code>mysqli_driver-&gt;driver_version<\/code> est\u00e1 obsoleta<\/h3>\n<p>La propiedad <strong>mysqli_driver-&gt;driver_version<\/strong> de la extensi\u00f3n MySQLi no ha sido actualizada desde hace 13 a\u00f1os. A pesar de los muchos cambios en el controlador desde entonces, todav\u00eda devuelve el valor de la versi\u00f3n antigua del controlador, haciendo que esta propiedad no tenga sentido.<\/p>\n<p>En PHP 8.1, la <a href=\"https:\/\/github.com\/php\/php-src\/commit\/3dfd3558ca2f63f\">propiedad mysqli_driver-&gt;driver_version est\u00e1 obsoleta<\/a>.<\/p>\n<h2>Otros cambios menores<\/h2>\n<p>Hay <a href=\"https:\/\/wiki.php.net\/rfc\/deprecations_php_8_1\">muchas m\u00e1s desaprobaciones en PHP 8.1<\/a>. Enumerarlas todas aqu\u00ed ser\u00eda un ejercicio agotador. Te recomendamos que consultes directamente la RFC para estas desaprobaciones menores.<\/p>\n<p>La p\u00e1gina de GitHub de PHP tambi\u00e9n incluye una gu\u00eda de <a href=\"https:\/\/github.com\/php\/php-src\/blob\/master\/UPGRADING\">NOTAS DE ACTUALIZACI\u00d3N a PHP 8.1<\/a>. En ella se enumeran todos los cambios de \u00faltima hora que debes tener en cuenta antes de actualizar a PHP 8.1.<\/p>\n\n<h2>Summary<\/h2>\n<p>PHP 8.1 es mejor que <a href=\"https:\/\/kinsta.com\/es\/blog\/php-8\/\">su predecesor<\/a>, lo que no es poco. Creemos que las caracter\u00edsticas m\u00e1s interesantes de PHP 8.1 son los Enums, las Fibras, los Tipos Puros de Intersecci\u00f3n y sus muchas mejoras de rendimiento. Adem\u00e1s, estamos impacientes por poner a prueba PHP 8.1 y comparar varios <a href=\"https:\/\/kinsta.com\/es\/blog\/frameworks-php\/\">frameworks<\/a> y <a href=\"https:\/\/kinsta.com\/es\/cuota-de-mercado-de-wordpress\/\">CMS<\/a> de PHP.<\/p>\n<p>Aseg\u00farate de marcar esta entrada del blog para su futura referencia.<\/p>\n<p><em>\u00bfQu\u00e9 caracter\u00edstica de PHP 8.1 es tu favorita? Comparte tu opini\u00f3n con la comunidad en la secci\u00f3n de comentarios m\u00e1s abajo.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lanzado el 25 de noviembre de 2021, PHP 8.1 est\u00e1 finalmente aqu\u00ed, con varias caracter\u00edsticas interesantes. En este art\u00edculo, cubriremos en detalle las novedades de PHP &#8230;<\/p>\n","protected":false},"author":117,"featured_media":43521,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kinsta_gated_content":false,"_kinsta_gated_content_redirect":"","footnotes":""},"tags":[432,868],"topic":[1317],"class_list":["post-43518","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-php","tag-php-8-1","topic-actualizaciones-php"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v24.6 (Yoast SEO v24.6) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Novedades de PHP 8.1: Caracter\u00edsticas, Cambios, Mejoras y Mucho M\u00e1s<\/title>\n<meta name=\"description\" content=\"Descubre las novedades de PHP 8.1. Desde las nuevas caracter\u00edsticas de PHP 8.1 y las mejoras de rendimiento hasta los cambios y las desaprobaciones , \u00a1lo cubrimos todo!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Novedades de PHP 8.1: Caracter\u00edsticas, Cambios, Mejoras y Mucho M\u00e1s\" \/>\n<meta property=\"og:description\" content=\"Descubre las novedades de PHP 8.1. Desde las nuevas caracter\u00edsticas de PHP 8.1 y las mejoras de rendimiento hasta los cambios y las desaprobaciones , \u00a1lo cubrimos todo!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/\" \/>\n<meta property=\"og:site_name\" content=\"Kinsta\u00ae\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/kinsta.es\/\" \/>\n<meta property=\"article:published_time\" content=\"2021-09-16T09:09:56+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-08-23T09:38:02+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/09\/php-8.1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1460\" \/>\n\t<meta property=\"og:image:height\" content=\"730\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Salman Ravoof\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:description\" content=\"Descubre las novedades de PHP 8.1. Desde las nuevas caracter\u00edsticas de PHP 8.1 y las mejoras de rendimiento hasta los cambios y las desaprobaciones , \u00a1lo cubrimos todo!\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/09\/php-8.1.png\" \/>\n<meta name=\"twitter:creator\" content=\"@salmanravoof\" \/>\n<meta name=\"twitter:site\" content=\"@Kinsta_ES\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Salman Ravoof\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"38 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/\"},\"author\":{\"name\":\"Salman Ravoof\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/person\/9cafd2eedd617e640eeea4cf3a5fd987\"},\"headline\":\"Novedades de PHP 8.1: Caracter\u00edsticas, Cambios, Mejoras y Mucho M\u00e1s\",\"datePublished\":\"2021-09-16T09:09:56+00:00\",\"dateModified\":\"2023-08-23T09:38:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/\"},\"wordCount\":8320,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/es\/#organization\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/09\/php-8.1.png\",\"keywords\":[\"php\",\"php 8.1\"],\"articleSection\":[\"Sin Categor\u00eda\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/\",\"url\":\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/\",\"name\":\"Novedades de PHP 8.1: Caracter\u00edsticas, Cambios, Mejoras y Mucho M\u00e1s\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/es\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/09\/php-8.1.png\",\"datePublished\":\"2021-09-16T09:09:56+00:00\",\"dateModified\":\"2023-08-23T09:38:02+00:00\",\"description\":\"Descubre las novedades de PHP 8.1. Desde las nuevas caracter\u00edsticas de PHP 8.1 y las mejoras de rendimiento hasta los cambios y las desaprobaciones , \u00a1lo cubrimos todo!\",\"breadcrumb\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#primaryimage\",\"url\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/09\/php-8.1.png\",\"contentUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/09\/php-8.1.png\",\"width\":1460,\"height\":730,\"caption\":\"Novedades de PHP 8.1: Caracter\u00edsticas, cambios, mejoras y m\u00e1s\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/kinsta.com\/es\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Actualizaciones de PHP\",\"item\":\"https:\/\/kinsta.com\/es\/secciones\/actualizaciones-php\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Novedades de PHP 8.1: Caracter\u00edsticas, Cambios, Mejoras y Mucho M\u00e1s\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/kinsta.com\/es\/#website\",\"url\":\"https:\/\/kinsta.com\/es\/\",\"name\":\"Kinsta\u00ae\",\"description\":\"Soluciones de alojamiento premium, r\u00e1pidas y seguras\",\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/es\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/kinsta.com\/es\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/kinsta.com\/es\/#organization\",\"name\":\"Kinsta\",\"url\":\"https:\/\/kinsta.com\/es\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg\",\"contentUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg\",\"width\":500,\"height\":500,\"caption\":\"Kinsta\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/kinsta.es\/\",\"https:\/\/x.com\/Kinsta_ES\",\"https:\/\/www.instagram.com\/kinstahosting\/\",\"https:\/\/www.linkedin.com\/company\/kinsta\/\",\"https:\/\/www.pinterest.com\/kinstahosting\/\",\"https:\/\/www.youtube.com\/c\/Kinsta\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/person\/9cafd2eedd617e640eeea4cf3a5fd987\",\"name\":\"Salman Ravoof\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/0c5885f75cb78473fb7408e5e49ad190?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/0c5885f75cb78473fb7408e5e49ad190?s=96&d=mm&r=g\",\"caption\":\"Salman Ravoof\"},\"description\":\"Salman Ravoof is a self-taught web developer, writer, creator, and a huge admirer of Free and Open Source Software (FOSS). Besides tech, he's excited by science, philosophy, photography, arts, cats, and food. Learn more about him on his website, and connect with Salman on Twitter.\",\"sameAs\":[\"https:\/\/salmanravoof.com\",\"https:\/\/www.linkedin.com\/in\/salman-ravoof-5a749133\/\",\"https:\/\/x.com\/salmanravoof\"],\"url\":\"https:\/\/kinsta.com\/es\/blog\/author\/salmanravoof\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Novedades de PHP 8.1: Caracter\u00edsticas, Cambios, Mejoras y Mucho M\u00e1s","description":"Descubre las novedades de PHP 8.1. Desde las nuevas caracter\u00edsticas de PHP 8.1 y las mejoras de rendimiento hasta los cambios y las desaprobaciones , \u00a1lo cubrimos todo!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/","og_locale":"es_ES","og_type":"article","og_title":"Novedades de PHP 8.1: Caracter\u00edsticas, Cambios, Mejoras y Mucho M\u00e1s","og_description":"Descubre las novedades de PHP 8.1. Desde las nuevas caracter\u00edsticas de PHP 8.1 y las mejoras de rendimiento hasta los cambios y las desaprobaciones , \u00a1lo cubrimos todo!","og_url":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/","og_site_name":"Kinsta\u00ae","article_publisher":"https:\/\/www.facebook.com\/kinsta.es\/","article_published_time":"2021-09-16T09:09:56+00:00","article_modified_time":"2023-08-23T09:38:02+00:00","og_image":[{"width":1460,"height":730,"url":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/09\/php-8.1.png","type":"image\/png"}],"author":"Salman Ravoof","twitter_card":"summary_large_image","twitter_description":"Descubre las novedades de PHP 8.1. Desde las nuevas caracter\u00edsticas de PHP 8.1 y las mejoras de rendimiento hasta los cambios y las desaprobaciones , \u00a1lo cubrimos todo!","twitter_image":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/09\/php-8.1.png","twitter_creator":"@salmanravoof","twitter_site":"@Kinsta_ES","twitter_misc":{"Escrito por":"Salman Ravoof","Tiempo de lectura":"38 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#article","isPartOf":{"@id":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/"},"author":{"name":"Salman Ravoof","@id":"https:\/\/kinsta.com\/es\/#\/schema\/person\/9cafd2eedd617e640eeea4cf3a5fd987"},"headline":"Novedades de PHP 8.1: Caracter\u00edsticas, Cambios, Mejoras y Mucho M\u00e1s","datePublished":"2021-09-16T09:09:56+00:00","dateModified":"2023-08-23T09:38:02+00:00","mainEntityOfPage":{"@id":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/"},"wordCount":8320,"commentCount":0,"publisher":{"@id":"https:\/\/kinsta.com\/es\/#organization"},"image":{"@id":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/09\/php-8.1.png","keywords":["php","php 8.1"],"articleSection":["Sin Categor\u00eda"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/kinsta.com\/es\/blog\/php-8-1\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/","url":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/","name":"Novedades de PHP 8.1: Caracter\u00edsticas, Cambios, Mejoras y Mucho M\u00e1s","isPartOf":{"@id":"https:\/\/kinsta.com\/es\/#website"},"primaryImageOfPage":{"@id":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#primaryimage"},"image":{"@id":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/09\/php-8.1.png","datePublished":"2021-09-16T09:09:56+00:00","dateModified":"2023-08-23T09:38:02+00:00","description":"Descubre las novedades de PHP 8.1. Desde las nuevas caracter\u00edsticas de PHP 8.1 y las mejoras de rendimiento hasta los cambios y las desaprobaciones , \u00a1lo cubrimos todo!","breadcrumb":{"@id":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/kinsta.com\/es\/blog\/php-8-1\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#primaryimage","url":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/09\/php-8.1.png","contentUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/09\/php-8.1.png","width":1460,"height":730,"caption":"Novedades de PHP 8.1: Caracter\u00edsticas, cambios, mejoras y m\u00e1s"},{"@type":"BreadcrumbList","@id":"https:\/\/kinsta.com\/es\/blog\/php-8-1\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/kinsta.com\/es\/"},{"@type":"ListItem","position":2,"name":"Actualizaciones de PHP","item":"https:\/\/kinsta.com\/es\/secciones\/actualizaciones-php\/"},{"@type":"ListItem","position":3,"name":"Novedades de PHP 8.1: Caracter\u00edsticas, Cambios, Mejoras y Mucho M\u00e1s"}]},{"@type":"WebSite","@id":"https:\/\/kinsta.com\/es\/#website","url":"https:\/\/kinsta.com\/es\/","name":"Kinsta\u00ae","description":"Soluciones de alojamiento premium, r\u00e1pidas y seguras","publisher":{"@id":"https:\/\/kinsta.com\/es\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/kinsta.com\/es\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/kinsta.com\/es\/#organization","name":"Kinsta","url":"https:\/\/kinsta.com\/es\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/","url":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg","contentUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg","width":500,"height":500,"caption":"Kinsta"},"image":{"@id":"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/kinsta.es\/","https:\/\/x.com\/Kinsta_ES","https:\/\/www.instagram.com\/kinstahosting\/","https:\/\/www.linkedin.com\/company\/kinsta\/","https:\/\/www.pinterest.com\/kinstahosting\/","https:\/\/www.youtube.com\/c\/Kinsta"]},{"@type":"Person","@id":"https:\/\/kinsta.com\/es\/#\/schema\/person\/9cafd2eedd617e640eeea4cf3a5fd987","name":"Salman Ravoof","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/kinsta.com\/es\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/0c5885f75cb78473fb7408e5e49ad190?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0c5885f75cb78473fb7408e5e49ad190?s=96&d=mm&r=g","caption":"Salman Ravoof"},"description":"Salman Ravoof is a self-taught web developer, writer, creator, and a huge admirer of Free and Open Source Software (FOSS). Besides tech, he's excited by science, philosophy, photography, arts, cats, and food. Learn more about him on his website, and connect with Salman on Twitter.","sameAs":["https:\/\/salmanravoof.com","https:\/\/www.linkedin.com\/in\/salman-ravoof-5a749133\/","https:\/\/x.com\/salmanravoof"],"url":"https:\/\/kinsta.com\/es\/blog\/author\/salmanravoof\/"}]}},"acf":[],"_links":{"self":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts\/43518","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/users\/117"}],"replies":[{"embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/comments?post=43518"}],"version-history":[{"count":17,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts\/43518\/revisions"}],"predecessor-version":[{"id":57588,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts\/43518\/revisions\/57588"}],"alternate":[{"embeddable":true,"hreflang":"en","title":"English","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43518\/translations\/en"},{"embeddable":true,"hreflang":"fr","title":"French","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43518\/translations\/fr"},{"embeddable":true,"hreflang":"it","title":"Italian","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43518\/translations\/it"},{"embeddable":true,"hreflang":"es","title":"Spanish","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43518\/translations\/es"},{"embeddable":true,"hreflang":"pt","title":"Portuguese","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43518\/translations\/pt"},{"embeddable":true,"hreflang":"de","title":"German","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43518\/translations\/de"},{"embeddable":true,"hreflang":"nl","title":"Dutch","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43518\/translations\/nl"},{"href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43518\/tree"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/media\/43521"}],"wp:attachment":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/media?parent=43518"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/tags?post=43518"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/topic?post=43518"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}