<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es"><title>Chemaclass - php</title><subtitle>Tech Lead compartiendo ideas prácticas sobre artesanía del software, TDD, liderazgo, Bitcoin e IA. Artículos, resúmenes de libros y charlas.</subtitle><link rel="self" type="application/atom+xml" href="https://chemaclass.com/es/tags/php/atom.xml"/><link rel="alternate" type="text/html" href="https://chemaclass.com"/><generator uri="https://www.getzola.org/">Zola</generator><updated>2022-11-28T00:00:00+00:00</updated><id>https://chemaclass.com/es/tags/php/atom.xml</id><entry xml:lang="es"><title>Recipes for Decoupling</title><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="architecture" scheme="https://chemaclass.com/tags/architecture/" label="Architecture"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><published>2022-11-28T00:00:00+00:00</published><updated>2022-11-28T00:00:00+00:00</updated><author><name>
Matthias Noback</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/readings/recipes-for-decoupling/"/><id>https://chemaclass.com/es/readings/recipes-for-decoupling/</id><summary type="html">¿Qué es el acoplamiento y por qué nos perjudica? Este libro recopila estrategias prácticas para separar tu código de dominio de la infraestructura y mantener un sistema sano a largo plazo.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>
&lt;p>¿Qué es el acoplamiento y por qué nos perjudica? ¿Cómo desacoplar de forma eficiente? Este libro recopila estrategias para separar tu código de dominio de los detalles de infraestructura. El resultado: un sistema más sano a largo plazo.&lt;/p>
&lt;p>Aprenderás a crear reglas de &lt;a rel="external" href="https://phpstan.org/">&lt;strong>PHPStan&lt;/strong>&lt;/a> desde cero. Además, el libro te guía por múltiples oportunidades de desacoplamiento:&lt;/p>
&lt;ul>
&lt;li>framework web&lt;/li>
&lt;li>frameworks cli&lt;/li>
&lt;li>validación de formularios&lt;/li>
&lt;li>orm y base de datos&lt;/li>
&lt;li>framework de testing&lt;/li>
&lt;/ul>
&lt;p>Lee más sobre el libro: &lt;a rel="external" href="https://matthiasnoback.nl/book/recipes-for-decoupling/">matthiasnoback.nl/book/recipes-for-decoupling/&lt;/a>&lt;/p>
&lt;blockquote>
&lt;p>Cómpralo aquí: &lt;a rel="external" href="https://leanpub.com/recipes-for-decoupling">leanpub.com/recipes-for-decoupling&lt;/a>&lt;/p>
&lt;/blockquote></content></entry><entry xml:lang="es"><title>Phel: el Lisp que Compila a PHP</title><subtitle>Un nuevo lenguaje funcional con interoperabilidad total con PHP</subtitle><category term="phel" scheme="https://chemaclass.com/tags/phel/" label="Phel"/><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="open-source" scheme="https://chemaclass.com/tags/open-source/" label="Open Source"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><published>2021-02-01T00:00:00+00:00</published><updated>2021-02-01T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/phel-first-release/"/><id>https://chemaclass.com/es/blog/phel-first-release/</id><summary type="html">El nuevo lenguaje de Programación Funcional construido para PHP.</summary><content type="html">&lt;p>Un nuevo lenguaje de Programación Funcional construido sobre el ecosistema de PHP.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="el-lenguaje-phel">El Lenguaje Phel
&lt;a class="heading-anchor" href="#el-lenguaje-phel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Phel es un lenguaje de Programación Funcional (&lt;a rel="external" href="https://en.wikipedia.org/wiki/Functional_programming">FP&lt;/a>) que compila a PHP. Es un dialecto de &lt;a rel="external" href="https://en.wikipedia.org/wiki/Lisp_(programming_language)">Lisp&lt;/a> inspirado en Clojure y Janet.&lt;/p>
&lt;h2 id="caracteristicas">Características
&lt;a class="heading-anchor" href="#caracteristicas" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>Construido sobre el ecosistema de PHP&lt;/li>
&lt;li>Buenos reportes de errores&lt;/li>
&lt;li>Diferentes estructuras de datos (Arrays, Tables y Tuples)&lt;/li>
&lt;li>Macros&lt;/li>
&lt;li>Funciones recursivas&lt;/li>
&lt;li>Sintaxis potente pero simple&lt;/li>
&lt;li>REPL&lt;/li>
&lt;/ul>
&lt;h2 id="por-que-phel">¿Por qué Phel?
&lt;a class="heading-anchor" href="#por-que-phel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Phel lo creó Jens Haase. Como menciona en el sitio web, “es el resultado de muchos &lt;a rel="external" href="https://phel-lang.org/blog/functional-programming-in-php">intentos fallidos de hacer programación funcional en PHP&lt;/a>”. Buscaba algo con estas características:&lt;/p>
&lt;ul>
&lt;li>Inspirado en LISP&lt;/li>
&lt;li>Lenguaje de Programación Funcional&lt;/li>
&lt;li>Que funcione en proveedores de hosting baratos&lt;/li>
&lt;li>Sea fácil de escribir y depurar&lt;/li>
&lt;/ul>
&lt;p>A finales de mayo de 2020 terminé el libro &lt;a href="/es/readings/7-languages-in-7-weeks/">Seven Languages in Seven Weeks&lt;/a>, donde aprendí los fundamentos de Prolog, Erlang, Clojure, Haskell… Incluso creé un &lt;a rel="external" href="https://github.com/Chemaclass/7LangIn7Weeks">repositorio en GitHub&lt;/a> para guardar mi progreso.&lt;/p>
&lt;p>A principios de junio de 2020, vi un post en el canal de PHP de Reddit mencionando este proyecto “&lt;strong>Phel&lt;/strong>”: un &lt;strong>lenguaje de programación funcional escrito en PHP&lt;/strong>.&lt;/p>
&lt;p>Llevo unos 8 años trabajando con PHP, y siempre intento combinar OOP con FP (creo que ambos paradigmas funcionan mejor juntos; no son excluyentes). Un nuevo dialecto de Lisp escrito en &lt;strong>PHP 7.4&lt;/strong> nativo sonaba emocionante. Decidí echarle un vistazo al código.&lt;/p>
&lt;p>Las lecturas recientes de &lt;a rel="external" href="https://x.com/matthiasnoback">Mathias NoBack&lt;/a>, como &lt;a href="/es/readings/object-design-style-guide">Object Design Style Guide&lt;/a> y &lt;a href="/es/readings/advance-web-application-architecture/">Advanced Web Application Architecture&lt;/a>, me dieron el empuje para aplicar lo aprendido en un proyecto real. Este fue (y sigue siendo) un desafío que me ayuda a crecer profesionalmente.&lt;/p>
&lt;p>Mi primer commit fue el 6 de junio de 2020. Desde entonces dedico un poco de tiempo cada día en mis horas libres.
Me ayuda a aprender sobre FP, diseño interno de lenguajes, testing y arquitectura de software en general.&lt;/p>
&lt;p>Empecé con cambios menores hasta que acabé refactorizando toda la estructura del compilador para hacer los módulos más legibles. Psalm, tipos estrictos, buena cobertura de tests, estilo de código unificado… Estos fueron algunos de mis temas favoritos.&lt;/p>
&lt;h2 id="ejemplo-de-codigo-phel">Ejemplo de código Phel
&lt;a class="heading-anchor" href="#ejemplo-de-codigo-phel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>El siguiente ejemplo da una breve impresión de cómo se ve Phel:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="plain">&lt;span class="giallo-l">&lt;span># Define un namespace&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>(ns my\example)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span># Define una variable con nombre &amp;quot;my-name&amp;quot; y valor &amp;quot;world&amp;quot;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>(def my-name &amp;quot;world&amp;quot;)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span># Define una función con nombre &amp;quot;print-name&amp;quot; y un argumento&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>(defn print-name [your-name]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> (print &amp;quot;hello&amp;quot; your-name))&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span># Llama a la función&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>(print-name my-name)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h2 id="estado-actual-de-phel">Estado actual de Phel
&lt;a class="heading-anchor" href="#estado-actual-de-phel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>Preparamos una fácil &lt;a rel="external" href="https://phel-lang.org/documentation/getting-started/">Guía de Inicio&lt;/a>&lt;/li>
&lt;li>Preparamos un Repositorio GitHub fácil con una &lt;a rel="external" href="https://github.com/phel-lang/phel-scaffolding">Plantilla de Scaffolding de Phel&lt;/a>&lt;/li>
&lt;li>Acabamos de lanzar la primera versión oficial: &lt;a rel="external" href="https://github.com/phel-lang/phel-lang/tags">0.1.0&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Consulta el sitio web oficial con toda la documentación: &lt;a rel="external" href="https://phel-lang.org/">https://phel-lang.org/&lt;/a>&lt;/p>
&lt;hr />
&lt;h3 id="tambien-recomendado">También recomendado
&lt;a class="heading-anchor" href="#tambien-recomendado" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://jesusvalera.dev/functional-programming-with-phel/">Functional Programming with Phel - JesusValera&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="es"><title>Mockear o No Mockear</title><subtitle>Cómo escapar del infierno del mocking</subtitle><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><published>2021-01-11T00:00:00+00:00</published><updated>2021-01-11T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/to-mock-or-not-to-mock/"/><id>https://chemaclass.com/es/blog/to-mock-or-not-to-mock/</id><summary type="html">Mockear es útil, pero 'qué mockear' suele resultar más complicado de lo esperado si no tratas esto con cuidado.</summary><content type="html">&lt;p>Mockear es útil, pero “qué mockear” suele resultar más complicado de lo esperado si no tratas esto con cuidado.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h4 id="como-escapar-del-infierno-del-mocking">Cómo escapar del infierno del mocking
&lt;a class="heading-anchor" href="#como-escapar-del-infierno-del-mocking" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;p>¿Qué pasa realmente cuando creamos un mock? ¿Qué tipos hay? ¿Es bueno o malo mockear? Como siempre, depende del contexto. Aquí veremos las situaciones principales: cuándo mockear, cuándo no hacerlo, y sobre todo por qué.&lt;/p>
&lt;h2 id="que-pasa-cuando-mockeas-algo">¿Qué pasa cuando mockeas algo?
&lt;a class="heading-anchor" href="#que-pasa-cuando-mockeas-algo" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Primero, deberíamos definir qué es un mock:&lt;/p>
&lt;blockquote>
&lt;p>En un test unitario, los objetos mock pueden simular el comportamiento de objetos reales complejos y por lo tanto son útiles cuando es impracticable o imposible incorporar un objeto real en un test unitario.&lt;/p>
&lt;/blockquote>
&lt;p>Mockear tiene sentido en &lt;em>testing unitario&lt;/em>. Un test de integración pasa por la implementación real, verificando cómo interactúan varias unidades. Estos tests sí pueden hablar con la BD o el sistema de archivos.
Partimos de esta base: &lt;em>un test unitario es rápido, determinista, no depende de recursos externos y no requiere contexto especial para ejecutarse&lt;/em>.&lt;/p>
&lt;p>Los mocks cumplen el contrato de la &lt;em>interfaz&lt;/em>. Nos permiten testear funcionalidad sin invocar clases colaboradoras complejas.&lt;/p>
&lt;p>Un mock es un doble de test que sustituye la implementación real. Además, puede verificar cómo el código bajo test lo utilizó durante la ejecución.&lt;/p>
&lt;blockquote>
&lt;p>Recomiendo encarecidamente que leas este post si quieres entrar en los detalles de por qué &lt;a rel="external" href="https://medium.com/javascript-scene/mocking-is-a-code-smell-944a70c90a6a">Mockear es un code smell&lt;/a> (Temas como estos: ¿Qué es un mock? ¿Qué es un test unitario? ¿Qué es la cobertura de tests? ¿Qué es el acoplamiento fuerte? ¿Qué causa el acoplamiento fuerte? ¿Qué tiene que ver la composición con el mocking? ¿Cómo eliminamos el acoplamiento? ¡y más!)&lt;/p>
&lt;/blockquote>
&lt;h2 id="el-problema-con-mockear">El problema con mockear
&lt;a class="heading-anchor" href="#el-problema-con-mockear" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Cuando mockeas, anulas la lógica de la clase mockeada. La lógica real queda oculta, y ahí es donde los bugs se esconden. Ten en cuenta que:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>El mock puede tener atributos, métodos o argumentos que el objeto real no tiene.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Los &lt;em>valores de retorno del mock pueden diferir de los reales&lt;/em>. Por ejemplo, puede devolver un tipo distinto con atributos diferentes.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Los &lt;em>efectos secundarios y comportamiento del mock pueden diferir del objeto real&lt;/em>. Quizás el mock no lanza una excepción que el objeto real sí lanzaría.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="alternativas-a-mockear">Alternativas a mockear
&lt;a class="heading-anchor" href="#alternativas-a-mockear" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>“¿Estás diciendo que mockear es malo y no deberíamos mockear?” No.&lt;/p>
&lt;p>Depende de lo que estés “anulando”.&lt;/p>
&lt;ul>
&lt;li>¿Es tu lógica de dominio de negocio lo que estás mockeando? Entonces está mal.&lt;/li>
&lt;li>¿Es la conexión a la BD lo que estás mockeando? Entonces está bien.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Depende del contexto de la lógica y dónde pertenece esa lógica.&lt;/p>
&lt;/blockquote>
&lt;p>¿Es parte de tu lógica de dominio de negocio? Entonces no deberías mockearla sino instanciarla.&lt;/p>
&lt;p>¿Es una dependencia de infraestructura como conexión a BD, sistema de archivos, red, o cualquier servicio externo que no tiene que ver con tu dominio de negocio? Entonces &lt;em>mockéala usando abstracciones/interfaces&lt;/em>.&lt;/p>
&lt;p>La interfaz es el &lt;em>contrato entre tu lógica de dominio y sus dependencias de infraestructura&lt;/em>.
Imagina lo fácil que es testear tu dominio instanciándolo y llamando a sus métodos con diferentes argumentos, todo bajo tu control total.&lt;/p>
&lt;h2 id="algunos-trucos">Algunos trucos
&lt;a class="heading-anchor" href="#algunos-trucos" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Cuando estés escribiendo un test unitario:&lt;/p>
&lt;ul>
&lt;li>Intenta instanciar tus clases primero.&lt;/li>
&lt;li>Evita mockear clases concretas. Escribí un artículo exclusivamente sobre esto:
fomentando &lt;a rel="external" href="https://medium.com/swlh/final-classes-in-php-9174e3e2747e">clases finales&lt;/a> e interfaces.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Mockea interfaces. Instancia clases concretas.&lt;/p>
&lt;/blockquote>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/RbSqXFUfRMU"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;p>“El uso excesivo de mocks lleva a código legacy.” - Philippe Boargau&lt;/p>
&lt;h3 id="como-podemos-evitar-el-mocking-excesivo">¿Cómo podemos evitar el mocking excesivo?
&lt;a class="heading-anchor" href="#como-podemos-evitar-el-mocking-excesivo" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Favorece el estado inmutable sobre el estado mutable.&lt;/li>
&lt;li>Haz las dependencias explícitas.&lt;/li>
&lt;li>Programa hacia una interfaz, no hacia una implementación.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="/images/blog/2021-01-11/footer.webp" alt="mockea interfaces, instancia clases concretas" />&lt;/p>
&lt;hr />
&lt;h4 id="referencias">Referencias
&lt;a class="heading-anchor" href="#referencias" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://medium.com/javascript-scene/mocking-is-a-code-smell-944a70c90a6a">Mocking is a code smell&lt;/a> - Eric Elliott&lt;/li>
&lt;li>&lt;a rel="external" href="https://blog.cleancoder.com/uncle-bob/2014/05/10/WhenToMock.html">When to mock&lt;/a> &amp;amp; &lt;a rel="external" href="https://blog.cleancoder.com/uncle-bob/2017/05/05/TestDefinitions.html">Test Definitions&lt;/a> - Uncle Bob&lt;/li>
&lt;li>&lt;a rel="external" href="https://matthiasnoback.nl/2018/09/final-classes-by-default-why/">Final classes by default&lt;/a> - Matthias Noback&lt;/li>
&lt;li>&lt;a rel="external" href="https://www.seanh.cc/2017/03/17/the-problem-with-mocks/">The problem with mocks&lt;/a> - Sean Hammond&lt;/li>
&lt;li>&lt;a rel="external" href="https://www.artima.com/weblogs/viewpost.jsp?thread=126923">A Set of Unit Testing Rules&lt;/a> - Michael Feathers&lt;/li>
&lt;/ul></content></entry><entry xml:lang="es"><title>Nunca Uses array_merge en un Bucle</title><subtitle>El operador spread al rescate</subtitle><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2020-11-10T00:00:00+00:00</published><updated>2020-11-10T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/array-merge-in-loop/"/><id>https://chemaclass.com/es/blog/array-merge-in-loop/</id><summary type="html">Usar array_merge dentro de un bucle mata el rendimiento. El operador spread te ayudará a mejorar esto aplanando el array.</summary><content type="html">&lt;p>Usar array_merge dentro de un bucle mata el rendimiento.
El operador spread te ayudará a mejorar esto aplanando el array.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="aplanando-un-array-de-un-nivel">Aplanando un array de un nivel
&lt;a class="heading-anchor" href="#aplanando-un-array-de-un-nivel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>He visto a gente usar array_merge dentro de un bucle así:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">5&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">foreach&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> as&lt;/span>&lt;span> $&lt;/span>&lt;span>list&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> $&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span>,&lt;/span>&lt;span> $&lt;/span>&lt;span>list&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> $merged === [1, 2, 3, 4, 5, 6];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Esto es mala práctica porque destroza el rendimiento de memoria.
Mejor usa el operador spread (disponible desde PHP 5.6):&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">5&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> === [1, 2, 3, 4, 5, 6];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h2 id="desempaquetando-un-array-asociativo">Desempaquetando un array asociativo
&lt;a class="heading-anchor" href="#desempaquetando-un-array-asociativo" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>¿Y si tuvieras un array asociativo como este?&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-1&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-3&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">5&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>En ese caso, necesitarás desempaquetar sus valores:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">array_values&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> === [1, 2, 3, 4, 5, 6];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>En programación funcional, esto se conoce como aplanar una lista.
Sin bucles ni problemas de rendimiento.&lt;/p>
&lt;h2 id="aplanando-un-array-multinivel">Aplanando un array multinivel
&lt;a class="heading-anchor" href="#aplanando-un-array-multinivel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>¿Y si quisieras aplanar un array multinivel como este?&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 5&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">6&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 7&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 8&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>¿O como este, incluso con clave-valores?&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-1&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 1&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 3&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-3&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">4&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 5&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-4&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">7&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 8&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Para estos casos, puedes usar la librería estándar de PHP:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> iterator_to_array&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> RecursiveIteratorIterator&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> RecursiveArrayIterator&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> $&lt;/span>&lt;span>use_keys&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> false&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> $merged === [1, 2, 3, 4, 5, 6, 7, 8];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h2 id="que-enfoque-de-aplanado-usar">Qué enfoque de aplanado usar
&lt;a class="heading-anchor" href="#que-enfoque-de-aplanado-usar" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Normalmente, saber aplanar un array de dos niveles suele ser suficiente:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>flattenList&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">array_values&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Para casos más complejos, la librería estándar de PHP te saca del apuro.&lt;/p>
&lt;hr />
&lt;h3 id="referencias">Referencias
&lt;a class="heading-anchor" href="#referencias" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://wiki.php.net/rfc/spread_operator_for_array">Spread_operator_for_array - Wikipedia&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://rosettacode.org/wiki/Flatten_a_list">Flatten_a_list - Rosettacode&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="es"><title>Arrays Tipados en PHP</title><subtitle>Una alternativa a la característica que falta en PHP: Generics</subtitle><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><published>2020-10-13T00:00:00+00:00</published><updated>2020-10-13T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/typed-arrays-php/"/><id>https://chemaclass.com/es/blog/typed-arrays-php/</id><summary type="html">Desempaquetado de argumentos, lista de argumentos variables de función, y funciones variádicas.</summary><content type="html">&lt;p>Desempaquetado de argumentos, lista de argumentos variables de función, y funciones variádicas.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h3 id="la-combinacion-perfecta">La combinación perfecta
&lt;a class="heading-anchor" href="#la-combinacion-perfecta" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Desempaquetado de argumentos&lt;/strong>: pasa los elementos de un array como argumentos individuales a una función.&lt;/li>
&lt;li>&lt;strong>Lista de argumentos variables&lt;/strong>: la función recibe los argumentos como un array.&lt;/li>
&lt;li>&lt;strong>Función variádica&lt;/strong>: permite verificar los tipos con un type-hint.&lt;/li>
&lt;/ul>
&lt;p>Usaremos este snippet para nuestros ejemplos.
Tenemos una clase &lt;code>Customer&lt;/code>:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">/**&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> * @psalm-immutable&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> */&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Customer&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> Usando la promoción de propiedades en constructor de PHP 8&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> https://wiki.php.net/rfc/constructor_promotion&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> __construct&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> string&lt;/span>&lt;span> $&lt;/span>&lt;span>name&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span> {&lt;/span>&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> Creamos una lista de 6 clientes&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_map&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> fn&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">int&lt;/span>&lt;span> $&lt;/span>&lt;span>i&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">name-&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">{&lt;/span>&lt;span>$&lt;/span>&lt;span>i&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">}&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> range&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Siempre que queramos manipular una lista de Customers, podemos pasar como argumento: &lt;code>…$customers&lt;/code>.&lt;/p>
&lt;h2 id="como-soliamos-hacerlo">Cómo solíamos hacerlo
&lt;a class="heading-anchor" href="#como-soliamos-hacerlo" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Definimos el tipo del array con PHPDoc, pero no podemos forzar el tipo real de cada elemento. El código se ejecuta sin problemas aunque pases cualquier tipo en &lt;code>array $customers&lt;/code>:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">/**&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> * &lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">@param&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">[]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> */&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">array&lt;/span>&lt;span> $&lt;/span>&lt;span>customers&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> foreach&lt;/span>&lt;span> (&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> as&lt;/span>&lt;span> $&lt;/span>&lt;span>customer&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... alguna lógica irrelevante para este ejemplo&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>El código de abajo funcionaría en “tiempo de compilación”. Pero podría fallar en “tiempo de ejecución”.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">any name&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>)&lt;/span>&lt;span>]&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> AnyOtherType&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>]&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Una alternativa recomendada: extraer la lógica y pedir el tipo concreto para verificarlo en tiempo de ejecución. Fallará si alguno de los elementos no es un Customer:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">/**&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> * &lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">@param&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">[]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> */&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">array&lt;/span>&lt;span> $&lt;/span>&lt;span>customers&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> foreach&lt;/span>&lt;span> (&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> as&lt;/span>&lt;span> $&lt;/span>&lt;span>customer&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> createInvoice&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>customer&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> createInvoice&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">Customer&lt;/span>&lt;span> $&lt;/span>&lt;span>customer&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... alguna lógica irrelevante para este ejemplo&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Todo lo de aquí abajo funcionaría en “tiempo de compilación”. Seguro que fallará durante “tiempo de ejecución” si &lt;code>createInvoice(Customer $customer)&lt;/code> recibe algo diferente a un Customer.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">any name&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>)&lt;/span>&lt;span>]&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> AnyOtherType&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>]&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> no funcionará&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Con &lt;code>createInvoice(Customer $customer)&lt;/code> aseguramos el tipo del argumento. Pero, ¿podemos ir un paso más allá? ¿Podríamos verificar los tipos al llamar a &lt;code>createInvoiceForCustomers(array $customers)&lt;/code>, y que el IDE se queje si los tipos no son correctos?&lt;/p>
&lt;p>Eso es precisamente para lo que sirven los Generics, pero aún no existen en PHP. Ni siquiera en PHP 8. Quizás lleguen pronto, pero por ahora hay una alternativa menos conocida con sus pros y contras. Veamos un ejemplo:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">Customer&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> ...&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> foreach&lt;/span>&lt;span> (&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> as&lt;/span>&lt;span> $&lt;/span>&lt;span>customer&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> createInvoice&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>customer&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Todo lo de aquí abajo funcionaría en “tiempo de compilación”. Seguro que fallará durante “tiempo de ejecución” si &lt;code>createInvoice()&lt;/code> recibe algo diferente a un Customer.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span>$&lt;/span>&lt;span>customers&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> OK&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">any name&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Customer&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">any name&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> OK&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> Esto ni siquiera es posible de escribir. El IDE te gritará.&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> Está esperando un `Customer`, pero `AnyOtherType` es dado:&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInvoiceForCustomers&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> AnyOtherType&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="pros">PROS
&lt;a class="heading-anchor" href="#pros" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Podemos tipar una lista de cualquier tipo concreto de forma sencilla.&lt;/li>
&lt;/ul>
&lt;h3 id="contras">CONTRAS
&lt;a class="heading-anchor" href="#contras" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Mejor limitar las funciones a uno o dos argumentos. De lo contrario, se complica la lectura.&lt;/li>
&lt;/ul>
&lt;h3 id="observaciones-importantes">Observaciones importantes
&lt;a class="heading-anchor" href="#observaciones-importantes" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Debe ser el último argumento de la función.&lt;/li>
&lt;li>Ayuda a minimizar el número de argumentos.&lt;/li>
&lt;/ul>
&lt;h2 id="los-variadics-simulan-arrays-tipados-usalos-con-cabeza">Los variadics simulan arrays tipados, úsalos con cabeza
&lt;a class="heading-anchor" href="#los-variadics-simulan-arrays-tipados-usalos-con-cabeza" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>El desempaquetado de argumentos, combinado con funciones variádicas, nos permite simular arrays tipados. Un gran poder conlleva una gran responsabilidad.
Hay que conocer bien nuestras herramientas para usarlas con criterio.&lt;/p>
&lt;p>&lt;img src="/images/blog/2020-10-13/footer.webp" alt="arrays tipados con variádicas en php" />&lt;/p>
&lt;hr />
&lt;h3 id="referencias">Referencias
&lt;a class="heading-anchor" href="#referencias" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://wiki.php.net/rfc/argument_unpacking">Desempaquetado de argumentos&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list">Lista de argumentos variables de función&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://wiki.php.net/rfc/variadics">Función variádica&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="es"><title>Guía de estilo para diseño de objetos</title><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><published>2020-10-10T00:00:00+00:00</published><updated>2020-10-10T00:00:00+00:00</updated><author><name>
Matthias Noback</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/readings/object-design-style-guide/"/><id>https://chemaclass.com/es/readings/object-design-style-guide/</id><summary type="html">&lt;p>Los objetos son el corazón de lenguajes como Java, Python y C#. Si aplicas buenas prácticas de diseño, tu código será más fácil de leer, escribir y mantener.&lt;/p>
&lt;p>Este libro reúne docenas de técnicas para crear código OO profesional que aguanta el paso del tiempo.&lt;/p></summary><content type="html">&lt;p>Los objetos son el corazón de lenguajes como Java, Python y C#. Si aplicas buenas prácticas de diseño, tu código será más fácil de leer, escribir y mantener.&lt;/p>
&lt;p>Este libro reúne docenas de técnicas para crear código OO profesional que aguanta el paso del tiempo.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>Los ejemplos usan pseudocódigo fácil de entender. Las técnicas aplican a cualquier lenguaje OO, desde C++ hasta PHP.&lt;/p></content></entry><entry xml:lang="es"><title>Advanced Web Application Architecture</title><subtitle>La guía que lleva tus habilidades de código al siguiente nivel</subtitle><category term="architecture" scheme="https://chemaclass.com/tags/architecture/" label="Architecture"/><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2020-08-16T00:00:00+00:00</published><updated>2020-08-16T00:00:00+00:00</updated><author><name>
Matthias Noback</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/readings/advance-web-application-architecture/"/><id>https://chemaclass.com/es/readings/advance-web-application-architecture/</id><summary type="html">Cómo desacoplar tu aplicación del framework y la base de datos con PHP moderno y diseño modular</summary><content type="html">&lt;p>Este libro te ayuda a poner en forma tus aplicaciones web. Trae muchas técnicas para desacoplar tu código de la infraestructura (el framework, la base de datos, etc.).&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>La Parte 1 presenta patrones de diseño para separar código de negocio e infraestructura. La Parte 2 muestra cómo estos patrones encajan con conceptos arquitectónicos como capas, puertos y adaptadores (arquitectura Hexagonal). El libro cierra con estrategias de testing y decisiones de diseño.&lt;/p>
&lt;h3 id="lo-que-aprenderas">Lo que aprenderás
&lt;a class="heading-anchor" href="#lo-que-aprenderas" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Separar código mezclado en código de negocio e infraestructura usando patrones.&lt;/li>
&lt;li>Dividir tu código en capas con una distinción clara entre puertos y adaptadores.&lt;/li>
&lt;li>Testear aplicaciones desacopladas.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Compra el libro: &lt;a rel="external" href="https://leanpub.com/web-application-architecture">https://leanpub.com/web-application-architecture&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;hr />
&lt;h3 id="patrones-de-diseno-para-modernizar-codigo-legacy">Patrones de diseño para modernizar código legacy
&lt;a class="heading-anchor" href="#patrones-de-diseno-para-modernizar-codigo-legacy" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/WI1QY6OMglE"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div></content></entry><entry xml:lang="es"><title>Strict Types en PHP</title><subtitle>declare(strict_types=1);</subtitle><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><published>2020-08-09T00:00:00+00:00</published><updated>2020-08-09T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/strict-types/"/><id>https://chemaclass.com/es/blog/strict-types/</id><summary type="html">Por qué declarar strict_types en PHP mejora la legibilidad del código y previene errores silenciosos de coerción de tipos.</summary><content type="html">&lt;p>En diciembre de 2015, PHP 7 introdujo las declaraciones de tipos escalares y la bandera strict types. ¿Qué es esto?&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>Lo bueno de declarar un archivo PHP como estricto es que se aplica &lt;strong>solo al archivo actual&lt;/strong>. Asegura tipos estrictos en ese archivo, pero no afecta al resto del proyecto. Puedes migrar de código no estricto a estricto paso a paso, especialmente en archivos o proyectos nuevos.&lt;/p>
&lt;blockquote>
&lt;p>Para habilitar el modo estricto, coloca una directiva declare al principio del archivo. La estrictez de tipado para escalares se configura por archivo. Esta directiva afecta tanto a los parámetros como al tipo de retorno de las funciones.&lt;/p>
&lt;/blockquote>
&lt;h2 id="strict-types-afecta-la-coercion-de-tipos">Strict types afecta la coerción de tipos
&lt;a class="heading-anchor" href="#strict-types-afecta-la-coercion-de-tipos" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Usar type hints sin &lt;code>strict_types&lt;/code> puede causar bugs sutiles.&lt;/p>
&lt;p>Sin strict types, &lt;code>int $x&lt;/code> significa “$x debe ser coercionable a int”. Cualquier valor coercionable a int pasaría:&lt;/p>
&lt;ul>
&lt;li>un &lt;code>int&lt;/code> (42 -&amp;gt; 42)&lt;/li>
&lt;li>un &lt;code>float&lt;/code> (13.1459 -&amp;gt; 13)&lt;/li>
&lt;li>un &lt;code>bool&lt;/code> (true -&amp;gt; 1)&lt;/li>
&lt;li>un &lt;code>null&lt;/code> (null -&amp;gt; 0)&lt;/li>
&lt;li>un &lt;code>string&lt;/code> con dígitos al inicio (“15 Trees” -&amp;gt; 15)&lt;/li>
&lt;/ul>
&lt;p>Con &lt;code>strict_types=1&lt;/code>, le dices al motor que &lt;code>int $x&lt;/code> significa que $x debe ser un int real, sin coerción. Tienes la seguridad de que recibes exactamente lo que se pasó, sin conversiones ni pérdida de datos.&lt;/p>
&lt;h2 id="a-quien-le-importa-esta-linea">¿A quién le importa esta línea?
&lt;a class="heading-anchor" href="#a-quien-le-importa-esta-linea" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>&lt;code>declare(strict_types=1);&lt;/code> es más para el lector que para el escritor. Le dice explícitamente:&lt;/p>
&lt;ul>
&lt;li>Los tipos en este archivo se tratan de forma estricta.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>‘strict_types=1’ es más para el lector que para el escritor&lt;/p>
&lt;/blockquote>
&lt;p>El escritor solo necesita mantener esa estrictez mientras escribe. Pero como escritor, deberías preocuparte por tus lectores. Eso incluye a tu yo futuro.&lt;/p>
&lt;p>&lt;img src="/images/blog/2020-08-09/footer.webp" alt="declaración strict_types en php" />&lt;/p>
&lt;hr />
&lt;h2 id="referencias">Referencias
&lt;a class="heading-anchor" href="#referencias" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.scalar-type-declarations">Declaraciones de tipos escalares&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://stackoverflow.com/questions/48723637/what-do-strict-types-do-in-php/48723830#48723830">Qué hacen los strict types en PHP&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="es"><title>Clases Final en PHP | Java | Cualquiera</title><subtitle>Final, o no final, esa es la cuestión</subtitle><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><published>2020-06-06T00:00:00+00:00</published><updated>2020-06-06T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/final-classes/"/><id>https://chemaclass.com/es/blog/final-classes/</id><summary type="html">Contratos claros, efectos secundarios aislados, testeabilidad, baja complejidad y carga cognitiva, fluidez del código y confianza en ti mismo.</summary><content type="html">&lt;p>Contratos claros, efectos secundarios aislados, testeabilidad, baja complejidad y carga cognitiva, fluidez del código y confianza en ti mismo.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="motivacion">Motivación
&lt;a class="heading-anchor" href="#motivacion" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="reduce-la-visibilidad-al-minimo">Reduce la visibilidad al mínimo
&lt;a class="heading-anchor" href="#reduce-la-visibilidad-al-minimo" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Cuando una clase es &lt;code>final&lt;/code>, no puede ser extendida. Esto la hace más legible y te asegura que la lógica está limitada a esa clase.&lt;/p>
&lt;h3 id="fomenta-composicion-sobre-herencia">Fomenta “composición sobre herencia”
&lt;a class="heading-anchor" href="#fomenta-composicion-sobre-herencia" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>El Principio Abierto-Cerrado dice: abierto para extensión, cerrado para modificación.&lt;/p>
&lt;p>Si decides crear una herencia (por una buena razón, de la que deberías ser consciente), simplemente quita &lt;code>final&lt;/code> y listo.&lt;/p>
&lt;p>Cuando por defecto no puedes extender una clase, te fuerzas a pensar en composición en lugar de herencia.&lt;/p>
&lt;h2 id="por-que-esta-clase-no-es-final">¿Por qué esta clase no es final?
&lt;a class="heading-anchor" href="#por-que-esta-clase-no-es-final" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Si preferimos composición sobre herencia, deberíamos evitar la herencia tanto como sea posible. La herencia se usa mal a menudo en POO.&lt;/p>
&lt;h3 id="un-concepto-mal-entendido">Un concepto mal entendido
&lt;a class="heading-anchor" href="#un-concepto-mal-entendido" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Cuando nos enseñaron POO, normalmente empezamos con el ejemplo clásico de herencia.&lt;/p>
&lt;p>Pero cuando Alan Kay creó Smalltalk, la herencia no era el concepto principal. Lo principal era el paso de mensajes: enviar mensajes a objetos que encapsulan datos y lógica, cambiando comportamiento mediante diferentes objetos. Eso es composición. La herencia se hizo tan popular que terminó eclipsando a la composición.&lt;/p>
&lt;h3 id="beneficios">Beneficios
&lt;a class="heading-anchor" href="#beneficios" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Contratos claros.&lt;/strong> Usar interfaces te obliga a pensar en comunicación entre objetos.&lt;/li>
&lt;li>&lt;strong>Código aislado, sin efectos secundarios.&lt;/strong> Inyectar solo interfaces elimina efectos secundarios molestos.&lt;/li>
&lt;li>&lt;strong>Testeabilidad.&lt;/strong> Mockear interfaces es muy fácil.&lt;/li>
&lt;li>&lt;strong>Complejidad manejable.&lt;/strong> Todo aislado significa menos cambios en cascada.&lt;/li>
&lt;li>&lt;strong>Baja carga cognitiva.&lt;/strong> Menos complejidad, más foco en lo importante.&lt;/li>
&lt;li>&lt;strong>Flexibilidad.&lt;/strong> Sin acoplamiento innecesario, mover código es más fácil.&lt;/li>
&lt;li>&lt;strong>Confianza.&lt;/strong> Testear código aislado te da seguridad para cambiarlo.&lt;/li>
&lt;/ul>
&lt;h2 id="composicion-sobre-herencia">Composición sobre herencia
&lt;a class="heading-anchor" href="#composicion-sobre-herencia" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Si necesitas reconfigurar un objeto, cambiar partes de un algoritmo o reescribir parte de la implementación, considera crear una nueva clase en lugar de sobreescribir una existente.&lt;/p>
&lt;p>¿Necesitas representar una jerarquía donde las subclases sustituyen a las clases padre? Esta sería la situación clásica donde podrías usar herencia. Aun así, el resultado suele ser mejor si heredas de interfaces abstractas, no de clases concretas.&lt;/p>
&lt;h3 id="que-hacer-en-su-lugar">Qué hacer en su lugar
&lt;a class="heading-anchor" href="#que-hacer-en-su-lugar" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Usa interfaces para definir contratos entre clases.&lt;/li>
&lt;li>Usa clases finales para implementar esas interfaces.&lt;/li>
&lt;li>Usa composición (inyección de dependencias por constructor) para unir las piezas.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Interfaces -&amp;gt; Clases finales -&amp;gt; Composición&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="/images/blog/2020-06-06/footer.webp" alt="interfaces, clases finales y composición" />&lt;/p></content></entry><entry xml:lang="es"><title>Symfony 5</title><subtitle>Symfony 5: La Vía Rápida</subtitle><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="symfony" scheme="https://chemaclass.com/tags/symfony/" label="Symfony"/><category term="architecture" scheme="https://chemaclass.com/tags/architecture/" label="Architecture"/><published>2020-02-20T00:00:00+00:00</published><updated>2020-02-20T00:00:00+00:00</updated><author><name>
Fabien Potencier</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/readings/symfony-5/"/><id>https://chemaclass.com/es/readings/symfony-5/</id><summary type="html">Una guía práctica del creador de Symfony para desarrollar aplicaciones web desde cero hasta producción.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>
&lt;p>Escrito por el creador de Symfony, este libro presenta un enfoque práctico para desarrollar aplicaciones web con Symfony 5: desde cero hasta producción. Si estás descubriendo Symfony por primera vez o quieres refrescar tus conocimientos, esta guía te da una introducción completa a las aplicaciones modernas con Symfony.&lt;/p></content></entry></feed>