<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title>Chemaclass - php</title><subtitle>Tech Lead sharing practical insights on software craftsmanship, TDD, leadership, Bitcoin, and AI. Blog posts, book summaries, and conference talks.</subtitle><link rel="self" type="application/atom+xml" href="https://chemaclass.com/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/tags/php/atom.xml</id><entry xml:lang="en"><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/readings/recipes-for-decoupling/"/><id>https://chemaclass.com/readings/recipes-for-decoupling/</id><summary type="html">What is coupling, and why is it bad? What is decoupling, and how to do it efficiently? This book is a compilation of strategies to decouple your domain code from those infrastructure details, so you can enjoy a healthier system in the long run.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>
&lt;p>What is coupling, and why is it bad? What is decoupling, and how to do it efficiently? This book is a compilation of
strategies to decouple your domain code from those infrastructure details, so you can enjoy a healthier system in the
long run.&lt;/p>
&lt;p>This book will teach you how to create &lt;a rel="external" href="https://phpstan.org/">&lt;strong>PHPStan&lt;/strong>&lt;/a> rules from no knowledge, and then it will
guide you across many decoupling opportunities like, for example:&lt;/p>
&lt;ul>
&lt;li>web framework&lt;/li>
&lt;li>cli frameworks&lt;/li>
&lt;li>form validation&lt;/li>
&lt;li>orm and database&lt;/li>
&lt;li>test framework&lt;/li>
&lt;/ul>
&lt;p>Read more about the book: &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>Buy it here: &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="en"><title>Phel: The Lisp That Compiles to PHP</title><subtitle>A new functional language with full interoperability with 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/blog/phel-first-release/"/><id>https://chemaclass.com/blog/phel-first-release/</id><summary type="html">The new Functional Programming language build-in for PHP.</summary><content type="html">&lt;p>A new Functional Programming language built-in on the PHP ecosystem.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="the-phel-language">The Phel Language
&lt;a class="heading-anchor" href="#the-phel-language" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Phel is a Functional Programming (&lt;a rel="external" href="https://en.wikipedia.org/wiki/Functional_programming">FP&lt;/a>) language that compiles to PHP. It is a dialect of &lt;a rel="external" href="https://en.wikipedia.org/wiki/Lisp_(programming_language)">Lisp&lt;/a> inspired by Clojure and Janet.&lt;/p>
&lt;h2 id="features">Features
&lt;a class="heading-anchor" href="#features" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>Built on PHP’s ecosystem&lt;/li>
&lt;li>Good error reporting&lt;/li>
&lt;li>Different Datastructures (Arrays, Tables, and Tuples)&lt;/li>
&lt;li>Macros&lt;/li>
&lt;li>Recursive functions&lt;/li>
&lt;li>Powerful but simple Syntax&lt;/li>
&lt;li>REPL&lt;/li>
&lt;/ul>
&lt;h2 id="why-phel">Why Phel?
&lt;a class="heading-anchor" href="#why-phel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Phel is a creation of Jens Haase, and as he mentions on the website, “it is the result of many &lt;a rel="external" href="https://phel-lang.org/blog/functional-programming-in-php">failed attempts to do functional programming in PHP&lt;/a>”. He was looking for something with these characteristics:&lt;/p>
&lt;ul>
&lt;li>A LISP-inspired&lt;/li>
&lt;li>Functional Programming language&lt;/li>
&lt;li>That runs on cheap hosting providers&lt;/li>
&lt;li>It is easy to write and debug&lt;/li>
&lt;/ul>
&lt;p>From my point, it was ending May 2020 when I finished the
book &lt;a href="/readings/7-languages-in-7-weeks/">Seven Languages in Seven Weeks&lt;/a>, in which I learned the basics of Prolog, Erlang,
Clojure, Haskell… I even created a &lt;a rel="external" href="https://github.com/Chemaclass/7LangIn7Weeks">repository in GitHub&lt;/a> to store my
progress over the weeks with these learnings.&lt;/p>
&lt;p>Suddenly, one day beginning of June 2020, I saw a post in Reddit’s PHP official channel, with a message of someone
mentioning this “&lt;strong>Phel&lt;/strong>” project, claiming to be a &lt;strong>“functional programming language” written in PHP&lt;/strong>!&lt;/p>
&lt;p>I’ve worked with PHP for around 8 years so far, and I always try to combine OOP with FP as much as possible (because I
believe both paradigms are better combined; they are not necessarily exclusive), and a new dialect of Lisp fully written
in native &lt;strong>PHP 7.4&lt;/strong> sounded really exciting. I decided to take a look at it. I wanted to see the code.&lt;/p>
&lt;p>The fresh readings from &lt;a rel="external" href="https://x.com/matthiasnoback">Mathias NoBack&lt;/a> books such
as &lt;a href="/readings/object-design-style-guide">Object Design Style Guide&lt;/a>,
and &lt;a href="/readings/advance-web-application-architecture/">Advanced Web Application Architecture&lt;/a>, gave me the courage to try
out what I learned and put it for real in a project. This was (and still is) a beautiful challenge, which helps me to
test myself and grow professionally at the same time.&lt;/p>
&lt;p>My first commit was done on 6 June 2020, and since then I’ve been dedicating a little time each day during my free
hours to its development.
It helps me to learn more about FP, languages’ internal design, and best practices on testing and software design
architecture in general.&lt;/p>
&lt;p>I started applying minor changes until I ended refactoring the whole compiler structure (among other things) in order to
make the modules easier to read and understand. Psalm, strict types, good test coverage, unifying code style… These were
some of my favorite topics.&lt;/p>
&lt;h2 id="example-of-phel-code">Example of Phel code
&lt;a class="heading-anchor" href="#example-of-phel-code" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>The following example gives a short impression of how Phel looks like:&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 a 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 a variable with name &amp;quot;my-name&amp;quot; and value &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 a func with name &amp;quot;print-name&amp;quot; and one argument&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># Call the function&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="current-status-of-phel">Current status of Phel
&lt;a class="heading-anchor" href="#current-status-of-phel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>We prepared an easy &lt;a rel="external" href="https://phel-lang.org/documentation/getting-started/">Getting Started Guide&lt;/a>&lt;/li>
&lt;li>We prepared an easy GitHub Repository with a &lt;a rel="external" href="https://github.com/phel-lang/phel-scaffolding">Phel Scaffolding Template&lt;/a>&lt;/li>
&lt;li>We just released the first official version: &lt;a rel="external" href="https://github.com/phel-lang/phel-lang/tags">0.1.0&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Check out the official website with all documentation: &lt;a rel="external" href="https://phel-lang.org/">https://phel-lang.org/&lt;/a>&lt;/p>
&lt;hr />
&lt;h3 id="also-recommended">Also recommended
&lt;a class="heading-anchor" href="#also-recommended" 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="en"><title>To Mock or Not to Mock</title><subtitle>How to escape the mocking hell</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/blog/to-mock-or-not-to-mock/"/><id>https://chemaclass.com/blog/to-mock-or-not-to-mock/</id><summary type="html">Mocking is useful, but 'what to mock' usually turns out to be a more complicated than expected if you don't treat this carefully.</summary><content type="html">&lt;p>Mocking is useful, but “what to mock” usually turns out to be more complicated than expected if you don’t treat
this carefully.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h4 id="how-to-escape-the-mocking-hell">How to escape the mocking hell
&lt;a class="heading-anchor" href="#how-to-escape-the-mocking-hell" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;p>What is actually happening when we create a mock? Which types of mocks are there? Is mocking good or bad? Well, as
always, everything depends on the context. And here we will consider some of the main situations about when to mock and
when not to mock, but especially why.&lt;/p>
&lt;h2 id="what-happens-when-you-mock-something">What happens when you mock something?
&lt;a class="heading-anchor" href="#what-happens-when-you-mock-something" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>First, we should define what is a mock:&lt;/p>
&lt;blockquote>
&lt;p>In a unit test, mock objects can simulate the behavior of complex, real objects and are therefore useful when it is impractical or impossible to incorporate a real object into a unit test.&lt;/p>
&lt;/blockquote>
&lt;p>Mocking makes sense in a &lt;em>unit testing&lt;/em> context. An integration test should go through the real implementation checking
the integration between multiple units, which are even allowed to talk to the DB or File IO: infrastructure code.
Therefore we should agree that &lt;em>a unit test is a fast and deterministic test that doesn’t rely on external dependencies
and doesn’t require any special context to run&lt;/em>.&lt;/p>
&lt;p>Mock objects meet the &lt;em>interface&lt;/em> requirements. In consequence, they allow us to write and unit-test functionality
without calling complex underlying or collaborating classes.&lt;/p>
&lt;p>A mock is a test double that stands in for real implementation code during the unit testing process. It is also capable
of producing assertions about how it was manipulated by the test subject during the test run.&lt;/p>
&lt;blockquote>
&lt;p>I strongly recommend you to read this post if you want to get into the details of why &lt;a rel="external" href="https://medium.com/javascript-scene/mocking-is-a-code-smell-944a70c90a6a">Mocking is a code smell&lt;/a> (Topics like these: What is a mock? What is a unit test? What is test coverage? What is tight coupling? What causes tight coupling? What does composition have to do with mocking? How do we remove coupling? and more!)&lt;/p>
&lt;/blockquote>
&lt;h2 id="the-problem-with-mocking">The problem with mocking
&lt;a class="heading-anchor" href="#the-problem-with-mocking" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>When you mock you are overriding the logic of the mocked class. The real logic is getting hidden behind the scenes and
there is actually where bugs love to live. Consider that:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>The mock may have attributes, methods, or arguments that the real object doesn’t.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The mock’s &lt;em>return values may differ from the real objects’ return values&lt;/em>. For example, it may return a different
type of object that has different attributes.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The mock’s &lt;em>side effects and behavior may differ from the real objects’ ones&lt;/em>. For example, maybe the mock fails to
raise an exception when the real object would raise it.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="alternatives-to-mocking">Alternatives to mocking
&lt;a class="heading-anchor" href="#alternatives-to-mocking" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>“Are you saying that mocking is bad and we shouldn’t mock?!” No.&lt;/p>
&lt;p>It depends on what you are “overriding”.&lt;/p>
&lt;ul>
&lt;li>Is your business domain logic what you are mocking? Then it’s wrong.&lt;/li>
&lt;li>Is the connection to the DB what you are mocking? Then it’s right.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>It depends on the context of the logic and where that logic belongs.&lt;/p>
&lt;/blockquote>
&lt;p>Is it part of your business domain logic? Then you shouldn’t mock it but instantiate it.&lt;/p>
&lt;p>Is it part of any infrastructure dependency like DB connection, IO file system, Network, or any external service that
has nothing to do directly with your business domain? Then &lt;em>mock it using abstractions/interfaces&lt;/em>.&lt;/p>
&lt;p>The interface should be the &lt;em>contract between your business domain logic and its external infrastructure dependencies&lt;/em>.
Imagine how easy it would be to unit test your domain logic by instantiating it and calling their methods with different
arguments expecting different inputs under your entire control.&lt;/p>
&lt;h2 id="some-tricks">Some tricks
&lt;a class="heading-anchor" href="#some-tricks" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>When you are writing a unit test:&lt;/p>
&lt;ul>
&lt;li>Try to instantiate your classes first.&lt;/li>
&lt;li>Avoid mocking concrete classes. I wrote an article exclusively about this:
encouraging &lt;a rel="external" href="https://medium.com/swlh/final-classes-in-php-9174e3e2747e">final classes&lt;/a> and interfaces.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Mock interfaces. Instantiate concrete classes.&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>“Excessive use of mocks leads to legacy code.” - Philippe Boargau&lt;/p>
&lt;h3 id="how-can-we-avoid-excessive-mocking">How can we avoid excessive mocking?
&lt;a class="heading-anchor" href="#how-can-we-avoid-excessive-mocking" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Favor immutable state over a mutable state.&lt;/li>
&lt;li>Make dependencies explicit.&lt;/li>
&lt;li>Program to an interface, not to an implementation.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="/images/blog/2021-01-11/footer.webp" alt="mock interfaces, instantiate concrete classes" />&lt;/p>
&lt;hr />
&lt;h4 id="references">References
&lt;a class="heading-anchor" href="#references" 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="en"><title>Never Use array_merge in a Loop</title><subtitle>The spread operator to the rescue</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/blog/array-merge-in-loop/"/><id>https://chemaclass.com/blog/array-merge-in-loop/</id><summary type="html">Using array_merge inside a loop is a performance killer. The spread operator will help you to improve this by flatting the array.</summary><content type="html">&lt;p>Using array_merge inside a loop is a performance killer.
The spread operator will help you to improve this by flatting the array.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="flattening-a-one-level-array">Flattening a one-level array
&lt;a class="heading-anchor" href="#flattening-a-one-level-array" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>I have seen people using the array_merge function in a loop like:&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>This is a very bad practice because it’s a (memory) performance killer!
Instead, you should use the spread operator (in PHP since 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="unpacking-an-assoc-array">Unpacking an assoc-array
&lt;a class="heading-anchor" href="#unpacking-an-assoc-array" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>What if you had an assoc-array instead like this one?&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>In that case, you will need to unpack its values:&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>In Functional Programming, this is known as flatting a list.
No loops &amp;amp; no more performance problem.&lt;/p>
&lt;h2 id="flatting-a-multilevel-array">Flatting a multilevel array
&lt;a class="heading-anchor" href="#flatting-a-multilevel-array" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>What if you wanted to flat a multilevel array like this one?&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>Or like this one, even with key-values?&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>In these cases, you might want to use the internal standard library:&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="which-flattening-approach-to-reach-for">Which flattening approach to reach for
&lt;a class="heading-anchor" href="#which-flattening-approach-to-reach-for" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Usually, being aware of how to flat a “2 level” array might be sufficient:&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>Otherwise, the internal standard library will help you deal with it.&lt;/p>
&lt;hr />
&lt;h3 id="references">References
&lt;a class="heading-anchor" href="#references" 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="en"><title>Typed Arrays in PHP</title><subtitle>An alternative to the missing feature in 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/blog/typed-arrays-php/"/><id>https://chemaclass.com/blog/typed-arrays-php/</id><summary type="html">Argument unpacking, function variable argument list, and variadics function.</summary><content type="html">&lt;p>Argument unpacking, function variable argument list, and variadics function.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h3 id="the-perfect-combination">The perfect combination
&lt;a class="heading-anchor" href="#the-perfect-combination" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Argument unpacking: Instead of passing the argument itself to the function, the elements it contains will be passed (as individual arguments).&lt;/li>
&lt;li>Function variable argument list: The arguments will be passed into the given variable as an array.&lt;/li>
&lt;li>Variadics function: Types can be checked with a type-hint.&lt;/li>
&lt;/ul>
&lt;p>We will use this snippet for our examples.
Having a class, &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 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);"> Using PHP 8 constructor property promotion&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);"> We create a list of 6 customers&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>Whenever we want to manipulate a list of Customers, we can pass as an argument: &lt;code>…$customers&lt;/code>.&lt;/p>
&lt;h2 id="how-we-used-to-do-it">How we used to do it
&lt;a class="heading-anchor" href="#how-we-used-to-do-it" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>We define the array type using the PHPDoc param comment block above. But we cannot define the real type of the item. The code will still run without any problem passing any type on that argument &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 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 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>
&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);"> ... some irrelevant logic for this example&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>The code below would work at “compile-time”. But it might fail at “runtime”.&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>An alternative (recommended!) might be to extract that logic and ask for the particular type in order to “check it” at runtime in that particular moment, failing if one of the items wasn’t really a 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 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 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>
&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);"> ... some irrelevant logic for this example&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Everything here below would work at “compile-time”. It will for sure break during “runtime” if the &lt;code>createInvoice(Customer $customer)&lt;/code> receives something different than a 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);"> won&amp;#39;t work&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>By doing that &lt;code>createInvoice(Customer $customer)&lt;/code> we are ensuring the type of the argument, which is good! But, what about going one step further. Could we check the types of the elements when calling the function &lt;code>createInvoiceForCustomers(array $customers)&lt;/code>, even making the IDE complain when the types are not right?&lt;/p>
&lt;p>Well, that’s actually what Generics are for, but sadly, they are not yet in PHP. Not even in the upcoming PHP 8. Hopefully in a near future, but we cannot predict that for now.
Luckily, we have currently an alternative nowadays, but it’s not that popular. It has its own “pros” and “cons”, so let’s take a look at an example first:&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>Everything here below would work at “compile-time”. It will for sure break during “runtime” if the &lt;code>createInvoice()&lt;/code> receives something different than a 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>&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);"> This is not even possible to write. The IDE will yell at you. &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);"> It&amp;#39;s expecting a `Customer`, but `AnyOtherType` is given:&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>We can easily type a list of any concrete type.&lt;/li>
&lt;/ul>
&lt;h3 id="cons">CONS
&lt;a class="heading-anchor" href="#cons" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>We better define our functions with one or two arguments max. Otherwise, it would be too complicated to read.&lt;/li>
&lt;/ul>
&lt;h3 id="important-remarks">Important remarks
&lt;a class="heading-anchor" href="#important-remarks" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>It needs to be the last taken argument of a function.&lt;/li>
&lt;li>It helps to minimize the number of arguments that we use in a function.&lt;/li>
&lt;/ul>
&lt;h2 id="variadics-simulate-typed-arrays-use-them-wisely">Variadics simulate typed arrays, use them wisely
&lt;a class="heading-anchor" href="#variadics-simulate-typed-arrays-use-them-wisely" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Argument unpacking is a great feature that, in combination with variadic functions, can help us to simulate typed arrays. With great power comes great responsibility, and this is no exception.
We need to learn about our toolbox in order to use it wisely.&lt;/p>
&lt;p>&lt;img src="/images/blog/2020-10-13/footer.webp" alt="typed arrays with variadics in php" />&lt;/p>
&lt;hr />
&lt;h3 id="references">References
&lt;a class="heading-anchor" href="#references" 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">Argument unpacking&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list">Function variable argument list&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://wiki.php.net/rfc/variadics">Variadics function&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="en"><title>Object design style guide</title><subtitle>Powerful Techniques for Creating Flexible, Readable, and Maintainable Object-Oriented Code in Any OO Language</subtitle><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/readings/object-design-style-guide/"/><id>https://chemaclass.com/readings/object-design-style-guide/</id><summary type="html">Matthias Noback's practical guide to writing flexible, readable, and maintainable object-oriented code, with techniques applicable to any OO language from Python to PHP.</summary><content type="html">&lt;p>Objects are the central concept of languages like Java, Python, C#. Applying best practices for object design means that
your code will be easy to read, write, and maintain.&lt;/p>
&lt;p>This book captures dozens of techniques for creating pro-quality OO code that can stand the
test of time.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>Examples are in an instantly-familiar pseudocode, teaching techniques you can apply to any OO language, from C++ to PHP.&lt;/p></content></entry><entry xml:lang="en"><title>Advanced Web Application Architecture</title><subtitle>The best guide that brings your coding skills a level up.</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/readings/advance-web-application-architecture/"/><id>https://chemaclass.com/readings/advance-web-application-architecture/</id><summary type="html">The best guide that brings your coding and architecture skills a level up. All the modern PHP features combined with the elegance of a well designed modular design.</summary><content type="html">&lt;p>This book helps you get your web applications back in shape. It contains many techniques for decoupling from
infrastructure (like the framework or the database).&lt;/p>
&lt;p>“The best guide that brings your coding and architecture skills a level up. All the modern PHP features combined with the elegance of a well-designed modular design.”&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>In Part 1 we unlock a collection of design patterns which help you establish a clean separation between core and
infrastructure code. Part 2 shows how these design patterns resonate at a higher level with architectural concepts like
layers, ports and adapters (a.k.a. Hexagonal architecture). The book finishes with a discussion of testing strategies and design trade-offs.&lt;/p>
&lt;h3 id="what-you-ll-learn">What you’ll learn
&lt;a class="heading-anchor" href="#what-you-ll-learn" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Separating mixed code into core and infrastructure code by refactoring into patterns.&lt;/li>
&lt;li>Dividing your code into layers, and making a clear distinction between an application’s ports and adapters.&lt;/li>
&lt;li>Testing decoupled applications.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Buy the book: &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="design-patterns-for-modernizing-legacy-code-bases">Design patterns for modernizing legacy code bases
&lt;a class="heading-anchor" href="#design-patterns-for-modernizing-legacy-code-bases" 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="en"><title>Strict Types in 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/blog/strict-types/"/><id>https://chemaclass.com/blog/strict-types/</id><summary type="html">Why declaring strict_types in PHP improves code readability and prevents silent type coercion bugs.</summary><content type="html">&lt;p>In December 2015, PHP 7 introduced scalar type declarations and with it the strict types flag. What is this new feature?&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>The good thing about declaring a PHP file as strict is that it actually applies to &lt;strong>ONLY the current file&lt;/strong>. It ensures that this file has strict types, but it doesn’t apply to any other file in the whole project. It allows you to do, step by step, this migration from non-strict code to strict code, especially for new files or projects.&lt;/p>
&lt;blockquote>
&lt;p>To enable the strict mode, a single declare directive must be placed at the top of the file. This means that the strictness of typing for scalars is configured on a per-file basis. This directive not only affects the type declarations of parameters, but also a function’s return type.&lt;/p>
&lt;/blockquote>
&lt;h2 id="strict-types-affect-coercion-types">Strict types affect coercion types
&lt;a class="heading-anchor" href="#strict-types-affect-coercion-types" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Using a type hint without &lt;code>strict_types&lt;/code> may lead to subtle bugs.&lt;/p>
&lt;p>Without this, &lt;code>int $x&lt;/code> meant &lt;code>$x must have a value coercible to an int&lt;/code>. Any value that could be coerced to an int would pass the hint type, including:&lt;/p>
&lt;ul>
&lt;li>a proper &lt;code>int&lt;/code> (example: 42 -&amp;gt; 42)&lt;/li>
&lt;li>a &lt;code>float&lt;/code> (example: 13.1459 -&amp;gt; 13)&lt;/li>
&lt;li>a &lt;code>bool&lt;/code> (example: true -&amp;gt; 1)&lt;/li>
&lt;li>a &lt;code>null&lt;/code> (example: null -&amp;gt; 0)&lt;/li>
&lt;li>a &lt;code>string&lt;/code> with leading digits (example: “15 Trees” -&amp;gt; 15)&lt;/li>
&lt;/ul>
&lt;p>By setting &lt;code>strict_types=1&lt;/code>, you tell the engine that int $x means $x must only be an int proper, no type coercion allowed. You have the great assurance you’re getting exactly and only what was given, without any conversion or potential loss.&lt;/p>
&lt;h2 id="who-should-care-about-this-strict-type-line">Who should care about this “strict type” line?
&lt;a class="heading-anchor" href="#who-should-care-about-this-strict-type-line" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Actually, declare(strict_types=1); is more for the reader than for the writer. Why? Because it will explicitly tell the reader:&lt;/p>
&lt;ul>
&lt;li>The types in this current scope (file/class) are treated strictly.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>‘strict_types=1’ is more for the reader than for the writer&lt;/p>
&lt;/blockquote>
&lt;p>The writer just needs to maintain such strictness while writing the expected behavior. That said, as a writer, you should care about your readers, which also includes your future self. Because you are going to be one of them.&lt;/p>
&lt;p>&lt;img src="/images/blog/2020-08-09/footer.webp" alt="strict_types declaration in php" />&lt;/p>
&lt;hr />
&lt;h2 id="references">References
&lt;a class="heading-anchor" href="#references" 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">Scalar type declarations&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">What do strict types do in PHP&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="en"><title>Final Classes in PHP | Java | Any</title><subtitle>Final, or not final, that's the question</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/blog/final-classes/"/><id>https://chemaclass.com/blog/final-classes/</id><summary type="html">Clear contracts, isolated side effects, testability, low complexity and cognitive load, code fluidity, and confidence in yourself.</summary><content type="html">&lt;p>Clear contracts, isolated side effects, testability, low complexity and cognitive load, code fluidity, and confidence in yourself.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="motivation">Motivation
&lt;a class="heading-anchor" href="#motivation" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="reduce-the-scope-visibility-to-the-minimum">Reduce the scope visibility to the minimum
&lt;a class="heading-anchor" href="#reduce-the-scope-visibility-to-the-minimum" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>When you see a class prefixed with final you will prevent a particular class to be extended by any other, which not only makes it more readable but also makes you be sure that the scope of the logic where you are is limited to that particular class.&lt;/p>
&lt;h3 id="encourage-composition-over-inheritance-mentality">Encourage “composition over inheritance” mentality
&lt;a class="heading-anchor" href="#encourage-composition-over-inheritance-mentality" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>The Open-Close Principle states: open for extension but closed for modification.&lt;/p>
&lt;p>If for any reason, a good one you should be completely aware of, you decide to create an inheritance there, well, then just drop the final keyword and you are good to go.&lt;/p>
&lt;p>When you “by default” can’t extend from a class (because it’s final), you will help yourself by thinking about using composition instead of inheritance.&lt;/p>
&lt;h2 id="why-isn-t-this-class-final">Why isn’t this class final?
&lt;a class="heading-anchor" href="#why-isn-t-this-class-final" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>If we aim for composition over inheritance, then we should try to avoid inheritance as much as possible, and use it only when it’s really necessary. Inheritance is often misused in OOP.&lt;/p>
&lt;h3 id="misconception">Misconception
&lt;a class="heading-anchor" href="#misconception" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>When we first taught OOP, we usually introduced the classic inheritance example.&lt;/p>
&lt;p>Nonetheless, when Alan Kay created Smalltalk, the inheritance was never the main concept of it. The main concept was messaging, which is that you can send messages to objects and they encapsulate the data and logic in it, and you can change their behavior by using different objects, which is actually composition. But the concept of inheritance is so popular that it eventually overshadows composition.&lt;/p>
&lt;h3 id="benefits">Benefits
&lt;a class="heading-anchor" href="#benefits" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Clear contracts. Using interfaces will force you to think in terms of communication between objects.&lt;/li>
&lt;li>Isolated, side effect free code units. Injecting interfaces only as dependencies will remove every nasty side effect around the code you are working on.&lt;/li>
&lt;li>Testability. Mocking dependencies is extremely easy when they are interfaces.&lt;/li>
&lt;li>Low, manageable complexity. Since everything is isolated, you won’t need to worry about rippling changes. This dramatically decreases the complexity of your code.&lt;/li>
&lt;li>Low cognitive load. With decreased complexity, your brain will be free to focus on what matters.&lt;/li>
&lt;li>Code fluidity. By removing any unnecessary coupling, you will be able to move things around way more easily than before.&lt;/li>
&lt;li>Confidence in yourself. Being able to test your code in isolation so well will give you a wonderful sense of confidence in changing it.&lt;/li>
&lt;/ul>
&lt;h2 id="composition-over-inheritance">Composition over inheritance
&lt;a class="heading-anchor" href="#composition-over-inheritance" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>If you feel the need to reconfigure an object, to change parts of an algorithm, or to rewrite part of the implementation, consider creating a new class instead of overriding an existing class.
If you need to represent a hierarchy of classes, where subclasses are proper substitutes for their parent classes. This would be the classic situation where you may still consider inheritance. However, the result may even be better if you don’t inherit from concrete parent classes but from abstract interfaces.&lt;/p>
&lt;h3 id="what-you-should-start-doing-instead">What you should start doing instead
&lt;a class="heading-anchor" href="#what-you-should-start-doing-instead" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Use interfaces to define the contracts between your classes.&lt;/li>
&lt;li>Use final classes to implement behavior for those interfaces.&lt;/li>
&lt;li>Use composition (using dependency injection through constructor) to put things together and prevent complexity.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Interfaces -&amp;gt; Final classes -&amp;gt; Composition&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="/images/blog/2020-06-06/footer.webp" alt="interfaces, final classes and composition" />&lt;/p></content></entry><entry xml:lang="en"><title>Symfony 5</title><subtitle>Symfony 5: The Fast Track</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/readings/symfony-5/"/><id>https://chemaclass.com/readings/symfony-5/</id><summary type="html">Fabien Potencier's official guide to building web applications with Symfony 5, covering the framework from scratch to production deployment.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>
&lt;p>This book, written by Symfony’s creator, lays out a pragmatic approach to developing web applications with Symfony 5:
from scratch to production. Whether you are discovering Symfony for the first time or refreshing your knowledge, this
practical guide provides the definitive introduction to modern Symfony applications.&lt;/p></content></entry></feed>