<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    
    <title>Belgeek</title>
    <description>Shared notes, thoughts and eventual nonsense... Mostly harmless...</description>
    <link>https://notes.belgeek.dev/</link>
    <atom:link href="https://notes.belgeek.dev/feed_rss_created.xml" rel="self" type="application/rss+xml" />

    
    <managingEditor>Dmitri Goosens &lt;notes@belgeek.dev&gt;</managingEditor>
    
    <language>en</language>

    
    <pubDate>Mon, 18 Nov 2024 08:28:07 -0000</pubDate>
    <lastBuildDate>Mon, 18 Nov 2024 08:28:07 -0000</lastBuildDate>
    <ttl>1440</ttl>

    
    <generator>MkDocs RSS plugin - v1.16.0</generator>

    
    

    
    
    <item>
      <title>Gitlab :: How to avoid duplicate pipelines</title>
      
      
        
      <author>dgoosens</author>
        
      
      
      
        
      <category>OSS</category>
        
      <category>git</category>
        
      <category>gitlab</category>
        
      <category>tools</category>
        
      
      <description>&lt;h1 id=&#34;gitlab-how-to-avoid-duplicate-pipelines&#34;&gt;Gitlab :: How to avoid duplicate pipelines&lt;a class=&#34;headerlink&#34; href=&#34;#gitlab-how-to-avoid-duplicate-pipelines&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;When one has defined a CI pipeline in &lt;a href=&#34;https://gitlab.com/&#34;&gt;Gitlab&lt;/a&gt; that runs on every push to your repository and one that runs for merge requests, one may end up with duplicate pipelines running waisting money and resources&lt;!-- more --&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What happens is quite simple, a first pipeline is started when one pushes to the repository and, if the branch is part or a Merge Request, another pipeline is started when this merge request is updated.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;gitlab.gif&#34; src=&#34;../../../../gitlab-ci_avoid-duplicate-pipelines/gitlab.gif&#34; /&gt;&lt;/p&gt;
&lt;p&gt;There is a rather simple &lt;code&gt;workflow&lt;/code&gt; rule to avoid this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;c1&#34;&gt;# .gitlab-ci.yaml&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;# ... stuff before&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;workflow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;$CI_PIPELINE_SOURCE == &amp;#39;merge_request_event&amp;#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;$CI_OPEN_MERGE_REQUESTS == null&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;# ... stuff after&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;if: $CI_PIPELINE_SOURCE == &#39;merge_request_event&#39;&lt;/code&gt; makes sure the pipeline is triggered for every push to a Merge Request&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if: $CI_OPEN_MERGE_REQUESTS == null&lt;/code&gt; makes sure the pipeline is triggered when there is no open merge request associated with the branch&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With these two simple &lt;code&gt;workflow&lt;/code&gt; lines, duplicate pipelines become impossible as you&#39;re either in the first or in the second scenario, but never in both.&lt;/p&gt;</description>
      <link>https://notes.belgeek.dev/2024/02/27/gitlab--how-to-avoid-duplicate-pipelines/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Tue, 27 Feb 2024 00:00:00 +0000</pubDate>
      <source url="https://notes.belgeek.dev/feed_rss_created.xml">Belgeek</source>
      
      <guid isPermaLink="true">https://notes.belgeek.dev/2024/02/27/gitlab--how-to-avoid-duplicate-pipelines/</guid>
      
      <enclosure url="https://notes.belgeek.dev/assets/images/social/2024/02/27/gitlab--how-to-avoid-duplicate-pipelines.png" type="image/png" length="61546" />
      
    </item>
    
    <item>
      <title>Rust -- Integer Overflow</title>
      
      
        
      <author>dgoosens</author>
        
      
      
      
        
      <category>OSS</category>
        
      <category>Rust</category>
        
      
      <description>&lt;h1 id=&#34;rust-integer-overflow&#34;&gt;Rust -- Integer Overflow&lt;a class=&#34;headerlink&#34; href=&#34;#rust-integer-overflow&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Rust has a brilliant way to give the developer control over integer overflow...&lt;br /&gt;
Let&#39;s have look  &lt;!-- more --&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Integer overflow&lt;/strong&gt; occurs when one tries to set a value that is higher than the highest accepted value of an integer.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;OVERFLOW!&#34; src=&#34;../../../../rust_integer-overflow/overflow.gif&#34; /&gt;&lt;/p&gt;
&lt;p&gt;For instance, an &lt;code&gt;u8&lt;/code&gt;, which is a &lt;code&gt;unsigned 8-bit long integer&lt;/code&gt; accepts a value between &lt;code&gt;0&lt;/code&gt; &amp;amp; &lt;code&gt;255&lt;/code&gt;&lt;br /&gt;
When trying to set its value to &lt;code&gt;256&lt;/code&gt; or higher, one gets an integer overflow &lt;/p&gt;
&lt;div class=&#34;admonition note&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Note&lt;/p&gt;
&lt;p&gt;Integer overflow includes what is called &lt;em&gt;integer underflow&lt;/em&gt; when reaching the lower limits.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;AFAIK, most languages do not come packed with native methods to deal with integer overflow.&lt;br /&gt;
Even in so-called advanced languages like Java and GoLang, one has to use very hacky code to detect and handle these. &lt;/p&gt;
&lt;p&gt;In Rust, there are two possible reactions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;when compiling in &lt;code&gt;debug&lt;/code&gt; mode, the compiler will panic about integer overflow&lt;/li&gt;
&lt;li&gt;when compiling in &lt;code&gt;--release&lt;/code&gt; mode, there are no checks for integer overflow and rust will use &lt;strong&gt;complement wrapping&lt;/strong&gt; (ie &lt;code&gt;256&lt;/code&gt; becomes &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;257&lt;/code&gt; becomes &lt;code&gt;1&lt;/code&gt; etc., just like it would happen in Java or Go)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;BUT&lt;/strong&gt; there are methods to avoid this default behavior in release mode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;wrapping_*&lt;/code&gt; methods make the wrapping explicit&lt;br /&gt;
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// for instance&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;u8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;u8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wrapping_add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// will be 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;checked_*&lt;/code&gt; methods will return &lt;code&gt;None&lt;/code&gt; when integer overflow
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// for instance&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;u8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;u8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;match&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;checked_add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Some&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;num&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;fm&#34;&gt;panic!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;You overflowed baby !&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// checked_* methods will return None on overflow &lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// and the value if everything is ok&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;overflowing_*&lt;/code&gt; methods will return a &lt;code&gt;tuple(Self, bool)&lt;/code&gt; with the integer, eventually overflown and a boolean that indicates whether there has been integer overflow
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;u8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;u8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;overflowing_add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;fm&#34;&gt;panic!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;quot;You overflowed baby !&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;saturating_*&lt;/code&gt; methods will prevent the overflow by either not going higher than the MAX or lower than the MIN
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;u8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;u8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;saturating_add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// will return 255 as that is the MAX value of an u8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Strangely enough... overflow appears not to be dealt with for floats and other numeric values...&lt;/p&gt;
&lt;div class=&#34;admonition info&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Info&lt;/p&gt;
&lt;p&gt;For the full Rust info, start here:&lt;br /&gt;
&lt;a href=&#34;https://doc.rust-lang.org/book/ch03-02-data-types.html#integer-overflow&#34;&gt;https://doc.rust-lang.org/book/ch03-02-data-types.html#integer-overflow&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</description>
      <link>https://notes.belgeek.dev/2023/12/27/rust----integer-overflow/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Wed, 27 Dec 2023 00:00:00 +0000</pubDate>
      <source url="https://notes.belgeek.dev/feed_rss_created.xml">Belgeek</source>
      
      <guid isPermaLink="true">https://notes.belgeek.dev/2023/12/27/rust----integer-overflow/</guid>
      
      <enclosure url="https://notes.belgeek.dev/assets/images/social/2023/12/27/rust----integer-overflow.png" type="image/png" length="58024" />
      
    </item>
    
    <item>
      <title>PHP: Xdebug in PHPStorm on, almost, all docker environments, is easy</title>
      
      
        
      <author>dgoosens</author>
        
      
      
      
        
      <category>apiplatform</category>
        
      <category>docker</category>
        
      <category>frankenphp</category>
        
      <category>php</category>
        
      <category>symfony</category>
        
      <category>xdebug</category>
        
      
      <description>&lt;h1 id=&#34;php-xdebug-in-phpstorm-on-almost-all-docker-environments-is-easy&#34;&gt;PHP: Xdebug in PHPStorm on, almost, all docker environments, is easy&lt;a class=&#34;headerlink&#34; href=&#34;#php-xdebug-in-phpstorm-on-almost-all-docker-environments-is-easy&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Xdebug is a very powerful debugging tool, well actually, probably the God tool of all tools if you&#39;re debugging.&lt;br /&gt;
It lets you pause the execution of your app and lets you analyze, in full context what is happening, step debug etc etc.&lt;br /&gt;
Even though the setup has gotten drastically easier, thanks to the awesome effort Derick Rethans, its creator, has put in it, it still appears to scare of some developers... Let us hope this DevNote helps.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- more --&gt;

&lt;p&gt;I have not slept for days, almost a week, after I read Steve&#39;s tweet talking about &lt;a href=&#34;https://xdebug.org&#34;&gt;Xdebug&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://x.com/JustSteveKing/status/1718560158257700886?s=20&#34;&gt;&lt;img alt=&#34;Steve admitting he is not using Xdebug&#34; src=&#34;../../../../php_xdebug-on-docker-frankenphp/tweet-steve.png&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Not you Steve!&lt;br /&gt;
How can you do this to &lt;a href=&#34;https://phpc.social/@derickr&#34;&gt;Derick&lt;/a&gt;, one of the most brilliant minds in the PHP community?&lt;br /&gt;
How?&lt;br /&gt;
Why?&lt;/p&gt;
&lt;p&gt;So I decided I could no longer live with this and that I ought to, at least, try to show Steve the way...&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;This is the way&#34; src=&#34;/common/this-is-the-way.gif&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;git-the-code&#34;&gt;Git the code&lt;a class=&#34;headerlink&#34; href=&#34;#git-the-code&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now I know Steve is currently playing with &lt;a href=&#34;https://api-platform.com/&#34;&gt;ApiPlatform&lt;/a&gt; as he finally, after more than four years, discovered he has been doing APIs all wrong:&lt;/p&gt;
&lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube.com/embed/NpfnnXi1CHI?si=h8rbXfbEojNO9EvN&#34; title=&#34;YouTube video player&#34; frameborder=&#34;0&#34; allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&#34; allowfullscreen&gt;&lt;/iframe&gt;

&lt;div class=&#34;admonition info&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Info&lt;/p&gt;
&lt;p&gt;Do check out his video with Kevin Dunglas, the creator of ApiPlatform if you also want to have the same revelation:&lt;br /&gt;
&lt;a href=&#34;https://www.youtube.com/watch?v=H5nnVXYxY5o&#34;&gt;https://www.youtube.com/watch?v=H5nnVXYxY5o&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;So, let us set up a real quick ApiPlatform project and configure Xdebug.
(For the full ApiPlatform documentation, see &lt;a href=&#34;https://api-platform.com/docs/distribution/&#34;&gt;here&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Generate a Github clone (&lt;a href=&#34;https://github.com/new?template_name=api-platform&amp;amp;template_owner=api-platform&#34;&gt;here&lt;/a&gt;), &lt;code&gt;git clone&lt;/code&gt; and your done...&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;steve
├── api
├── compose.override.yaml
├── compose.prod.yaml
├── compose.yaml
├── helm
├── LICENSE
├── pwa
├── README.md
└── update-deps.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now the default ApiPlatform comes with a lot of features, but in the end, the &lt;code&gt;/api&lt;/code&gt; directory is just a PHP project encapsulated in a certain Docker environment...&lt;/p&gt;
&lt;p&gt;How it is encapsulated really is not very relevant... Except for one thing... The setup of your PHPStorm environment.&lt;/p&gt;
&lt;h2 id=&#34;setup-the-phpstorm-project&#34;&gt;Setup the PHPStorm project&lt;a class=&#34;headerlink&#34; href=&#34;#setup-the-phpstorm-project&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now, normally one would just create a new project of the root dir...
Yet, in that case, the &lt;a href=&#34;https://plugins.jetbrains.com/plugin/7219-symfony-support&#34;&gt;Symfony Support&lt;/a&gt; plugin, which is quite handy, will have some trouble figuring out where the files are located (and I have not found a setting that would make it possible to set a root path for the plugin).&lt;/p&gt;
&lt;p&gt;I have found it easier to do this in two steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;create a new project of the &lt;code&gt;/api&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;in the same window, create a second project of the root directory, and attach it to the &lt;code&gt;/api&lt;/code&gt; project&lt;br /&gt;
&lt;img alt=&#34;Attach a project in PHPStorm&#34; src=&#34;../../../../php_xdebug-on-docker-frankenphp/phpstorm-attach-project.png&#34; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the end, PHPStorm is smart enough to notice &lt;code&gt;/api&lt;/code&gt; is in the root directory...
But the Symfony Support plugin will work out of the box... Brilliant!&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;PHPStorm project listing&#34; src=&#34;../../../../php_xdebug-on-docker-frankenphp/phpstorm-project-listing.png&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;build&#34;&gt;Build&lt;a class=&#34;headerlink&#34; href=&#34;#build&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Following the documentation, we only need to build the docker environment, and we&#39;re all set.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;c1&#34;&gt;# in the root directory&lt;/span&gt;
docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;compose&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;build&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-cache
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once it is built, start the container:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;compose&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;up&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--wait
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;admonition info&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Info&lt;/p&gt;
&lt;p&gt;If you want to make your life easier with those docker commands, check out this article:
&lt;a href=&#34;../../04/the-makefile-for-symfony-apiplatform--frankenphp-projects/&#34;&gt;the MakeFile for Symfony, ApiPlatform &amp;amp; FrankenPHP projects&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;AND YOUR ALL DONE!&lt;/strong&gt;&lt;br /&gt;
Go to &lt;a href=&#34;https://localhost&#34;&gt;https://localhost&lt;/a&gt;, accept the local SSL cert, and you&#39;ll see the project running.&lt;br /&gt;
Yes, it is that easy!&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;ApiPlatform running&#34; src=&#34;../../../../php_xdebug-on-docker-frankenphp/apiplatform-localhost.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Click on API to see the API in action, and play with it...
(Do check out the future details in the ApiPlatform mentioned above).&lt;/p&gt;
&lt;p&gt;Now, the nice thing about FrankenPHP, that bundles the ApiPlatform package, is that it comes preloaded with Xdebug out of the box!&lt;/p&gt;
&lt;p&gt;Almost done...&lt;br /&gt;
Back to PHPStorm, for the final setup:&lt;/p&gt;
&lt;h2 id=&#34;configure-the-phpstorm-project&#34;&gt;Configure the PHPStorm project&lt;a class=&#34;headerlink&#34; href=&#34;#configure-the-phpstorm-project&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are 3 steps:&lt;/p&gt;
&lt;h3 id=&#34;1-setup-the-runtime&#34;&gt;1. Setup the runtime&lt;a class=&#34;headerlink&#34; href=&#34;#1-setup-the-runtime&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Go into the settings, select the &lt;code&gt;PHP&lt;/code&gt; tab, and click on the &lt;code&gt;...&lt;/code&gt; to set the CLI interpreter:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;PHPStorm PHP tab&#34; src=&#34;../../../../php_xdebug-on-docker-frankenphp/phpstorm-php-tab.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;In the upper left corner click on the &lt;code&gt;+&lt;/code&gt; to add a new one, and select &lt;code&gt;From Docker...&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Choose &lt;code&gt;Docker compose&lt;/code&gt;, select the configuration file, &lt;code&gt;./compose.yaml&lt;/code&gt; at the root of your project and finally, select &lt;code&gt;php&lt;/code&gt; as the service:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;PHPStorm, new CLI&#34; src=&#34;../../../../php_xdebug-on-docker-frankenphp/phpstorm-new-cli-interpreter.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Click OK, and you&#39;re all done:&lt;br /&gt;
You can give the interpreter a name... and as you can see &lt;strong&gt;Xdebug&lt;/strong&gt; is ready!&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;PHPStorm, CLI interpreters&#34; src=&#34;../../../../php_xdebug-on-docker-frankenphp/phpstorm-cli-interpreters.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;2-folder-mapping&#34;&gt;2. Folder mapping&lt;a class=&#34;headerlink&#34; href=&#34;#2-folder-mapping&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Back to the settings, go to the &lt;code&gt;Server&lt;/code&gt; tab under &lt;code&gt;PHP&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Click the &lt;code&gt;+&lt;/code&gt; button to add a new configuration, give it a name, set &lt;code&gt;localhost&lt;/code&gt; as host, &lt;code&gt;443&lt;/code&gt; as port, check the &lt;code&gt;Use path mappings...&lt;/code&gt; and simply map the &lt;code&gt;/api&lt;/code&gt; directory to &lt;code&gt;/app&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;PHPStorm servers tab&#34; src=&#34;../../../../php_xdebug-on-docker-frankenphp/phpstorm-servers-tab.png&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;3-xdebug-setup&#34;&gt;3. Xdebug setup&lt;a class=&#34;headerlink&#34; href=&#34;#3-xdebug-setup&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The final step is a personal preference...&lt;br /&gt;
You can either chose to enable Xdebug with a cookie or with a URL parameter, but I personally prefer to have it running all the time and only listen to it when I need to.&lt;/p&gt;
&lt;p&gt;In PHPstorm, open &lt;code&gt;api/frankenphp/conf.d/app.dev.ini&lt;/code&gt; and add the following lines:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;na&#34;&gt;xdebug.start_with_request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;yes&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;xdebug.log_level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first one will make sure Xdebug is running for every request, the second one disables the Xdebug logging which would pollute your console.&lt;/p&gt;
&lt;p&gt;Finally, create an &lt;code&gt;.env&lt;/code&gt; file at the root of the project and add the following lines:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;na&#34;&gt;XDEBUG_MODE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;debug,develop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are other ways to enable Xdebug, but IMHO, this is the easiest one.&lt;/p&gt;
&lt;h2 id=&#34;done&#34;&gt;Done !&lt;a class=&#34;headerlink&#34; href=&#34;#done&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You&#39;re all set...&lt;br /&gt;
Restart the docker environment:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;compose&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;up&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--wait
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Go to &lt;code&gt;/api/index.php&lt;/code&gt;, set a breakpoint wherever you want and click the &lt;code&gt;Start listening for PHP Debug Connections&lt;/code&gt; (you can easily add a shortcut for this, I&#39;ve set &lt;span class=&#34;keys&#34;&gt;&lt;kbd class=&#34;key-alt&#34;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&#34;key-shift&#34;&gt;Shift&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&#34;key-x&#34;&gt;X&lt;/kbd&gt;&lt;/span&gt;), and go to &lt;a href=&#34;https://localhost/docs&#34;&gt;https://localhost/docs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Xdebug in action in PHPStorm&#34; src=&#34;../../../../php_xdebug-on-docker-frankenphp/phpstorm-xdebug-in-action.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Now you can set breakpoints wherever you want, execute a query, or a CLI command, and Xdebug will pause the execution and lets you analyze the full context of your app.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Happy Debugging !&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;YES!&#34; src=&#34;/common/yes.gif&#34; /&gt;&lt;/p&gt;
&lt;p&gt;My pleasure Steve....&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;a class=&#34;headerlink&#34; href=&#34;#conclusion&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This procedure is more or less the same for any Docker environment as long as it bundles Xdebug...&lt;br /&gt;
Adding Xdebug to a Docker environment is a little out of scope of this DevNote...&lt;/p&gt;
&lt;div class=&#34;admonition info&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Info&lt;/p&gt;
&lt;p&gt;As I said,
« &lt;em&gt;Adding Xdebug to a Docker environment is a little out of scope of this DevNote...&lt;/em&gt; »&lt;br /&gt;
Say no more... &lt;a href=&#34;https://phpc.social/@heiglandreas&#34;&gt;Andreas Heigl&lt;/a&gt; wrote about it here: &lt;a href=&#34;https://andreas.heigl.org/2023/11/07/xdebug-in-docker/&#34;&gt;https://andreas.heigl.org/2023/11/07/xdebug-in-docker/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</description>
      <link>https://notes.belgeek.dev/2023/11/06/php-xdebug-in-phpstorm-on-almost-all-docker-environments-is-easy/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Mon, 06 Nov 2023 00:00:00 +0000</pubDate>
      <source url="https://notes.belgeek.dev/feed_rss_created.xml">Belgeek</source>
      
      <guid isPermaLink="true">https://notes.belgeek.dev/2023/11/06/php-xdebug-in-phpstorm-on-almost-all-docker-environments-is-easy/</guid>
      
      <enclosure url="https://notes.belgeek.dev/assets/images/social/2023/11/06/php-xdebug-in-phpstorm-on-almost-all-docker-environments-is-easy.png" type="image/png" length="74888" />
      
    </item>
    
    <item>
      <title>Bring Value to your code</title>
      
      
        
      <author>dgoosens</author>
        
      
      
      
        
      <category>ddd</category>
        
      <category>design pattern</category>
        
      <category>php</category>
        
      
      <description>&lt;h1 id=&#34;bring-value-to-your-code&#34;&gt;Bring Value to your code&lt;a class=&#34;headerlink&#34; href=&#34;#bring-value-to-your-code&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Through its iterations, PHP has become as appropriate as any other language to express Domain-Driven Design and implement other, more complex, concepts and patterns. One of these, one of the most important building blocks in Domain Driven Design (DDD), is the Value Object... But what is a Value Object? Is it only useful in DDD? How, where and why should one use them? Let&#39;s try to check it out...&lt;!-- more --&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;admonition info&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Info&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.phparch.com/magazine/2022/11/the-value-of-the-ast/&#34;&gt;&lt;img align=&#34;right&#34; alt=&#34;phparchitect-cover_2022-11.png&#34; src=&#34;../../../../ddd_value-objects/phparchitect-cover_2022-11.png&#34; width=&#34;30%&#34; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;
&lt;a href=&#34;https://www.phparch.com/magazine/2022/12/owning-the-web/&#34;&gt;&lt;img align=&#34;right&#34; alt=&#34;phparchitect-cover_2022-12.png&#34; src=&#34;../../../../ddd_value-objects/phparchitect-cover_2022-12.png&#34; width=&#34;30%&#34; /&gt;&lt;/a&gt;
&lt;strong&gt;This article was first published in two parts in PHP[Architect] in the editions or November &amp;amp; December 2022.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Once more, kudos to Larry GARFIELD (&lt;a href=&#34;https://phpc.social/@crell&#34;&gt;@crell&lt;/a&gt;), who was kind enough to go through this article and made sure the biggest non-sense was corrected.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Eric Evans, in &lt;em&gt;Domain-Driven Design&lt;/em&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; -- also called &lt;em&gt;the Blue Book&lt;/em&gt; or the DDD Bible -- gives the following definition of a Value Object:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An object that represents a descriptive aspect of the domain with no conceptual identity is called a VALUE OBJECT. VALUE OBJECTS are instantiated to represent elements of the design that we care about only for what they are, not who or which they are.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And in his &lt;em&gt;Implementing Domain-Driven Design&lt;/em&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, aka &lt;em&gt;the Red Book&lt;/em&gt;, Vernon Vaughn dedicates a whole chapter to Value Objects and lists its characteristics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It measures, quantifies, or describes a thing in the domain;&lt;/li&gt;
&lt;li&gt;It should be immutable;&lt;/li&gt;
&lt;li&gt;It captures a whole value;&lt;/li&gt;
&lt;li&gt;It is replaceable;&lt;/li&gt;
&lt;li&gt;It prevents side-effects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&#39;s all very DDD... But, as we&#39;ll see below, Value Objects are very useful even if one doesn&#39;t work with the Domain Driven Design paradigm.&lt;/p&gt;
&lt;h2 id=&#34;identity-not&#34;&gt;Identity... Not!&lt;a class=&#34;headerlink&#34; href=&#34;#identity-not&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Evans highlights the key characteristic of a Value Object, that it is defined by its value and not by its identity.&lt;/p&gt;
&lt;p&gt;If you plan to paint your house in, let&#39;s say, pink, you go out to the store and buy a load of buckets of pink paint. Back home, you just pick the first bucket and start painting. Although they are different buckets, what you really care about is the color it contains.
The value of the bucket is defined, not by its identity, but by the color it contains and, therefore, all the buckets are equal.&lt;/p&gt;
&lt;p&gt;In PHP, this translates into objects that have no &lt;code&gt;id&lt;/code&gt; and one or more &lt;code&gt;attributes&lt;/code&gt; that define its value.&lt;br /&gt;
&lt;em&gt;&lt;strong&gt;Side note&lt;/strong&gt;: we are focusing on the PHP object for the moment, not how the data is stored in a database. This distinction is very important. We will address persistence later on.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As PHP developers, we all know at least one famous Value Object: &lt;code&gt;DateTimeImmutable&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$now&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;\DateTimeImmutable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;DateTimeImmutable&lt;/code&gt; object has values for year, month, day, hour, minute, seconds and timezone ... but not a single property that sets an identity.&lt;/p&gt;
&lt;p&gt;With PHP 8.1, &lt;code&gt;Enums&lt;/code&gt; were introduced and they work pretty well as Value Objects:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;enum&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Suit&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Hearts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Diamonds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Clubs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Spades&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As one can see, no identity... Value only.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Side-note&lt;/strong&gt;: Enums are a little peculiar in regards of the identity characteristic. They are in fact Singletons and will therefore always return the same instance. So they kind of are their own identity value.
This does not disqualify them as Value Objects. As one can read below, Enums definitely match with all the Value Object&#39;s criteria.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Last but not least, we can also define our own custom Value Objects:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;EmailAddress&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$value&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;){&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Again... no identity and only a value.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Side-note:&lt;/strong&gt; the absence of an identity is the main difference between a Value Object and an Entity whether it is a Domain Driven Design Entity or an ORM Entity.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;admonition warning&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Rule 0&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A Value Object is a thing that defines itself by its value not by its identity.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;descriptive&#34;&gt;Descriptive&lt;a class=&#34;headerlink&#34; href=&#34;#descriptive&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Another important keyword in Evans&#39; definition above is &lt;em&gt;descriptive&lt;/em&gt;. And Vaughn writes a Value Object &lt;strong&gt;describes, measures or quantifies&lt;/strong&gt; something.&lt;/p&gt;
&lt;p&gt;To handle these characteristics, a Value Object has one or more attributes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Color&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$green&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the above code listing, we have a class that is able to define a color with the RBGA model. When talking about the color of light, like on a screen, &lt;code&gt;R&lt;/code&gt;ed, &lt;code&gt;G&lt;/code&gt;reen, &lt;code&gt;B&lt;/code&gt;lue and &lt;code&gt;A&lt;/code&gt;lpha are the four channels that define a color.&lt;/p&gt;
&lt;p&gt;Every attribute of the &lt;code&gt;Color&lt;/code&gt; class indicates each channel&#39;s exact intensity that is required to obtain the exact color we want:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$black&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$white&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$redTransparent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;25&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Interestingly enough, these attributes, instead of scalars, could also be other Value Objects. For instance:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;enum&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Sharpness&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;VerySharp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;NotSoSharp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;NotSharpAtAll&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;nx&#34;&gt;enum&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Hardness&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;OhSoHard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;RegularHard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Medium&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Soft&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;VirtualPencil&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Sharpness&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$sharpness&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Hardness&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$hardness&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;$virtualPencilToDrawAMustachOnMarcInMeta&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;VitualPencil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                                                &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
                                                &lt;span class=&#34;nx&#34;&gt;Sharpness&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;VerySharp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                                                &lt;span class=&#34;nx&#34;&gt;Hardness&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;OhSoHard&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                                            &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the above example, the &lt;code&gt;VirtualPencil&lt;/code&gt; is defined by a &lt;code&gt;Color&lt;/code&gt;, a &lt;code&gt;Sharpness&lt;/code&gt; and a &lt;code&gt;Hardness&lt;/code&gt; attribute, and all of them are themselves Value Objects.&lt;/p&gt;
&lt;div class=&#34;admonition warning&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Rule 1&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A Value Object has one or more attributes whose values define the Value Object. The attributes are either primitives or other Value Objects.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;immutable&#34;&gt;Immutable&lt;a class=&#34;headerlink&#34; href=&#34;#immutable&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In order to share the value object within an application and avoid any side effects, it is highly recommended for them to be immutable so that they can&#39;t change all of a sudden.&lt;/p&gt;
&lt;p&gt;This will avoid annoying, sometimes embarrassing, and always hard to debug issues like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;VirtualPencilExtensionHandler&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;handleExtension&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;TheExtensionInterface&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$extension&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;void&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;$extension&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;NastyExtensionThatChangesColor&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;implements&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;TheExtensionInterface&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;void&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;$color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;blue&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As one sees, now Marc will end up with a blue mustache if we were to use the set color later on in a virtual pencil... And nobody would want Marc to have a blue mustache, or would we?&lt;/p&gt;
&lt;p&gt;More seriously, this shows that sometimes an object, or any referenced variable, when passed on to another scope, may get changed without the original scope being aware of it. As we can see above, this may cause quite some trouble.&lt;/p&gt;
&lt;p&gt;This can easily be prevented by making the Value Object&#39;s attributes immutable.
Easy in PHP 8.1, with the latest &lt;code&gt;readonly&lt;/code&gt; property:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Color&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$green&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and even easier in PHP 8.2 with &lt;code&gt;readonly&lt;/code&gt; classes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Color&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$green&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you&#39;re not lucky enough to work with PHP&#39;s latest versions, you still can use &lt;code&gt;private&lt;/code&gt; properties and &lt;code&gt;public&lt;/code&gt; getter methods for the Value Objects, but obviously no public setter methods.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Color&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$green&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$green&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; 
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// etc&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Side note&lt;/strong&gt;: there are cases where one explicitly wants/needs mutable Value Objects. This is acceptable but in that case these Value Objects should &lt;strong&gt;never&lt;/strong&gt; be shared.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;admonition warning&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Rule 2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Value Objects should almost always be immutable.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;whole-value&#34;&gt;Whole value&lt;a class=&#34;headerlink&#34; href=&#34;#whole-value&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As Evans theorized DDD and talked about Value Objects, one often tends to think he also invented them. But the origin of the Value Object appears to be the &lt;em&gt;Whole Value&lt;/em&gt;, introduced by Ward Cunningham&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:3&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;In short, a Value Object is either complete, with all its attributes, or it is not.
In the color examples above, it would not make sense to leave out one of the channels, and even if we were to make the &lt;code&gt;$alpha&lt;/code&gt; attribute optional, it should never be &lt;code&gt;null&lt;/code&gt;, as it would no longer be a valid color.&lt;/p&gt;
&lt;h3 id=&#34;all-or-nothing&#34;&gt;All or nothing&lt;a class=&#34;headerlink&#34; href=&#34;#all-or-nothing&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;It is therefore highly recommended to instantiate a Value Object once with all its attributes, as we did in the examples above.
Setting all the &lt;code&gt;readonly&lt;/code&gt; properties in the constructor makes it impossible to end up in an invalid state.&lt;/p&gt;
&lt;p&gt;Now, in some cases this is complicated. For more complex objects, we might need to convert data or extract it from a database, use a webservice or parse a file to gather the required information to inject into the Value Object or use, for instance, a Strategy Patttern to calculate the value of the attributes we want to inject into the Value Object.&lt;br /&gt;
In short, there are many use cases where it is not that simple to instantiate the object on the fly.&lt;/p&gt;
&lt;p&gt;In those cases it is recommended to use a &lt;code&gt;factory&lt;/code&gt;, either within the Value Object itself, or, when it gets really complex, in a dedicated class.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Color&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;ofHexColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$hexColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$opacity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;self&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;$hexColor&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;ltrim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$hexColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;$parts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;match&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;strlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$hexColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
                &lt;span class=&#34;nb&#34;&gt;str_repeat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;substr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$hexColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
                &lt;span class=&#34;nb&#34;&gt;str_repeat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;substr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$hexColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
                &lt;span class=&#34;nb&#34;&gt;str_repeat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;substr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$hexColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
            &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
                &lt;span class=&#34;nb&#34;&gt;substr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$hexColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
                &lt;span class=&#34;nb&#34;&gt;substr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$hexColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
                &lt;span class=&#34;nb&#34;&gt;substr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$hexColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;default&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;throw&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;InvalidColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                        &lt;span class=&#34;nb&#34;&gt;sprintf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;%s is not a valid CSS color&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$hexColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;hexdec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$parts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]),&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;hexdec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$parts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]),&lt;/span&gt; 
                        &lt;span class=&#34;nb&#34;&gt;hexdec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$parts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]),&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$opacity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;var_dump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;ofHexColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;#f00&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;//  Color Object&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//  (&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//      [red] =&amp;gt; 255&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//      [green] =&amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//      [blue] =&amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//      [alpha] =&amp;gt; 1&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//  )&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These &lt;code&gt;factories&lt;/code&gt; may also be interesting to add additional static constructors to the Value Objects. For instance, in our color example, we might need to be able to instantiate an object with other color notations:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Color&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;ofHsvColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$hue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$saturation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$opacity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;self&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;// convert, validate, initiate here&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;ofCmykColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$cyan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$magenta&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$yellow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$black&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$opacity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;self&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;// convert, validate, initiate here&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By the way, these static constructor methods allow for more explicit and more expressive method names, which is always useful, even when not following the DDD principles.
It is therefore very common to define a private constructors and implement one or more static methods to initiate the Value Object, even if there is only one:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Color&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$green&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;ofRgbaColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$green&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$alpha&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;self&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;// validation&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$green&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;evolvable-objects&#34;&gt;Evolvable objects&lt;a class=&#34;headerlink&#34; href=&#34;#evolvable-objects&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;An alternative to &lt;code&gt;factory&lt;/code&gt; methods is to use an evolvable object:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Color&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$red&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$blue&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$green&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$alpha&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;withRed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;self&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;green&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;withBlue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;self&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;green&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;// etc with Green &amp;amp; Alpha&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;$color&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;var_dump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//  Color Object&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//  (&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//      [red] =&amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//      [green] =&amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//      [blue] =&amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//      [alpha] =&amp;gt; 1&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//  )&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;$otherColor&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;withRed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;var_dump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$otherColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//  Color Object&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//  (&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//      [red] =&amp;gt; 255&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//      [green] =&amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//      [blue] =&amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//      [alpha] =&amp;gt; 1&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;//  )&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As one can see in this very simple example, one can chain a series of more or less complex methods, each one generating a new valid Value Object, until we end up with the final Value Object we aimed for.
Please note that in order to get there, we did take care to define valid default values for the Color&#39;s four channels.&lt;/p&gt;
&lt;div class=&#34;admonition warning&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Rule 3&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Value Objects are whole objects and should be complete.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;replaceable&#34;&gt;Replaceable&lt;a class=&#34;headerlink&#34; href=&#34;#replaceable&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If a Value Object is immutable (see above), one can not simply change its value, or the value of its attributes. That seems pretty obvious.&lt;/p&gt;
&lt;p&gt;This means that when we need to change the represented value, we should completely replace it with a new Value Object.
This is very easy to understand when using plain scalars:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$firstname&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;Eric&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$firstname&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;John&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the above two lines, &lt;code&gt;Eric&lt;/code&gt; did not become &lt;code&gt;John&lt;/code&gt;, but the value of &lt;code&gt;$firstname&lt;/code&gt;, that was initially set to &lt;code&gt;Eric&lt;/code&gt; was replaced with the value &lt;code&gt;John&lt;/code&gt; (any resemblance with reality is mere coincidence :poke &lt;a href=&#34;https://www.phpugly.com/&#34;&gt;PHPUgly&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The same goes for Value Objects:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$firstname&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Firstname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Eric&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$firstname&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Firstname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;John&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;// and not&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$firstname&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;John&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;admonition warning&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Rule 4&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Referenced Value Objects are not updated but replaced with new instances.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;side-effect-free&#34;&gt;Side-effect-free&lt;a class=&#34;headerlink&#34; href=&#34;#side-effect-free&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now this is a good practice that comes from functional programming and is tightly related with the immutability and replacement principles explained above.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Side-effect-free&lt;/em&gt; means that any operation on an object, in this case, a Value Object, should not alter the object&#39;s state.&lt;/p&gt;
&lt;div class=&#34;admonition info inline end&#34;&gt;
&lt;p&gt;Do check out Larry Garfield&#39;s book if you would like to explore FP further.&lt;br /&gt;
&lt;a href=&#34;https://leanpub.com/thinking-functionally-in-php&#34;&gt;&lt;img alt=&#34;Larry Garfield - Thinking functional in PHP&#34; src=&#34;../../../../ddd_value-objects/larry-garfield_thinking-functional-in-PHP.png&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Total&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$valueToAdd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;self&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$valueToAdd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;$originalTotal&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Total&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$newTotal&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$originalTotal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$newTotal&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$newTotal&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$originalTotal&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;// 2&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$newTotal&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;      &lt;span class=&#34;c1&#34;&gt;// 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the example above, the value of &lt;code&gt;$originalTotal&lt;/code&gt; does not change, even when a method is called on it and a new Value Object, &lt;code&gt;$newTotal&lt;/code&gt;, is created with a different value.&lt;/p&gt;
&lt;div class=&#34;admonition warning&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Rule 5&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Value Objects remain unaffected by the operations that are applied upon them.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&#34;ok-great-now-what&#34;&gt;OK great... now what?&lt;a class=&#34;headerlink&#34; href=&#34;#ok-great-now-what&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that we more or less understand what a Value Object is and have seen a series of very simple PHP examples, let us have a closer look at the benefits of using them.&lt;/p&gt;
&lt;h3 id=&#34;value-objects-are-valid-objects&#34;&gt;Value objects are valid objects&lt;a class=&#34;headerlink&#34; href=&#34;#value-objects-are-valid-objects&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the examples above, we mostly focused on the properties of the Value Objects and barely touched one of the biggest advantages of them, being that, when implemented properly, Value Objects are always valid objects.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;PhpArchEmailAddress&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; 
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;preg_match&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;/.*@phparch\.com/m&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;throw&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;InvalidPhpArchEmailAddress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;nb&#34;&gt;sprintf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;lt;%s&amp;gt; is not a valid email address.&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;preg_match&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;/ben\.ramsey@phparch\.com/m&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;throw&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ExasperatedEric&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;Ben? Ben Ramsey? Are you kidding me?&amp;quot;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
            &lt;span class=&#34;c1&#34;&gt;// private joke for the PHPUgly Community&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

        &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Whether directly in the constructor, or in a factory, one can apply all the required validation and filter rules &lt;strong&gt;before&lt;/strong&gt; instantiating the Value Object. As a result, if the object can be initiated with the passed in attributes, it will be valid.
More, it is auto-validated!&lt;/p&gt;
&lt;p&gt;If one were to use a basic string to deal with a such an email address, one would have to check its validity every time it is used.
With immutable Value Objects, one no longer needs to verify anything. Its sole existence proves that the value(s) it contains are valid. This does clean up our code drastically and makes it much easier to maintain and to read.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Side note&lt;/strong&gt;: when the validation rules get a little more complicated, it is recommended to move them to a dedicated class that will be easier to maintain and, more importantly, to test.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;admonition warning&#34;&gt;
&lt;p&gt;So, yes, Value Objects are &lt;strong&gt;ALWAYS&lt;/strong&gt; valid!&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&#34;types&#34;&gt;Types&lt;a class=&#34;headerlink&#34; href=&#34;#types&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Since PHP 7.4, we have been blessed with proper typed properties in PHP and we can now benefit from all the advantages other strongly typed languages offer in terms of performance and security.&lt;/p&gt;
&lt;p&gt;Value Objects are perfect to extend our favorite programming language with rich and expressive types.&lt;/p&gt;
&lt;p&gt;Compare both of these examples:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;PhpArchNewEditionNotifier&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// with a string&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$senderEmailAddress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;PhpArchNewEditionNotifier&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// with a Value Object&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;PhpArchEmailAddress&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$senderEmailAddress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next to being much more efficient, remember one does not need to write/copy-paste validating lines every time the value is used, the second example is much more expressive as it clearly indicates what the &lt;code&gt;$senderEmailAddress&lt;/code&gt; should be.&lt;/p&gt;
&lt;h3 id=&#34;specialized-rich-models&#34;&gt;Specialized &amp;amp; Rich Models&lt;a class=&#34;headerlink&#34; href=&#34;#specialized-rich-models&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Value Objects address one particular concern and, next to the values, can encapsulate rich and context bound business logic.&lt;/p&gt;
&lt;p&gt;This means one will not bundle things together if they don&#39;t belong to the same context.&lt;br /&gt;
Instead of this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Price&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$price&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$currency&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$vatRate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$discountRate&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$discountAmount&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;one could move attributes that belong to the same context into dedicated Value Objects.&lt;br /&gt;
For instance:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Price&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$price&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;VatRate&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$vatRate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Discount&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$discount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the example above, we are using the &lt;code&gt;Money for PHP&lt;/code&gt; library (see &lt;a href=&#34;https://www.moneyphp.org/&#34;&gt;https://www.moneyphp.org/&lt;/a&gt;). Next to dealing with the well known &lt;code&gt;float&lt;/code&gt; issues when dealing with money, it is also a remarkable example of a Value Object.&lt;/p&gt;
&lt;p&gt;In short, it more or less functions like this (not in PHP8.1):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Currency&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Money&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$amount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Currency&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$currency&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;$amounts&lt;/code&gt; are in cents and are, in the end, converted to a &lt;code&gt;string&lt;/code&gt; in order to be able to store values that are greater than the system&#39;s integer limit (&lt;code&gt;PHP_INT_MAX&lt;/code&gt;). Check out Money&#39;s source code to get a better understanding of the &lt;code&gt;$amount&lt;/code&gt; attribute.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;VatRate&lt;/code&gt; is a rather simple Value Object:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;VatRate&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$rate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Interestingly enough, one could add a nice method to the &lt;code&gt;VatRate&lt;/code&gt; Value Object to calculate the VAT and to apply the VAT, making the model richer:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;VatRate&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;calculateVat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;multiply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;rate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;applyVat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;calculateVat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;// Money being immutable, the add() &amp;amp; multiply()&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// methods will return new instances of Money&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Last but not least, the Discount Value Object. One may have been wondering why, in the first example, there were &lt;code&gt;$discountRate&lt;/code&gt; and &lt;code&gt;$discountAmount&lt;/code&gt;, both &lt;code&gt;nullable&lt;/code&gt;.
That is because the system should be able to deal with rates and fixed amounts for the discount.&lt;/p&gt;
&lt;p&gt;This probably is a smarter approach:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;interface&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Discount&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;asRate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;asMoney&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;applyDiscount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;RateDiscount&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;implements&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Discount&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$rate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;asRate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;rate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;asMoney&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;multiply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;rate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;applyDiscount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;subtract&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;asMoney&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;FixedAmountDiscount&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;implements&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Discount&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$amount&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;asRate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;amount&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getAmount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getAmount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;asMoney&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;amount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;applyDiscount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$money&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;subtract&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;asMoney&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, one can easily figure out the total price:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Price&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;total&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;  &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;vatRate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;applyVat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                    &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;discount&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;applyDiscount&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                        &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;price&lt;/span&gt;
                    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is just a very simple example, but it does illustrate that Value Objects are very specialized objects and that they can encapsulate very context bound business logic.&lt;/p&gt;
&lt;h3 id=&#34;testing&#34;&gt;Testing&lt;a class=&#34;headerlink&#34; href=&#34;#testing&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As we are testing the code we write, or, better, write the code that addresses a written test (see TDD), testing just got much more straightforward.&lt;/p&gt;
&lt;p&gt;The reason is pretty obvious. If we were, for instance, to use a regular email address (as &lt;code&gt;string&lt;/code&gt;) as an attribute in multiple functions in multiple classes, we would need to write tests with valid and invalid email addresses for each one of them. With an &lt;code&gt;EmailAddress&lt;/code&gt; Value Object, we only need to write those tests once and will no longer have to worry about it anywhere else.&lt;br /&gt;
As mentioned above, if a Value Object can be instantiated it must be valid.&lt;/p&gt;
&lt;p&gt;Last but not least, there is no need to mock Value Objects.&lt;/p&gt;
&lt;h3 id=&#34;cognitive-load&#34;&gt;Cognitive load&lt;a class=&#34;headerlink&#34; href=&#34;#cognitive-load&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As the usage of Value Objects encourages you to encapsulate the context bound business logic along with it, one will, in the end write more classes, but much smaller ones.&lt;/p&gt;
&lt;p&gt;As a result, just like in DDD, where the business logic is split over multiple insulated contexts, the cognitive load required to understand what a given object does, how it works, and how to interact with it gets reduced... Even more now one knows that it can not change all of a sudden and that it will &lt;em&gt;de facto&lt;/em&gt; always be valid.&lt;/p&gt;
&lt;h3 id=&#34;caching&#34;&gt;Caching&lt;a class=&#34;headerlink&#34; href=&#34;#caching&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Once more, because of their immutability, Value Objects become perfect for caching, even for a very long period of time.&lt;/p&gt;
&lt;p&gt;This can be done either with a application wide caching mechanism:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$psr6CachePool&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$psr6CachePool&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;hasItem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;PhpArchEmailAddress&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$emailAddressAsString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;nv&#34;&gt;$psr6CachePool&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;nv&#34;&gt;$psr6CachePool&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getItem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;PhpArchEmailAddress&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$emailAddressAsString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                    &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;PhpArchEmailAddress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$emailAddressAsString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$emailAddress&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$psr6CachePool&lt;/span&gt;
                    &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getItem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;PhpArchEmailAddress&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$emailAddressAsString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                    &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or through memoization:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;ComplicatedMathematicalValueObject&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$val1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$val2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;complicatedOperation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;is_null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// very long operation goes here&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Bear in mind that when using memoization, one loses the ability to use the &lt;code&gt;==&lt;/code&gt; operator to compare two Value Objects as for the &lt;code&gt;==&lt;/code&gt; operator, the Value Object before and after memoization will no longer be equal.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$var1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ComplicatedMathematicalValueObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$var2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ComplicatedMathematicalValueObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;var_dump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$var1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$var2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;// true&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;$var1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;complicatedOperation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;var_dump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$var1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$var2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It is therefore very common to add an &lt;code&gt;isEqual()&lt;/code&gt; method to the Value Objects to deal with this.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;ComplicatedMathematicalValueObject&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;isEqual&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ComplicatedMathematicalValueObject&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$other&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;bool&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;val1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;===&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$other&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;val1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;val2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$other&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;val2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;$var1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ComplicatedMathematicalValueObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$var2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ComplicatedMathematicalValueObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;var_dump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$var1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;isEqual&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$var2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;// true&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;$var1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;complicatedOperation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;var_dump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$var1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;isEqual&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$var2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By the way, this &lt;code&gt;isEqual()&lt;/code&gt; method will also deal with issues with inheritance:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;MustacheColor&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;$colorA&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$colorB&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;MustacheColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;var_dump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$colorA&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$colorB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This makes sense, the &lt;code&gt;==&lt;/code&gt; operator also expects the objects to be of the exact same type. Sadly, it is not possible, yet, to overload PHP&#39;s operators.&lt;/p&gt;
&lt;p&gt;Luckily, the &lt;code&gt;isEqual()&lt;/code&gt; method will deal with this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Color&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;isEqual&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$otherColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;bool&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;red&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;===&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$otherColor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;red&lt;/span&gt;
            &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;green&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;===&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$otherColor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;green&lt;/span&gt;
            &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;blue&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;===&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$otherColor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;blue&lt;/span&gt;
            &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;alpha&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;===&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$otherColor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;$colorA&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;$colorB&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;MustacheColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;var_dump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$colorA&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;isEqual&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$colorB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Remember that we care about the values here. It is obvious that a &lt;code&gt;MustacheColor&lt;/code&gt; and a &lt;code&gt;Color&lt;/code&gt; are not identical, yet their values are.&lt;/p&gt;
&lt;h2 id=&#34;caveats&#34;&gt;Caveats&lt;a class=&#34;headerlink&#34; href=&#34;#caveats&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&#34;and-what-about-dtos&#34;&gt;And what about DTOs?&lt;a class=&#34;headerlink&#34; href=&#34;#and-what-about-dtos&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As Matthias Noback wrote in a blog post lately&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:4&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;, DTOs and Value Objects are not the same.&lt;/p&gt;
&lt;p&gt;First of all, they have a different purpose.
DTO, or Data Transfer Objects, are used on the boundaries of your application, either when data enters it, or when it leaves it. Value Objects, on the other hand are, mostly, used within the application and even more often within its business layer.&lt;/p&gt;
&lt;p&gt;Secondly, even though both DTOs and Value Objects define a structure for data, DTOs do not need to be complete as it is required for a Value Object (see Whole Value above). DTO&#39;s properties can be &lt;code&gt;nullable&lt;/code&gt;, and it is not the DTO&#39;s responsibility to validate or only accept valid data or state.&lt;/p&gt;
&lt;p&gt;Thirdly, as indicated above, Value Objects ought to be specialized, only deal with a specific concern and, eventually, include context bound business logic.
DTOs, on the other hand, do not require to be limited to a specific scope. They need to make data interchangeable, in and out of an application, and should be formatted according to the usage that will be made of it. Also, DTOs will barely ever include any complex business logic.&lt;/p&gt;
&lt;h3 id=&#34;persistence&#34;&gt;Persistence&lt;a class=&#34;headerlink&#34; href=&#34;#persistence&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;One of the biggest challenges when working with Value Objects clearly is persistence, &lt;em&gt;ie&lt;/em&gt; storing it in a database or wherever. The complication mostly comes from the absence of an identifier.
This mind shift does require a little effort as we are kind of used to mirror our database design with our code, or the other way around.&lt;/p&gt;
&lt;p&gt;This is another principle that comes from DDD, where the code that is used to express the business layer is to be completely decoupled from the persistence layer, for instance, the database.
PHP Value Objects are only useful in a PHP context, not in a database... at least not as such. So it makes perfect sense to break the sacred rule of one model/one table and one property/one column!&lt;/p&gt;
&lt;p&gt;An unpopular point of view, maybe: the database is the place where one stores data, NOT where one consumes it.
If one needs to use the data outside of the application, either one ought to use the application to fetch it -- for instance, through a dedicated API that uses the application&#39;s business logic -- or build some kind of data warehouse where the data is transformed and can be optimized for that specific task.&lt;/p&gt;
&lt;p&gt;There are multiple ways to store these Value Objects in the database though. There will always be a suitable solution:&lt;/p&gt;
&lt;h4 id=&#34;along-with-the-encapsulating-entity&#34;&gt;Along with the encapsulating entity&lt;a class=&#34;headerlink&#34; href=&#34;#along-with-the-encapsulating-entity&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Remember, and this is important, your database does not have to be an exact reflection of your code (and &lt;em&gt;vice versa&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;For example,&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// Entity&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Book&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Uuid&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$uid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Author&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$author&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Title&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$coverColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;could simply be stored in a table that would look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;create&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;book&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                 &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;varchar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;36&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;not&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;author_uid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;varchar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;36&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;not&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;               &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;varchar&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;not&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cover_color_rgba&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- ...&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;foreign&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;author_uid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;references&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;author&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- ...&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;Author&lt;/code&gt; being another entity, with an identity, the book table contains a foreign key to the &lt;code&gt;author&lt;/code&gt; table.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Title&lt;/code&gt; Value Object is directly stored as string.&lt;/p&gt;
&lt;p&gt;And in the above example, the &lt;code&gt;Color&lt;/code&gt; is stored in its RGBA notation (and this is explicitly indicated) even though the original &lt;code&gt;Color&lt;/code&gt; Value Object uses three &lt;code&gt;int&lt;/code&gt;s and a &lt;code&gt;float&lt;/code&gt;. It is shorter and easier to store in a single field this way.&lt;/p&gt;
&lt;p&gt;Depending on the chosen technology for the communication with the database (raw SQL, PDO, ORM, REST...), this communication layer will be responsible for the conversion of the data in the database into valid PHP objects and the other way around.
It is highly recommended to have a close look at the Repository pattern to deal with this.&lt;/p&gt;
&lt;h4 id=&#34;denormalization&#34;&gt;Denormalization&lt;a class=&#34;headerlink&#34; href=&#34;#denormalization&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Much has been said about how to avoid repetition in code and why we should do so. Maybe a little to much.
This is also often enforced in databases where one tends to use foreign keys to reference data that is reused elsewhere.&lt;/p&gt;
&lt;p&gt;Yet, in the case of Value Objects, especially for small ones, denormalization probably is one of the most interesting approaches.
Denormalization is the exact opposite of &#34;avoiding repetition&#34;, except one does it on purpose.
Please note that unlike one may think, if done properly, this might actually improve the database&#39;s performance as additional joins are no longer required.&lt;/p&gt;
&lt;p&gt;Consider this code&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;// Entity&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Book&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Color&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$coverColor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Money&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$price&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If one were to mimic the code&#39;s structure and did not want the RGBA &lt;code&gt;Color&lt;/code&gt; notation, this would result in database tables that could look more or less like these:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;create&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;auto_increment&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;primary&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color_red&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;not&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color_green&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;not&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color_blue&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;not&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color_alpha&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;not&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;create&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;auto_increment&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;primary&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;amount&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price_currency&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;create&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;book&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- ...&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cover_color_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- ...&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;foreign&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cover_color_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;references&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;foreign&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;references&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- ...&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Color&lt;/code&gt; and &lt;code&gt;Price&lt;/code&gt; would have an identity and foreign keys would be created to reference the &lt;code&gt;$bookCoverColor&lt;/code&gt; and &lt;code&gt;$price&lt;/code&gt;. If we were to add another concept with a price or a color, we would be able to use the same &lt;code&gt;color&lt;/code&gt; and &lt;code&gt;price&lt;/code&gt; tables. Multiple joins would be required to fetch all the book&#39;s attributes.&lt;/p&gt;
&lt;p&gt;But it could also be stored in a denormalized way, in one single database table that would look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;create&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;book&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- ...&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cover_color_red&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cover_color_green&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cover_color_blue&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cover_color_alpha&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price_amount&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price_currency&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;char&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;-- ...&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As one can see in this example, the &lt;code&gt;Color&lt;/code&gt; Value Object is stored directly in four fields, one per channel, in the &lt;code&gt;book&lt;/code&gt; table. Depending on database usage and personal preferences, one could choose this version or the one in the previous code listing using the RGBA notation.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Money $price&lt;/code&gt; Value Object is stored into two distinct columns, one for the &lt;code&gt;amount&lt;/code&gt; another one for the &lt;code&gt;currency&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Side-note&lt;/strong&gt;: even though the &lt;code&gt;$amount&lt;/code&gt; in a &lt;code&gt;Money&lt;/code&gt; Value Object really is a &lt;code&gt;string&lt;/code&gt;, in the example, it is stored as an &lt;code&gt;int&lt;/code&gt;. Thing is, a book&#39;s price will never exceed &lt;code&gt;PHP_INT_MAX&lt;/code&gt; and the data department will be happy the data is immediately usable and will not need to get casted.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This does mean however that other concepts with a color and/or price would need to implement these columns as well. But is that really a problem? Not really...&lt;/p&gt;
&lt;h4 id=&#34;serialization&#34;&gt;Serialization&lt;a class=&#34;headerlink&#34; href=&#34;#serialization&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;One of the easiest ways is to serialize the data and store it in one single field in the database, preferably in JSON format (not with PHP&#39;s &lt;code&gt;serialize()&lt;/code&gt; function).&lt;/p&gt;
&lt;p&gt;Remember that, these days, most of the RDBMS are able to deal directly with JSON. So if one really needs to access the data in the database directly, even though it will be a little slower, it still is possible.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;Color&lt;/code&gt; field would look like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;255&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;quot;green&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;quot;blue&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;quot;alpha&amp;quot;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Readable, exploitable, single field... Definitely an option to bear in mind.&lt;/p&gt;
&lt;h4 id=&#34;as-an-entity&#34;&gt;As an entity&lt;a class=&#34;headerlink&#34; href=&#34;#as-an-entity&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Last but not least, in some cases it does make sense to consider a Value Object as an entity when storing it (and only when storing it). This, however, should only be considered when other options are not feasible.&lt;/p&gt;
&lt;p&gt;There are multiple options here, all of them are right and really depend on how much one wants to decouple the persistence layer from the Value Objects.&lt;/p&gt;
&lt;p&gt;First option, the easiest one, is to autogenerate a unique identifier when instantiating the Values Object. This property should be private and not accessible via the object&#39;s public API (when using an ORM like Doctrine, you actually don&#39;t need any setter or getter methods).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Color&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$green&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Second option is the one used in DDD-world and makes use of a surrogate identifier.
This is achieved by using a parent class with a private or protected property&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;abstract&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;ValueObjectWithId&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Color&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ValueObjectWithId&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$red&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$green&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$blue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;readonly&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$alpha&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Obviously, this could also be achieved with at &lt;code&gt;trait&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;trait&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ValueObjectWithId&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Color&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ValueObjectWithId&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;// ...&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In all three cases the generation of the &lt;code&gt;id&lt;/code&gt; would be delegated to the database. ORM systems like Doctrine are able to hydrate the private properties but this could also be achieved with Reflection or by binding a closure to the class (see Marco Pivetta&#39;s, aka &lt;a href=&#34;https://twitter.com/ocramius&#34;&gt;@ocramius&lt;/a&gt;, blog post here: &lt;a href=&#34;http://ocramius.github.io/blog/accessing-private-php-class-members-without-reflection/&#34;&gt;http://ocramius.github.io/blog/accessing-private-php-class-members-without-reflection/&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;This approach does require more SQL queries though as, when saving the Value Object to the database, one will have to check if an entry with the same properties already exists, inject the private &lt;code&gt;id&lt;/code&gt; that will be used later on in the encapsulating entities or Value Objects.&lt;/p&gt;
&lt;h4 id=&#34;dedicated-persistence-types&#34;&gt;Dedicated Persistence Types&lt;a class=&#34;headerlink&#34; href=&#34;#dedicated-persistence-types&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;ORMs like Doctrine and Eloquent allow us to create dedicated adapters that take care of the conversion of DataTypes, in this case the Value Objects, from the application&#39;s PHP into the database and the other way around.&lt;/p&gt;
&lt;p&gt;One still has to decide which of the above strategies is the most suited... But once implemented, these auto-magic transformers come in quite handy.&lt;/p&gt;
&lt;h4 id=&#34;enums&#34;&gt;Enums&lt;a class=&#34;headerlink&#34; href=&#34;#enums&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;As PHP 8.1 introduced the long awaited native &lt;code&gt;enums&lt;/code&gt;, it seems useful to add a little note on those. It seems very obvious to store a PHP Enum as an Enum in a database... Thing is, this may not be the best move.&lt;/p&gt;
&lt;p&gt;Back in 2011, yes, that&#39;s a long time ago, Chris Komlenic wrote a little blog post listing a series of issues with the MySQL Enum type&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:5&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;. As MySQL still is one of the most popular RDBMS, this list of objections remains pretty much valid. In PostgreSQL, Enums are real reusable data types, so part of the objections are less valid for that RDBMS.&lt;/p&gt;
&lt;p&gt;Granted, database Enums are easy to use, but they come at a cost and, in the end, offer only very negligible benefits on optimization (an in depth analysis of this would be out of scope of the current article).&lt;/p&gt;
&lt;p&gt;In the end, and especially when working with an ORM, it is really not complicated to use one of the strategies mentioned above and avoid the &#34;evil&#34; native database enum type.&lt;/p&gt;
&lt;h2 id=&#34;some-interesting-value-objects&#34;&gt;Some Interesting Value Objects&lt;a class=&#34;headerlink&#34; href=&#34;#some-interesting-value-objects&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We already mentioned the &lt;code&gt;DateTimeImmutable&lt;/code&gt; object and had a look at the &lt;code&gt;Money&lt;/code&gt; Value Object in the examples above and also mentioned its benefits over using &lt;code&gt;float&lt;/code&gt;s to deal with monetary values.&lt;/p&gt;
&lt;p&gt;Here are some more Value Objects that might be of interest:&lt;/p&gt;
&lt;h3 id=&#34;uuid&#34;&gt;UUID&lt;a class=&#34;headerlink&#34; href=&#34;#uuid&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Ben Ramsey created PHP&#39;s best implementation of &lt;code&gt;Uuid&lt;/code&gt; (&lt;a href=&#34;https://uuid.ramsey.dev/en/stable/index.html&#34;&gt;https://uuid.ramsey.dev/en/stable/index.html&lt;/a&gt;).&lt;br /&gt;
By the way, Ben just added version 7 of the Uuid specification. Make sure to check it out.&lt;/p&gt;
&lt;h3 id=&#34;not-null&#34;&gt;Not NULL&lt;a class=&#34;headerlink&#34; href=&#34;#not-null&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In his brilliant blog post &#34;Much ado about null&#34;, Larry Garfield shows a series of very interesting alternatives to the usage of &lt;code&gt;null&lt;/code&gt;. Check out the &lt;code&gt;Maybe&lt;/code&gt; [Monad] Value Object, and even more his &lt;code&gt;Result&lt;/code&gt; proposal at the end of the post (&lt;a href=&#34;https://peakd.com/hive-168588/@crell/much-ado-about-null&#34;&gt;https://peakd.com/hive-168588/@crell/much-ado-about-null&lt;/a&gt;).&lt;/p&gt;
&lt;h3 id=&#34;symfonystring&#34;&gt;Symfony/String&lt;a class=&#34;headerlink&#34; href=&#34;#symfonystring&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The Symfony/String component is another very nice implementation of a &#34;big&#34; Value Object that handles strings as immutables and provide rich functionality (&lt;a href=&#34;https://symfony.com/doc/current/components/string.html&#34;&gt;https://symfony.com/doc/current/components/string.html&lt;/a&gt;).&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;a class=&#34;headerlink&#34; href=&#34;#conclusion&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We now know what a Value Object is, that it is one fundamental tool when working in Domain Driven Design, but that it definitely is a very interesting approach anywhere.
We&#39;ve briefly discussed Value Object&#39;s characteristics, its benefits and ways to use and store them.&lt;/p&gt;
&lt;p&gt;Domain Driven Design is gaining a lot of traction within the PHP community, which only shows our favorite programming language has matured a lot over the last years, and chances are Value Objects, and other concepts from DDD, will become more and more used, even when not working on a DDD project.&lt;/p&gt;
&lt;p&gt;Another building block to bring value to our code...&lt;/p&gt;
&lt;h2 id=&#34;references&#34;&gt;References&lt;a class=&#34;headerlink&#34; href=&#34;#references&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;hr /&gt;
&lt;div class=&#34;footnote&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/179133.Domain_Driven_Design&#34;&gt;Eric Evans, &lt;em&gt;Domain-Driven Design - Tackling Complexity in the Hearth of Software&lt;/em&gt;&lt;/a&gt;&amp;#160;&lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:1&#34; title=&#34;Jump back to footnote 1 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/15756865-implementing-domain-driven-design?ac=1&amp;amp;from_search=true&amp;amp;qid=cNRlTg9JNg&amp;amp;rank=1&#34;&gt;Vernon Vaughn VERNON, &lt;em&gt;Implementing Domain-Driven Design&lt;/em&gt;&lt;/a&gt;&amp;#160;&lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:2&#34; title=&#34;Jump back to footnote 2 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://fit.c2.com/wiki.cgi?WholeValue&#34;&gt;Ward CUNNINGHAM, &lt;em&gt;Whole Value&lt;/em&gt;&lt;/a&gt;&amp;#160;&lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:3&#34; title=&#34;Jump back to footnote 3 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://matthiasnoback.nl/2022/09/is-it-a-dto-or-a-value-object/&#34;&gt;Matthias NOBACK, &lt;em&gt;Is it a DTO or a Value Object?&lt;/em&gt;&lt;/a&gt;&amp;#160;&lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:4&#34; title=&#34;Jump back to footnote 4 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil/&#34;&gt;Chris KOMLENIC, &lt;em&gt;8 Reasons Why MySQL&#39;s ENUM Data Type Is Evil&lt;/em&gt;&lt;/a&gt;&amp;#160;&lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:5&#34; title=&#34;Jump back to footnote 5 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <link>https://notes.belgeek.dev/2023/11/05/bring-value-to-your-code/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Sun, 05 Nov 2023 00:00:00 +0000</pubDate>
      <source url="https://notes.belgeek.dev/feed_rss_created.xml">Belgeek</source>
      
      <guid isPermaLink="true">https://notes.belgeek.dev/2023/11/05/bring-value-to-your-code/</guid>
      
      <enclosure url="https://notes.belgeek.dev/assets/images/social/2023/11/05/bring-value-to-your-code.png" type="image/png" length="62733" />
      
    </item>
    
    <item>
      <title>the MakeFile for Symfony, ApiPlatform &amp;amp; FrankenPHP projects</title>
      
      
        
      <author>dgoosens</author>
        
      
      
      
        
      <category>apiplatform</category>
        
      <category>docker</category>
        
      <category>frankenphp</category>
        
      <category>php</category>
        
      <category>symfony</category>
        
      
      <description>&lt;h1 id=&#34;the-makefile-for-symfony-apiplatform-frankenphp-projects&#34;&gt;the MakeFile for Symfony, ApiPlatform &amp;amp; FrankenPHP projects&lt;a class=&#34;headerlink&#34; href=&#34;#the-makefile-for-symfony-apiplatform-frankenphp-projects&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;This is my simple Makefile when working/playing with Symfony, ApiPlatform &amp;amp; FrankenPHP that run on Docker...
It can easily be adapted to fit any other configuration that runs on Docker &lt;!-- more --&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Also available as an easy &lt;a href=&#34;https://gist.github.com/dgoosens/a5866ba4ccc5098c4410fd638f6c1dae&#34;&gt;gist&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;makefile&#34;&gt;Makefile&lt;a class=&#34;headerlink&#34; href=&#34;#makefile&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;DOCKER_COMPOSE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;compose

&lt;span class=&#34;nv&#34;&gt;.DEFAULT_GOAL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;help&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;##help: List available tasks on this project&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;@echo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;@echo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;These are the available commands&amp;quot;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;@echo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;@grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-E&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;\#\#[a-zA-Z\.\-]+:.*$$&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;MAKEFILE_LIST&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;##&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;awk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;BEGIN {FS = &amp;quot;: &amp;quot;}; {printf &amp;quot;  \033[36m%-30s\033[0m %s\n&amp;quot;, $$1, $$2}&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;


&lt;span class=&#34;c&#34;&gt;##build: Build all docker images&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;build&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;DOCKER_COMPOSE&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;build&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-cache
&lt;span class=&#34;nf&#34;&gt;.PHONY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;build&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;##start: Start containers and make sure they are ready&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;DOCKER_COMPOSE&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;up&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--wait&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d
&lt;span class=&#34;nf&#34;&gt;.PHONY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;##stop: Kill all containers&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;stop&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;DOCKER_COMPOSE&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;kill&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;.PHONY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stop&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;##clean: Remove all containers with their volumes&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;clean&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;DOCKER_COMPOSE&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;down&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--remove-orphans&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;.PHONY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;clean&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;##logs: tail PHP container logs&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;logs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;DOCKER_COMPOSE&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;logs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f
&lt;span class=&#34;nf&#34;&gt;.PHONY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logs&lt;/span&gt;


&lt;span class=&#34;c&#34;&gt;##bash: access the PHP container&amp;#39;s bash&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;bash&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;DOCKER_COMPOSE&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;php&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l
&lt;span class=&#34;nf&#34;&gt;.PHONY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bash&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;##composer: run composer commands [use `--` if multiple arguments]&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;composer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;DOCKER_COMPOSE&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;php&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;composer&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;filter-out&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$@&lt;/span&gt;,&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;MAKECMDGOALS&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;.PHONY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;composer&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;##console: run symfony&amp;#39;s console commands [use `--` if multiple arguments]&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;DOCKER_COMPOSE&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;php&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bin/console&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;filter-out&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$@&lt;/span&gt;,&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;MAKECMDGOALS&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;.PHONY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;console&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;##vbin: run any `bin` script, with arguments, located in your `vendor/bin` [use `--` after the binary]&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;vbin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;DOCKER_COMPOSE&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;php&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;vendor/bin/&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;filter-out&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$@&lt;/span&gt;,&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;MAKECMDGOALS&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;nf&#34;&gt;.PHONY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vbin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run &lt;code&gt;make help&lt;/code&gt; to get the list of commands.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;symfony-makefile.png&#34; src=&#34;../../../../php_symfony-makefile/symfony-makefile.png&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;make console&lt;/code&gt; will list all the &lt;a href=&#34;https://symfony.com/doc/current/console.html&#34;&gt;Symfony Console&lt;/a&gt; commands...
and you just need to append those commands&lt;br /&gt;
for instance:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;make&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;console&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;debug:route
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;make composer&lt;/code&gt; will do the same for composer&lt;br /&gt;
for instance:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;make&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;composer&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;req&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;phpunit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;admonition info&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Info&lt;/p&gt;
&lt;p&gt;Do remember to add &lt;code&gt;--&lt;/code&gt; if there is more than one argument for both the &lt;code&gt;make console&lt;/code&gt; and &lt;code&gt;make composer&lt;/code&gt; commands&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;vbin&lt;/code&gt; command allows to run any script located in the &lt;code&gt;vendor/bin&lt;/code&gt; directory&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;c1&#34;&gt;# example&lt;/span&gt;
make&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;vbin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;schema&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
make&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;vbin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;simple-phpunit

&lt;span class=&#34;c1&#34;&gt;# if you need to pass arguments to the script, use `--`&lt;/span&gt;
make&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;vbin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;schema&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;comes in handy to run things like &lt;code&gt;phpunit&lt;/code&gt; or &lt;code&gt;phpstan&lt;/code&gt; &lt;/p&gt;</description>
      <link>https://notes.belgeek.dev/2023/11/04/the-makefile-for-symfony-apiplatform--frankenphp-projects/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Sat, 04 Nov 2023 00:00:00 +0000</pubDate>
      <source url="https://notes.belgeek.dev/feed_rss_created.xml">Belgeek</source>
      
      <guid isPermaLink="true">https://notes.belgeek.dev/2023/11/04/the-makefile-for-symfony-apiplatform--frankenphp-projects/</guid>
      
      <enclosure url="https://notes.belgeek.dev/assets/images/social/2023/11/04/the-makefile-for-symfony-apiplatform--frankenphp-projects.png" type="image/png" length="77864" />
      
    </item>
    
    <item>
      <title>Git: Squash commits</title>
      
      
        
      <author>dgoosens</author>
        
      
      
      
        
      <category>OSS</category>
        
      <category>git</category>
        
      <category>tools</category>
        
      
      <description>&lt;h1 id=&#34;git-squash-commits&#34;&gt;Git: Squash commits&lt;a class=&#34;headerlink&#34; href=&#34;#git-squash-commits&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;When merging your work into another branch, it may be useful to regroup all the commits into one and indicate a clear commit message that says what has been done. &lt;!-- more --&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;initial-setup&#34;&gt;Initial Setup&lt;a class=&#34;headerlink&#34; href=&#34;#initial-setup&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Working on a new feature while develop continued evolving.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* a78d2b1 (HEAD -&amp;gt; develop) feat: other god feature
* 7a5c8fb feat: hell of a feature
&lt;span class=&#34;hll&#34;&gt;| * ca5ee3c (feature/awesome-feature) found solution for config
&lt;/span&gt;&lt;span class=&#34;hll&#34;&gt;| * aff1a6c fucked up config
&lt;/span&gt;&lt;span class=&#34;hll&#34;&gt;| * 24aaa34 do some other shit
&lt;/span&gt;&lt;span class=&#34;hll&#34;&gt;| * bc471b9 do some shit
&lt;/span&gt;|/  
* 9a6b2f1 feat: bar
* 3a74cdc (main) initial commit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;merge&#34;&gt;Merge?&lt;a class=&#34;headerlink&#34; href=&#34;#merge&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Even after a &lt;code&gt;rebase&lt;/code&gt;, this will become messy:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;hll&#34;&gt;* ca5ee3c (HEAD -&amp;gt; develop) found solution for config
&lt;/span&gt;&lt;span class=&#34;hll&#34;&gt;* aff1a6c fucked up config
&lt;/span&gt;&lt;span class=&#34;hll&#34;&gt;* 24aaa34 do some other shit
&lt;/span&gt;&lt;span class=&#34;hll&#34;&gt;* bc471b9 do some shit
&lt;/span&gt;* a78d2b1 feat: other god feature
* 7a5c8fb feat: hell of a feature
* 9a6b2f1 feat: bar
* 3a74cdc (main) initial commit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Very ugly, not efficient!&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;squash-it-baby&#34;&gt;Squash it baby!&lt;a class=&#34;headerlink&#34; href=&#34;#squash-it-baby&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&#34;1-git-reset-soft&#34;&gt;1. git reset --soft&lt;a class=&#34;headerlink&#34; href=&#34;#1-git-reset-soft&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/awesome-feature
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reset&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--soft&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;9a6b2f1&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# where 9a6b2f1 is the point you diverted from develop&lt;/span&gt;
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;add&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;commit&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-m&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;feat: awesome feature with good commit message&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Result:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;hll&#34;&gt;* 51a726c (HEAD -&amp;gt; feature/awesome-feature) feat: awesome feature with good commit message
&lt;/span&gt;| * 2abdf42 (develop) feat: other god feature
| * 7a5c8fb feat: hell of a feature
|/  
* 9a6b2f1 feat: bar
* 3a74cdc (main) initial commit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;2-git-rebase&#34;&gt;2. git rebase&lt;a class=&#34;headerlink&#34; href=&#34;#2-git-rebase&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;develop
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# make sure develop is up to date&lt;/span&gt;
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/awesome-feature
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rebase&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;develop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Result:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* de09afd (HEAD -&amp;gt; feature/awesome-feature) feat: awesome feature with good commit message
* a78d2b1 (develop) feat: other god feature
* 7a5c8fb feat: hell of a feature
* 9a6b2f1 feat: bar
* 3a74cdc (main) initial commit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;admonition note&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Note&lt;/p&gt;
&lt;p&gt;Rebasing will also become much easier as there will only be &lt;strong&gt;ONE&lt;/strong&gt; commit to replay&lt;br /&gt;
And not the WHOLE history&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&#34;3-git-merge&#34;&gt;3. git merge&lt;a class=&#34;headerlink&#34; href=&#34;#3-git-merge&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;develop
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;merge&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/awesome-feature&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# and use the same good commit message as above&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Result:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;hll&#34;&gt;* de09afd (HEAD -&amp;gt; develop, feature/awesome-feature) feat: awesome feature with good commit message
&lt;/span&gt;* a78d2b1 feat: other god feature
* 7a5c8fb feat: hell of a feature
* 9a6b2f1 feat: bar
* 3a74cdc (main) initial commit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;4-cleanup&#34;&gt;4. Cleanup&lt;a class=&#34;headerlink&#34; href=&#34;#4-cleanup&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;branch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/awesome-feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Result:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;hll&#34;&gt;* de09afd (HEAD -&amp;gt; develop) feat: awesome feature with good commit message
&lt;/span&gt;* a78d2b1 feat: other god feature
* 7a5c8fb feat: hell of a feature
* 9a6b2f1 feat: bar
* 3a74cdc (main) initial commit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;in-short&#34;&gt;In short&lt;a class=&#34;headerlink&#34; href=&#34;#in-short&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;c1&#34;&gt;# squash&lt;/span&gt;
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;__feature/branch__
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reset&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--soft&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;__latest_common_parent__
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;add&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;commit&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-m&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;__good_commit_message__&amp;#39;&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;# rebase&lt;/span&gt;
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;__base/branch__
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;__feature/branch__
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rebase&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;__base/branch__

&lt;span class=&#34;c1&#34;&gt;# merge&lt;/span&gt;
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;__base/branch__
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;merge&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;__feature/branch__

&lt;span class=&#34;c1&#34;&gt;# cleanup&lt;/span&gt;
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;branch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;__feature/branch__
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;And don&#39;t forget to push your commit !&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;admonition note&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Note&lt;/p&gt;
&lt;p&gt;You can use &lt;code&gt;git-merge-base&lt;/code&gt; to find the latest common commit of two branches.&lt;br /&gt;
See &lt;a href=&#34;../../02/git-find-latest-common-ancestor-of-two-branches/&#34;&gt;Git: Find latest common ancestor of two branches&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</description>
      <link>https://notes.belgeek.dev/2023/11/03/git-squash-commits/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Fri, 03 Nov 2023 00:00:00 +0000</pubDate>
      <source url="https://notes.belgeek.dev/feed_rss_created.xml">Belgeek</source>
      
      <guid isPermaLink="true">https://notes.belgeek.dev/2023/11/03/git-squash-commits/</guid>
      
      <enclosure url="https://notes.belgeek.dev/assets/images/social/2023/11/03/git-squash-commits.png" type="image/png" length="59084" />
      
    </item>
    
    <item>
      <title>Git: Find latest common ancestor of two branches</title>
      
      
        
      <author>dgoosens</author>
        
      
      
      
        
      <category>OSS</category>
        
      <category>git</category>
        
      <category>tools</category>
        
      
      <description>&lt;h1 id=&#34;git-find-latest-common-ancestor-of-two-branches&#34;&gt;Git: Find latest common ancestor of two branches&lt;a class=&#34;headerlink&#34; href=&#34;#git-find-latest-common-ancestor-of-two-branches&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;To find the latest common ancestor of two branches, which is required, for instance, when squashing your commits, instead of scrolling through you &lt;code&gt;git log&lt;/code&gt; history you can use the &lt;code&gt;git-merge-base&lt;/code&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; tool. &lt;!-- more --&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;an-example-is-worth-a-1000-words&#34;&gt;An example is worth a 1000 words&lt;a class=&#34;headerlink&#34; href=&#34;#an-example-is-worth-a-1000-words&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;merge-base&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;__CURRENT_BRANCH__&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;__ANCESTOR_BRANCH__

&lt;span class=&#34;c1&#34;&gt;# for instance&lt;/span&gt;
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;merge-base&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;develop&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;main&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# will output the hash of the latest commit in common&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;admonition note&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Note&lt;/p&gt;
&lt;p&gt;Make sure that both branches are up to date to avoid the apocalypse!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;footnote&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Official &lt;code&gt;git-merge&lt;/code&gt; documentation can be found here: &lt;a href=&#34;https://git-scm.com/docs/git-merge-base&#34;&gt;https://git-scm.com/docs/git-merge-base&lt;/a&gt;&amp;#160;&lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:1&#34; title=&#34;Jump back to footnote 1 in the text&#34;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <link>https://notes.belgeek.dev/2023/11/02/git-find-latest-common-ancestor-of-two-branches/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 02 Nov 2023 00:00:00 +0000</pubDate>
      <source url="https://notes.belgeek.dev/feed_rss_created.xml">Belgeek</source>
      
      <guid isPermaLink="true">https://notes.belgeek.dev/2023/11/02/git-find-latest-common-ancestor-of-two-branches/</guid>
      
      <enclosure url="https://notes.belgeek.dev/assets/images/social/2023/11/02/git-find-latest-common-ancestor-of-two-branches.png" type="image/png" length="67700" />
      
    </item>
    
    <item>
      <title>Git: Rebase with dependent branches</title>
      
      
        
      <author>dgoosens</author>
        
      
      
      
        
      <category>OSS</category>
        
      <category>git</category>
        
      <category>tools</category>
        
      
      <description>&lt;h1 id=&#34;git-rebase-with-dependent-branches&#34;&gt;Git: Rebase with dependent branches&lt;a class=&#34;headerlink&#34; href=&#34;#git-rebase-with-dependent-branches&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Rebasing a branch on another is very common...&lt;br /&gt;
Yet by default, the dependent branches of the rebased branch will remain where they are and not follow the rebase.&lt;br /&gt;
This notes shows how to deal with those dependent branches. &lt;!-- more --&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;a class=&#34;headerlink&#34; href=&#34;#the-problem&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At some point in time, you will end up with a situation as described below where you have a branch (&lt;code&gt;main&lt;/code&gt;), with a child branch (&lt;code&gt;feature/foo&lt;/code&gt;) with a child-child branch (&lt;code&gt;feature/bar&lt;/code&gt;).&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;&lt;code&gt;graph LR
  A[A] --&amp;gt; B[B];
  B[B] --&amp;gt; C[C];
  C[C] --&amp;gt; D[D];
  D[D] --&amp;gt; E[E];
  E[E] -.- F{{main}};
  C[C] --&amp;gt; G[G];
  G[G] --&amp;gt; H[H];
  H[H] --&amp;gt; I[I];
  I[I] -.- J{{feature/foo}};
  H[H] --&amp;gt; K[K];
  K[K] --&amp;gt; L[L];
  L[L] -.- M{{feature/bar}};
  style F fill:#000,stroke:#000,color:#fff;
  style J fill:#000,stroke:#000,color:#fff;
  style M fill:#000,stroke:#000,color:#fff;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using rebase here &lt;em&gt;is&lt;/em&gt; complicated.&lt;/p&gt;
&lt;p&gt;Start by rebasing the first child (in this case &lt;code&gt;feature/foo&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/foo
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rebase&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;main
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You&#39;ll end up with this:&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;&lt;code&gt;graph LR
  A[A] --&amp;gt; B[B];
  B[B] --&amp;gt; C[C];
  C[C] --&amp;gt; D[D];
  D[D] --&amp;gt; E[E];
  E[E] -.- F{{main}};
  E[E] --&amp;gt; GG[G&#39;];
  GG[G&#39;] --&amp;gt; HH[H&#39;];
  HH[H&#39;] --&amp;gt; II[I&#39;];
  II[I&#39;] -.- JJ{{feature/foo}};
  C[C] --&amp;gt; G[G];
  G[G] --&amp;gt; H[H];
  H[H] --&amp;gt; K[K];
  K[K] --&amp;gt; L[L];
  L[L] -.- M{{feature/bar}};
  style F fill:#000,stroke:#000,color:#fff;
  style JJ fill:#000,stroke:#000,color:#fff;
  style M fill:#000,stroke:#000,color:#fff;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, &lt;code&gt;feature/foo&lt;/code&gt; has been rebased on &lt;code&gt;main&lt;/code&gt;... &lt;strong&gt;BUT&lt;/strong&gt; &lt;code&gt;feature/bar&lt;/code&gt; has been left where it was.&lt;/p&gt;
&lt;h2 id=&#34;wrong&#34;&gt;WRONG&lt;a class=&#34;headerlink&#34; href=&#34;#wrong&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you were to run a rebase with &lt;code&gt;feature/bar&lt;/code&gt; like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/bar
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rebase&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;main
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You end up with something like this:&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;&lt;code&gt;graph LR
  A[A] --&amp;gt; B[B];
  B[B] --&amp;gt; C[C];
  C[C] --&amp;gt; D[D];
  D[D] --&amp;gt; E[E];
  E[E] -.- F{{main}};
  E[E] --&amp;gt; GG[G&#39;];
  GG[G&#39;] --&amp;gt; HH[H&#39;];
  HH[H&#39;] --&amp;gt; II[I&#39;];
  II[I&#39;] -.- JJ{{feature/foo}};
  E[E] --&amp;gt; G[G&#39;&#39;];
  G[G&#39;&#39;] --&amp;gt; H[H&#39;&#39;];
  H[H&#39;&#39;] --&amp;gt; K[K&#39;&#39;];
  K[K&#39;&#39;] --&amp;gt; L[L&#39;&#39;];
  L[L&#39;&#39;] -.- M{{feature/bar}};
  style F fill:#000,stroke:#000,color:#fff;
  style JJ fill:#000,stroke:#000,color:#fff;
  style M fill:#000,stroke:#000,color:#fff;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;NOT WHAT YOU&#39;RE LOOKING FOR&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Could get worse...
Trying to rebase on &lt;code&gt;feature/foo&lt;/code&gt; will result in this (after dealing with a lot of conflicts):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/bar
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rebase&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/foo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre class=&#34;mermaid&#34;&gt;&lt;code&gt;graph LR
  A[A] --&amp;gt; B[B];
  B[B] --&amp;gt; C[C];
  C[C] --&amp;gt; D[D];
  D[D] --&amp;gt; E[E];
  E[E] -.- F{{main}};
  E[E] --&amp;gt; GG[G&#39;];
  GG[G&#39;] --&amp;gt; HH[H&#39;];
  HH[H&#39;] --&amp;gt; II[I&#39;];
  II[I&#39;] -.- JJ{{feature/foo}};
  II[I&#39;] --&amp;gt; G[G&#39;&#39;];
  G[G&#39;&#39;] --&amp;gt; H[H&#39;&#39;];
  H[H&#39;&#39;] --&amp;gt; K[K&#39;&#39;];
  K[K&#39;&#39;] --&amp;gt; L[L&#39;&#39;];
  L[L&#39;&#39;] -.- M{{feature/bar}};
  style F fill:#000,stroke:#000,color:#fff;
  style JJ fill:#000,stroke:#000,color:#fff;
  style M fill:#000,stroke:#000,color:#fff;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, commits &lt;code&gt;G&lt;/code&gt; &amp;amp; &lt;code&gt;H&lt;/code&gt; have been redone even though they ought to be skipped.
&lt;strong&gt;STILL NOT WHAT YOU&#39;RE LOOKING FOR&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;screaming.gif&#34; src=&#34;../../../../common/screaming.gif&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;the-solution&#34;&gt;THE SOLUTION&lt;a class=&#34;headerlink&#34; href=&#34;#the-solution&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The solution is to use the &lt;code&gt;--onto&lt;/code&gt; feature of &lt;code&gt;git rebase&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/bar
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rebase&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--onto&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;hash_of_H&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/foo@&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;@{1}&lt;/code&gt; in the above code means: the latest known state of &lt;code&gt;feature/foo&lt;/code&gt; &lt;strong&gt;before&lt;/strong&gt; the rebase.&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;&lt;code&gt;graph LR
  A[A] --&amp;gt; B[B];
  B[B] --&amp;gt; C[C];
  C[C] --&amp;gt; D[D];
  D[D] --&amp;gt; E[E];
  E[E] -.- F{{main}};
  E[E] --&amp;gt; GG[G&#39;];
  GG[G&#39;] --&amp;gt; HH[H&#39;];
  HH[H&#39;] --&amp;gt; II[I&#39;];
  II[I&#39;] -.- JJ{{feature/foo}};
  HH[H&#39;] --&amp;gt; K[K&#39;];
  K[K&#39;] --&amp;gt; L[L&#39;];
  L[L&#39;] -.- M{{feature/bar}};
  style F fill:#000,stroke:#000,color:#fff;
  style JJ fill:#000,stroke:#000,color:#fff;
  style M fill:#000,stroke:#000,color:#fff;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;PERFECT !&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Note that, if &lt;code&gt;feature/bar&lt;/code&gt; had been branched on the last commit of &lt;code&gt;feature/foo&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;&lt;code&gt;graph LR
  A[A] --&amp;gt; B[B];
  B[B] --&amp;gt; C[C];
  C[C] --&amp;gt; D[D];
  D[D] --&amp;gt; E[E];
  E[E] -.- F{{main}};
  C[C] --&amp;gt; G[G];
  G[G] --&amp;gt; H[H];
  H[H] -.- J{{feature/foo}};
  H[H] --&amp;gt; K[K];
  K[K] --&amp;gt; L[L];
  L[L] -.- M{{feature/bar}};
  style F fill:#000,stroke:#000,color:#fff;
  style J fill:#000,stroke:#000,color:#fff;
  style M fill:#000,stroke:#000,color:#fff;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The command would have been more simple:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/foo
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rebase&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;main
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/bar
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rebase&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--onto&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/foo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/foo@&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;pre class=&#34;mermaid&#34;&gt;&lt;code&gt;graph LR
  A[A] --&amp;gt; B[B];
  B[B] --&amp;gt; C[C];
  C[C] --&amp;gt; D[D];
  D[D] --&amp;gt; E[E];
  E[E] -.- F{{main}};
  E[E] --&amp;gt; GG[G&#39;];
  GG[G&#39;] --&amp;gt; HH[H&#39;];
  HH[H&#39;] -.- JJ{{feature/foo}};
  HH[H&#39;] --&amp;gt; K[K&#39;];
  K[K&#39;] --&amp;gt; L[L&#39;];
  L[L&#39;] -.- M{{feature/bar}};
  style F fill:#000,stroke:#000,color:#fff;
  style JJ fill:#000,stroke:#000,color:#fff;
  style M fill:#000,stroke:#000,color:#fff;&lt;/code&gt;&lt;/pre&gt;</description>
      <link>https://notes.belgeek.dev/2023/10/30/git-rebase-with-dependent-branches/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Mon, 30 Oct 2023 00:00:00 +0000</pubDate>
      <source url="https://notes.belgeek.dev/feed_rss_created.xml">Belgeek</source>
      
      <guid isPermaLink="true">https://notes.belgeek.dev/2023/10/30/git-rebase-with-dependent-branches/</guid>
      
      <enclosure url="https://notes.belgeek.dev/assets/images/social/2023/10/30/git-rebase-with-dependent-branches.png" type="image/png" length="60070" />
      
    </item>
    
    <item>
      <title>Git: Update local branch after rebase</title>
      
      
        
      <author>dgoosens</author>
        
      
      
      
        
      <category>OSS</category>
        
      <category>git</category>
        
      <category>tools</category>
        
      
      <description>&lt;h1 id=&#34;git-update-local-branch-after-rebase&#34;&gt;Git: Update local branch after rebase&lt;a class=&#34;headerlink&#34; href=&#34;#git-update-local-branch-after-rebase&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Quite often we have to use the &lt;a href=&#34;https://git-scm.com/book/en/v2/Git-Branching-Rebasing&#34;&gt;&lt;code&gt;git rebase&lt;/code&gt;&lt;/a&gt; to realign the branch we are working on with the latest version of its parent branch.&lt;br /&gt;
After the rebase, your coworkers need to update their version of the branch. &lt;!-- more --&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;The problem&lt;a class=&#34;headerlink&#34; href=&#34;#the-problem&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You, and your coworkers are working on a new feature...
Obviously, you created a feature branch to work on.&lt;br /&gt;
A couple of sprints further, the other teams have continued to fix bugs or implemented their features.&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;&lt;code&gt;graph LR
  A[A] --&amp;gt; B[B];
  B[B] --&amp;gt; C[C];
  C[C] --&amp;gt; D[D];
  D[D] --&amp;gt; E[E];
  E[E] -.- F{{main}};
  C[C] --&amp;gt; GG[G];
  GG[G] --&amp;gt; HH[H];
  HH[H] --&amp;gt; II[I];
  II[I] -.- JJ{{feature/foo}};&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You ar no longer aligned with the latest version.
If your feature is done, a &lt;code&gt;git merge&lt;/code&gt; might be an option... but quite often, one will use a &lt;code&gt;git rebase&lt;/code&gt; to realign the branches.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/foo
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rebase&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;main
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Done...&lt;br /&gt;
On your side.&lt;/p&gt;
&lt;p&gt;But your coworkers also need the rebased version of the feature branch.&lt;br /&gt;
A &lt;code&gt;git pull&lt;/code&gt; will not work as a &lt;code&gt;git rebase&lt;/code&gt; rewrites the commits and therefor the hashes won&#39;t match.&lt;/p&gt;
&lt;h2 id=&#34;this-is-the-way&#34;&gt;This is the way&lt;a class=&#34;headerlink&#34; href=&#34;#this-is-the-way&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&#34;the-long-option&#34;&gt;The long option&lt;a class=&#34;headerlink&#34; href=&#34;#the-long-option&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;checkout to another branch&lt;/li&gt;
&lt;li&gt;delete local branch&lt;/li&gt;
&lt;li&gt;fetch latest version of the branch from the repo&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;main
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;branch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-D&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/foo
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;checkout&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/foo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But we developers are lazy...&lt;br /&gt;
This can go faster&lt;/p&gt;
&lt;h3 id=&#34;in-two-lines&#34;&gt;In two lines&lt;a class=&#34;headerlink&#34; href=&#34;#in-two-lines&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is more efficient:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;fetch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;origin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;feature/foo
git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reset&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--hard&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;origin/feature/foo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;admonition warning&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Warning&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;git reset&lt;/code&gt; will remove all uncommitted changes AND all the commits that were not pushed to the repository before the rebase will be lost. &lt;/p&gt;
&lt;/div&gt;</description>
      <link>https://notes.belgeek.dev/2023/10/30/git-update-local-branch-after-rebase/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Mon, 30 Oct 2023 00:00:00 +0000</pubDate>
      <source url="https://notes.belgeek.dev/feed_rss_created.xml">Belgeek</source>
      
      <guid isPermaLink="true">https://notes.belgeek.dev/2023/10/30/git-update-local-branch-after-rebase/</guid>
      
      <enclosure url="https://notes.belgeek.dev/assets/images/social/2023/10/30/git-update-local-branch-after-rebase.png" type="image/png" length="58958" />
      
    </item>
    
    <item>
      <title>Git: Undo reset --hard</title>
      
      
        
      <author>dgoosens</author>
        
      
      
      
        
      <category>OSS</category>
        
      <category>git</category>
        
      <category>tools</category>
        
      
      <description>&lt;h1 id=&#34;git-undo-reset-hard&#34;&gt;Git: Undo reset --hard&lt;a class=&#34;headerlink&#34; href=&#34;#git-undo-reset-hard&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Sometimes one is distracted... and an accidental &lt;code&gt;git reset --hard&lt;/code&gt; happens.&lt;br /&gt;
But within a few days after the accident, you can recover from the GIT reflog.&lt;!-- more --&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;facepalm-moment&#34;&gt;Facepalm moment&lt;a class=&#34;headerlink&#34; href=&#34;#facepalm-moment&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reset&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--hard&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;HEAD^
HEAD&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;is&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;now&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;at&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;1a75c1d...&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;added&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;file1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now all the local data of &lt;code&gt;HEAD&lt;/code&gt; is gone...&lt;br /&gt;
And if you did not push that work to a remote repository, this is one of those facepalms moments.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Double facepalm&#34; src=&#34;../../../../common/double-facepalm.gif&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;but-there-is-a-solution&#34;&gt;But there is a solution !&lt;a class=&#34;headerlink&#34; href=&#34;#but-there-is-a-solution&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The git &lt;code&gt;reflog&lt;/code&gt;...&lt;br /&gt;
You can read everything there is to know about the reflog in the &lt;a href=&#34;https://git-scm.com/docs/git-reflog&#34;&gt;official documentation&lt;/a&gt;...&lt;br /&gt;
But tl;dr:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The reference log, aka &lt;code&gt;reflog&lt;/code&gt;, is a &lt;strong&gt;local&lt;/strong&gt; chronological history of all the changes that are made to the references, which are names that point to the different objects used by Git (commit hashes, tags, branches etc)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We can use the &lt;code&gt;reflog&lt;/code&gt; to view all those changes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reflog
1a75c1d...&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;HEAD@&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reset&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--hard&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;HEAD^:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;updating&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;HEAD
f6e5064...&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;HEAD@&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;commit:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;added&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;file2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To revert to the point before the hard reset accident:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reset&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--hard&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;f6e5064
HEAD&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;is&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;now&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;at&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;f6e5064...&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;added&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;file2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As one can see, it was possible to revert to commit &lt;code&gt;f6e5064&lt;/code&gt; and recover the otherwise lost work.&lt;/p&gt;
&lt;div class=&#34;admonition note&#34;&gt;
&lt;p class=&#34;admonition-title&#34;&gt;Note&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;By default, the reflogs are stored for 90 days...&lt;/li&gt;
&lt;li&gt;The reflogs are local only. They are not sent to the repository when pushing commits&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</description>
      <link>https://notes.belgeek.dev/2023/10/30/git-undo-reset---hard/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Mon, 30 Oct 2023 00:00:00 +0000</pubDate>
      <source url="https://notes.belgeek.dev/feed_rss_created.xml">Belgeek</source>
      
      <guid isPermaLink="true">https://notes.belgeek.dev/2023/10/30/git-undo-reset---hard/</guid>
      
      <enclosure url="https://notes.belgeek.dev/assets/images/social/2023/10/30/git-undo-reset---hard.png" type="image/png" length="59335" />
      
    </item>
    
    <item>
      <title>Discovery week (announcement)</title>
      
      
        
      <author>dgoosens</author>
        
      
      
      
        
      <category>devLife</category>
        
      <category>process</category>
        
      <category>team</category>
        
      
      <description>&lt;h1 id=&#34;discovery-week-announcement&#34;&gt;Discovery week (announcement)&lt;a class=&#34;headerlink&#34; href=&#34;#discovery-week-announcement&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;A couple of weeks ago, the &lt;strong&gt;&lt;a href=&#34;https://en.ardennes-etape.be/&#34;&gt;Ardennes-etape&lt;/a&gt;&lt;/strong&gt; Digital team organized its first « &lt;strong&gt;discovery week&lt;/strong&gt; ». One whole week where all projects and bugs, except for emergencies, obviously, were paused and where all the team members were able to discover...  &lt;!-- more --&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt=&#34;geek-thumb-up&#34; src=&#34;../../../../common/geek-thumb-up.gif&#34; /&gt;&lt;/p&gt;
&lt;p&gt;The objective was to spend time, together or alone, on a topic that was somehow related to our daily work, but that is too complex or time consuming to tackle within our regular sprints...&lt;/p&gt;
&lt;p&gt;Part of the team spent time getting up to speed with tools like Figma or, more generally, good UX practices (thanks &lt;a href=&#34;https://www.linkedin.com/in/ptaveira/&#34;&gt;Pedro&lt;/a&gt;).&lt;br /&gt;
Others dove into the hot topic of the moment, ie AI, and played around with ChatGPT, LangChain... Even though this was absolutely not required, they came up with very interesting proofs of concepts that will soon help everybody within the company to be more efficient.&lt;br /&gt;
Other research topics were Machine Learning, Docker, ElasticSearch, CI, pact.io (interface testing), latest NextJs release etc. &lt;br /&gt;
At the end of the week, time was spent to show and discuss our findings.&lt;/p&gt;
&lt;p&gt;As mentioned, this was our first « discovery week »... It was itself a proof of concept we heard about from other tech companies, but that needed to be tested and validated at Ardennes-étape...&lt;/p&gt;
&lt;p&gt;Conclusions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the whole team was able to take some time off from the daily business while remaining productive&lt;/li&gt;
&lt;li&gt;some excellent new skills were acquired&lt;/li&gt;
&lt;li&gt;time for some fresh tech-air does feel good&lt;/li&gt;
&lt;li&gt;and, although not required, some interesting, almost prod-ready, proof of concepts...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So overall the discovery week was a great success and everybody agrees this should be repeated, once every four months, aligned with our OKR cycle...&lt;/p&gt;</description>
      <link>https://notes.belgeek.dev/2023/06/20/discovery-week-announcement/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Tue, 20 Jun 2023 00:00:00 +0000</pubDate>
      <source url="https://notes.belgeek.dev/feed_rss_created.xml">Belgeek</source>
      
      <guid isPermaLink="true">https://notes.belgeek.dev/2023/06/20/discovery-week-announcement/</guid>
      
      <enclosure url="https://notes.belgeek.dev/assets/images/social/2023/06/20/discovery-week-announcement.png" type="image/png" length="65016" />
      
    </item>
    
    <item>
      <title>Rust</title>
      
      
        
      <author>dgoosens</author>
        
      
      
      
        
      <category>OSS</category>
        
      <category>Rust</category>
        
      
      <description>&lt;h1 id=&#34;rust&#34;&gt;Rust&lt;a class=&#34;headerlink&#34; href=&#34;#rust&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Still did not have time to get into it, very frustrating...&lt;br /&gt;
Figured putting this note here would help me to prioritize it a little. &lt;!-- more --&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;2023-12-27&#34;&gt;2023-12-27&lt;a class=&#34;headerlink&#34; href=&#34;#2023-12-27&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At last... Some time during the Xmas holidays to jump back into &lt;a href=&#34;/category/rust&#34;&gt;&lt;strong&gt;#Rust&lt;/strong&gt;&lt;/a&gt;!&lt;br /&gt;
Here is my first contribution: &lt;a href=&#34;../../../../2023/12/27/rust----integer-overflow/&#34;&gt;Rust -- Integer Overflow&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;2023-06-12&#34;&gt;2023-06-12&lt;a class=&#34;headerlink&#34; href=&#34;#2023-06-12&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Time is not on my side...&lt;br /&gt;
No it isn&#39;t&lt;/p&gt;
&lt;h2 id=&#34;2023-10-30&#34;&gt;2023-10-30&lt;a class=&#34;headerlink&#34; href=&#34;#2023-10-30&#34; title=&#34;Permanent link&#34;&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;../../../../common/mr-bean-waiting.gif&#34; /&gt;&lt;/p&gt;</description>
      <link>https://notes.belgeek.dev/2022/12/29/rust/?utm_source=documentation&amp;utm_medium=RSS&amp;utm_campaign=feed-syndication</link>
      <pubDate>Thu, 29 Dec 2022 00:00:00 +0000</pubDate>
      <source url="https://notes.belgeek.dev/feed_rss_created.xml">Belgeek</source>
      
      <guid isPermaLink="true">https://notes.belgeek.dev/2022/12/29/rust/</guid>
      
      <enclosure url="https://notes.belgeek.dev/assets/images/social/2022/12/29/rust.png" type="image/png" length="45972" />
      
    </item>
    
  </channel>
</rss>