<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="http://dotcom.software/feed.xml" rel="self" type="application/atom+xml" /><link href="http://dotcom.software/" rel="alternate" type="text/html" /><updated>2025-11-11T20:23:13+00:00</updated><id>http://dotcom.software/feed.xml</id><title type="html">Mike’s dev blog</title><subtitle>Programming enthusiast, mostly PHP. Father of two.</subtitle><entry><title type="html">Floating Dangers in PHP</title><link href="http://dotcom.software/dangers-of-floats-in-php/" rel="alternate" type="text/html" title="Floating Dangers in PHP" /><published>2022-10-04T00:00:00+00:00</published><updated>2022-10-04T00:00:00+00:00</updated><id>http://dotcom.software/dangers-of-floats-in-php</id><content type="html" xml:base="http://dotcom.software/dangers-of-floats-in-php/"><![CDATA[<p>Are you working with currencies? Do you use floats? You have to be extremely careful. Check out why.</p>

<h2 id="floating-dangers-in-php-on-medium"><a href="https://medium.com/@dotcom.software/floating-dangers-in-php-c4a2220bd8dc">Floating Dangers in PHP</a> on Medium.</h2>]]></content><author><name></name></author><summary type="html"><![CDATA[How to correctly compare floats in PHP? What are the dangers of using floating numbers in PHP.]]></summary></entry><entry><title type="html">Primitive obsession anti-pattern</title><link href="http://dotcom.software/primitive-obsession-antipattern/" rel="alternate" type="text/html" title="Primitive obsession anti-pattern" /><published>2022-08-21T00:00:00+00:00</published><updated>2022-08-21T00:00:00+00:00</updated><id>http://dotcom.software/primitive-obsession-antipattern</id><content type="html" xml:base="http://dotcom.software/primitive-obsession-antipattern/"><![CDATA[<p>The primitive obsession is a kind of a smell that indicates poor code quality. We consider boolean, string, int, and float as primitive types in PHP. They are the building blocks you cannot avoid but they can be arranged into meaningful domain objects instead…</p>

<h2 id="primitive-obsession-anti-pattern-on-medium"><a href="https://blog.devgenius.io/primitive-obsession-anti-pattern-83fb5dcd5cc2">Primitive obsession anti-pattern</a> on Medium.</h2>]]></content><author><name></name></author><summary type="html"><![CDATA[Improve your code by reducing this code smell from the heart of your application]]></summary></entry><entry><title type="html">Unit testing Twig’s Lazy Extensions</title><link href="http://dotcom.software/unit-testing-lazy-twig-extensions/" rel="alternate" type="text/html" title="Unit testing Twig’s Lazy Extensions" /><published>2020-06-15T00:00:00+00:00</published><updated>2020-06-15T00:00:00+00:00</updated><id>http://dotcom.software/unit-testing-lazy-twig-extensions</id><content type="html" xml:base="http://dotcom.software/unit-testing-lazy-twig-extensions/"><![CDATA[<p><a href="/efficient-twig-extensions/">Last time</a> we wrote a 
<a href="https://symfony.com/doc/current/templating/twig_extension.html#creating-lazy-loaded-twig-extensions">lazy Twig extension</a>
to speed up Twig initialization time.</p>

<p>Today it’s time to test it. There’s an excellent helper class called <code class="language-plaintext highlighter-rouge">IntegrationTestCase</code> in the Twig package.
This class expects a directory containing Twig test cases called “fixtures”.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CheckoutStepsExtensionTest</span> <span class="kd">extends</span> <span class="nc">IntegrationTestCase</span>
<span class="p">{</span>
    <span class="cd">/**
     * The directory with test cases
     */</span>
    <span class="k">protected</span> <span class="k">function</span> <span class="n">getFixturesDir</span><span class="p">():</span> <span class="kt">string</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="k">__DIR__</span> <span class="mf">.</span> <span class="s1">'/Fixtures'</span><span class="p">;</span>
    <span class="p">}</span>
    
    <span class="cd">/**
     * Unit tested extensions
     */</span>
    <span class="k">protected</span> <span class="k">function</span> <span class="n">getExtensions</span><span class="p">():</span> <span class="kt">array</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="p">[</span><span class="k">new</span> <span class="nc">CheckoutStepsExtension</span><span class="p">()];</span>
    <span class="p">}</span>
    
    <span class="cd">/**
     * Called functions expects an "Order" object.
     * Lets create a helper function will will return an Order.
     */</span>
    <span class="k">protected</span> <span class="k">function</span> <span class="n">getTwigFunctions</span><span class="p">():</span> <span class="kt">array</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="p">[</span>
            <span class="k">new</span> <span class="nc">TwigFunction</span><span class="p">(</span><span class="s1">'get_test_order'</span><span class="p">,</span> <span class="k">function</span> <span class="p">():</span> <span class="kt">OrderInterface</span> <span class="p">{</span>
                <span class="k">return</span> <span class="k">new</span> <span class="nc">Order</span><span class="p">();</span>
            <span class="p">}),</span>
        <span class="p">];</span>
    <span class="p">}</span>

    <span class="cd">/**
     * Since the runtime depends on its dependencies when created
     * we need to register custom runtime loader which will spawn called runtime.
     * For the sake of simplicity, we will mock the actual helper.
     */</span>
    <span class="k">protected</span> <span class="k">function</span> <span class="n">getRuntimeLoaders</span><span class="p">():</span> <span class="kt">array</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="p">[</span><span class="k">new</span> <span class="nc">FactoryRuntimeLoader</span><span class="p">([</span>
            <span class="nc">CheckoutStepsHelperRuntime</span><span class="o">::</span><span class="n">class</span> <span class="o">=&gt;</span> <span class="k">function</span> <span class="p">():</span> <span class="kt">CheckoutStepsHelperRuntime</span> <span class="p">{</span>
                <span class="nv">$helper</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">prophesize</span><span class="p">(</span><span class="nc">CheckoutStepsHelper</span><span class="o">::</span><span class="n">class</span><span class="p">);</span>
                <span class="nv">$helper</span><span class="o">-&gt;</span><span class="nf">isShippingRequired</span><span class="p">(</span><span class="nc">Argument</span><span class="o">::</span><span class="nf">type</span><span class="p">(</span><span class="nc">Order</span><span class="o">::</span><span class="n">class</span><span class="p">))</span><span class="o">-&gt;</span><span class="nf">willReturn</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
                <span class="nv">$helper</span><span class="o">-&gt;</span><span class="nf">isPaymentRequired</span><span class="p">(</span><span class="nc">Argument</span><span class="o">::</span><span class="nf">type</span><span class="p">(</span><span class="nc">Order</span><span class="o">::</span><span class="n">class</span><span class="p">))</span><span class="o">-&gt;</span><span class="nf">willReturn</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>

                <span class="k">return</span> <span class="k">new</span> <span class="nc">CheckoutStepsHelperRuntime</span><span class="p">(</span><span class="nv">$helper</span><span class="o">-&gt;</span><span class="nf">reveal</span><span class="p">());</span>
            <span class="p">}</span>
        <span class="p">])];</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The test is complete, lets create some tests inside the “fixtures” directory:</p>

<p>The <code class="language-plaintext highlighter-rouge">fixtures/functions/sylius_is_shipping_required.test</code> file:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>--TEST--
"sylius_is_shipping_required" function
--TEMPLATE--

--DATA--
return []
--EXPECT--
yes
</code></pre></div></div>

<p>Finally the <code class="language-plaintext highlighter-rouge">fixtures/functions/sylius_is_payment_required.test</code> file:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>--TEST--
"sylius_is_payment_required" function
--TEMPLATE--

--DATA--
return []
--EXPECT--
yes
</code></pre></div></div>

<p>Run the suite <code class="language-plaintext highlighter-rouge">vendor/bin/phpunit</code> and we should be GREEN OK! 
We are yellow OK though since the test case runs some weird <code class="language-plaintext highlighter-rouge">testLegacyIntegration</code> test which gets skipped.</p>

<p>However if we were to change the expectation to “no” we would end up with:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'no'
+'yes'

/var/www/html/vendor/twig/twig/src/Test/IntegrationTestCase.php:251
/var/www/html/vendor/twig/twig/src/Test/IntegrationTestCase.php:82
</code></pre></div></div>]]></content><author><name></name></author><summary type="html"><![CDATA[Last time we wrote a lazy Twig Extension. Today it's time to test it.]]></summary></entry><entry><title type="html">Efficient Twig extensions using Lazy Extensions</title><link href="http://dotcom.software/efficient-twig-extensions/" rel="alternate" type="text/html" title="Efficient Twig extensions using Lazy Extensions" /><published>2020-03-07T00:00:00+00:00</published><updated>2020-03-07T00:00:00+00:00</updated><id>http://dotcom.software/efficient-twig-extensions</id><content type="html" xml:base="http://dotcom.software/efficient-twig-extensions/"><![CDATA[<p><a href="https://symfony.com/doc/current/templating/twig_extension.html#creating-lazy-loaded-twig-extensions">Lazy Twig extensions</a>
were introduced in Twig 1.35 / 2.4.4, albeit there’re still see so many Symfony apps that don’t use them.</p>

<p>One has to be aware that to create the Twig environment, every extension has to be instantiated.
Now multiply that by the number of extensions in your app, some of them with possibly large dependency tree.</p>

<p>For instance, take a look at <a href="https://sylius.com/">Sylius</a> – popular e-commerce platform based on Symfony 
and its <code class="language-plaintext highlighter-rouge">CheckoutStepsExtension</code> – it depends on a helper, which depends on two services, both depending on composite 
resolvers, which in turn load another set of their dependencies.</p>

<p>This extension has to be instantiated every single time Twig is used, even though it’s not needed.</p>

<p>So instead of:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CheckoutStepsExtension</span> <span class="k">extends</span> <span class="err">\</span><span class="n">Twig_Extension</span>
<span class="p">{</span>
    <span class="k">private</span> <span class="nv">$checkoutStepsHelper</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">CheckoutStepsHelper</span> <span class="nv">$checkoutStepsHelper</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">checkoutStepsHelper</span> <span class="o">=</span> <span class="nv">$checkoutStepsHelper</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">getFunctions</span><span class="p">():</span> <span class="kt">array</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="p">[</span>
            <span class="k">new</span> <span class="err">\</span><span class="nf">Twig_Function</span><span class="p">(</span><span class="s1">'sylius_is_shipping_required'</span><span class="p">,</span> <span class="p">[</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">checkoutStepsHelper</span><span class="p">,</span> <span class="s1">'isShippingRequired'</span><span class="p">]),</span>
            <span class="k">new</span> <span class="err">\</span><span class="nf">Twig_Function</span><span class="p">(</span><span class="s1">'sylius_is_payment_required'</span><span class="p">,</span> <span class="p">[</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">checkoutStepsHelper</span><span class="p">,</span> <span class="s1">'isPaymentRequired'</span><span class="p">]),</span>
        <span class="p">];</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>we could move dependencies from the extension to a Twig Runtime:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CheckoutStepsExtension</span> <span class="k">extends</span> <span class="err">\</span><span class="n">Twig_Extension</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">getFunctions</span><span class="p">():</span> <span class="kt">array</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="p">[</span>
            <span class="k">new</span> <span class="err">\</span><span class="nf">Twig_Function</span><span class="p">(</span><span class="s1">'sylius_is_shipping_required'</span><span class="p">,</span> <span class="p">[</span><span class="nc">CheckoutStepsHelperRuntime</span><span class="o">::</span><span class="n">class</span><span class="p">,</span> <span class="s1">'isShippingRequired'</span><span class="p">]),</span>
            <span class="k">new</span> <span class="err">\</span><span class="nf">Twig_Function</span><span class="p">(</span><span class="s1">'sylius_is_payment_required'</span><span class="p">,</span> <span class="p">[</span><span class="nc">CheckoutStepsHelperRuntime</span><span class="o">::</span><span class="n">class</span><span class="p">,</span> <span class="s1">'isPaymentRequired'</span><span class="p">]),</span>
        <span class="p">];</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>and the Runtime proxy:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CheckoutStepsHelperRuntime</span> <span class="kd">implements</span> <span class="nc">RuntimeExtensionInterface</span>
<span class="p">{</span>
    <span class="k">private</span> <span class="nv">$checkoutStepsHelper</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">CheckoutStepsHelper</span> <span class="nv">$checkoutStepsHelper</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">checkoutStepsHelper</span> <span class="o">=</span> <span class="nv">$checkoutStepsHelper</span><span class="p">;</span>
    <span class="p">}</span>
    
    <span class="k">public</span> <span class="k">function</span> <span class="n">isShippingRequired</span><span class="p">(</span><span class="kt">OrderInterface</span> <span class="nv">$order</span><span class="p">):</span> <span class="kt">bool</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">checkoutStepsHelper</span><span class="o">-&gt;</span><span class="nf">isShippingRequired</span><span class="p">(</span><span class="nv">$order</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">isPaymentRequired</span><span class="p">(</span><span class="kt">OrderInterface</span> <span class="nv">$order</span><span class="p">):</span> <span class="kt">bool</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">checkoutStepsHelper</span><span class="o">-&gt;</span><span class="nf">isPaymentRequired</span><span class="p">(</span><span class="nv">$order</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">RuntimeExtensionInterface</code> interface is just for convenience. It enables Symfony DI’s autoconfiguration feature
to tag the class with the <code class="language-plaintext highlighter-rouge">twig.runtime</code> tag.</p>

<p>Last, but not least I hope, remember to test your Twig extensions. In the <a href="/unit-testing-lazy-twig-extensions/">next post</a>
I’ll show you how to do that properly.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Lazy Twig extensions were introduced in Twig 1.35 / 2.4.4, albeit there’re still see so many Symfony apps that don’t use them.]]></summary></entry><entry><title type="html">How to enable Twig template autocompletion with Symfony integration plugin in phpStorm</title><link href="http://dotcom.software/phpstorm-symfony-plugin-twig-template-autocompletion/" rel="alternate" type="text/html" title="How to enable Twig template autocompletion with Symfony integration plugin in phpStorm" /><published>2018-11-01T00:00:00+00:00</published><updated>2018-11-01T00:00:00+00:00</updated><id>http://dotcom.software/phpstorm-symfony-plugin-twig-template-autocompletion</id><content type="html" xml:base="http://dotcom.software/phpstorm-symfony-plugin-twig-template-autocompletion/"><![CDATA[<p>The plugin currently is lacking support for the new Symfony’s directory structure 
since we keep Twig files in the <code class="language-plaintext highlighter-rouge">templates/</code> directory.</p>

<p>The workaround is very simple, one just has to add the missing directory to the list of known Twig paths:</p>

<p><img src="/images/2018-11-01-phpstorm-symfony-plugin-twig-template-autocompletion.jpg" alt="Adding Twig path" /></p>

<p>That’s all, enjoy:</p>

<p><img src="/images/posts/2018-11-01-phpstorm-symfony-plugin-twig-template-autocompletion-2.jpg" alt="Adding Twig path" /></p>]]></content><author><name></name></author><summary type="html"><![CDATA[The plugin currently is lacking support for the new Symfony’s directory structure since we keep Twig files in the templates/ directory.]]></summary></entry><entry><title type="html">How to configure Symfony 4 Doctrine XML mapping</title><link href="http://dotcom.software/doctrine-xml-configuration/" rel="alternate" type="text/html" title="How to configure Symfony 4 Doctrine XML mapping" /><published>2018-10-24T00:00:00+00:00</published><updated>2018-10-24T00:00:00+00:00</updated><id>http://dotcom.software/doctrine-xml-configuration</id><content type="html" xml:base="http://dotcom.software/doctrine-xml-configuration/"><![CDATA[<p>I’ve attempted to answer this question lately on <a href="https://stackoverflow.com/questions/52962708/symfony-4-how-to-implement-doctrine-xml-orm-mapping/52963004#52963004">StackOverflow</a>. Astoundingly, the documentation is scarce about this.</p>

<p>Imagine <code class="language-plaintext highlighter-rouge">YourDomain\Customer\Customer</code> domain object:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;?php declare(strict_types=1);

namespace YourDomain\Customer;

class Customer
{
    private $id;
    private $email;
    private $password;

    public function __construct(string $email)
    {
        $this-&gt;setEmail($email);
    }

    public function getId(): ?int
    {
        return $this-&gt;id;
    }

    public function getEmail(): string
    {
        return $this-&gt;email;
    }

    public function setEmail(string $email): void
    {
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new \InvalidArgumentException('Not a valid e-mail address');
        }

        $this-&gt;email = $email;
    }

    public function getPassword(): string
    {
        return (string)$this-&gt;password;
    }

    public function setPassword(string $password): void
    {
        $this-&gt;password = $password;
    }
}
</code></pre></div></div>

<p>Define your own mapping first:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>orm:
  mappings:
    YourDomain\Customer:
      is_bundle: false
      type: xml
      // this is the location where xml files are located, mutatis mutandis
      dir: '%kernel.project_dir%/../src/Infrastructure/ORM/Mapping'
      prefix: 'YourDomain\Customer'
      alias: Customer
</code></pre></div></div>

<p>File name has to match the pattern <code class="language-plaintext highlighter-rouge">[class_name].orm.xml</code>, in your case <code class="language-plaintext highlighter-rouge">Customer.orm.xml</code>. If you have sub-namespaces inside, eg. value object <code class="language-plaintext highlighter-rouge">YourDomain\Customer\ValueObject\Email</code>, the file has to be named <code class="language-plaintext highlighter-rouge">ValueObject.Email.orm.xml</code>.</p>

<p>Example mapping:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
                   https://raw.github.com/doctrine/doctrine2/master/doctrine-mapping.xsd"&gt;
    &lt;entity name="YourDomain\Customer\Customer" table="customer"&gt;
        &lt;id name="id" type="integer" column="id"&gt;
            &lt;generator strategy="AUTO"/&gt;
        &lt;/id&gt;
        &lt;field name="email" type="email" unique="true"/&gt;
        &lt;field name="password" length="72"/&gt;
    &lt;/entity&gt;
&lt;/doctrine-mapping&gt;
</code></pre></div></div>]]></content><author><name></name></author><summary type="html"><![CDATA[I’ve attempted to answer this question lately on StackOverflow. Astoundingly, the documentation is scarce about this.]]></summary></entry><entry><title type="html">Conditional Xdebug breakpoints in phpStorm</title><link href="http://dotcom.software/conditional-xdebug-breakpoints-in-phpstorm/" rel="alternate" type="text/html" title="Conditional Xdebug breakpoints in phpStorm" /><published>2018-07-06T00:00:00+00:00</published><updated>2018-07-06T00:00:00+00:00</updated><id>http://dotcom.software/conditional-xdebug-breakpoints-in-phpstorm</id><content type="html" xml:base="http://dotcom.software/conditional-xdebug-breakpoints-in-phpstorm/"><![CDATA[<p>How many times did you modify that big loop of yours just to make phpStorm enter a debugging session in the right place at the right time?</p>

<p>Well, that times are over now, thanks to phpStorm and its <a href="https://www.jetbrains.com/help/phpstorm/configuring-breakpoints.html">conditional breakpoints</a>! Why didn’t I know that fancy functionality exists? I feel really pity for myself.</p>

<p>Just add a breakpoint, right click on it and add your condition. And yes, those are pure PHP conditions, go bananas!</p>

<p><img src="/images/2018-07-06-conditional-debugger-breakpoints-in-phpstorm.md.png" alt="Creating a conditional breakpoint" /></p>

<p>Run your code and let the magic happen.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[How many times did you modify that big loop of yours just to make phpStorm enter a debugging session in the right place at the right time?]]></summary></entry><entry><title type="html">Generate UUID v6 in PHP</title><link href="http://dotcom.software/generate-uuid-v6-with-php/" rel="alternate" type="text/html" title="Generate UUID v6 in PHP" /><published>2018-05-16T00:00:00+00:00</published><updated>2018-05-16T00:00:00+00:00</updated><id>http://dotcom.software/generate-uuid-v6-with-php</id><content type="html" xml:base="http://dotcom.software/generate-uuid-v6-with-php/"><![CDATA[<p>The <a href="https://tools.ietf.org/html/rfc4122">RFC 4122</a> describes five versions of UUID,
but none of them is optimized to be used as a primary key in a relational database
we are so fond of.</p>

<p>Brad Peabody <a href="https://bradleypeabody.github.io/uuidv6/">proposed Version 6</a>:</p>

<blockquote>
  <p>TL;DR: ‘Version 6’ UUIDs have the date/time encoded from high to low bytes
(bit-shifting around the version field in order to preserve its location) 
and thus sort correctly by time when treated as an opaque bunch of bytes; 
the clock sequence can be used to avoid duplicates generated at the same time; 
it’s okay to use random data from a good PRNG in place of the MAC address; 
the rest is the same as RFC 4122.</p>
</blockquote>

<p>Pity I didn’t found any PHP implementation, needed to write one myself. 
Go and grab it from Packagist as <a href="https://packagist.org/packages/mikemix/php-uuid-v6">mikemix/php-uuid-v6</a>.
Hope it helps someone!</p>

<p>Hopefully this proposal will make its way through the IETF process some day! 
<a href="https://github.com/ramsey">Ben Ramsey</a> already <a href="https://github.com/ramsey/uuid/issues/228">pledged his help</a>.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[The RFC 4122 describes five versions of UUID, but none of them is optimized to be used as a primary key in a relational database we are so fond of.]]></summary></entry><entry><title type="html">Dockerized MySQL hot backup tool with Percona Xtrabackup</title><link href="http://dotcom.software/dockerized-mysql-hot-backup-with-percona-xtrabackup/" rel="alternate" type="text/html" title="Dockerized MySQL hot backup tool with Percona Xtrabackup" /><published>2018-01-19T00:00:00+00:00</published><updated>2018-01-19T00:00:00+00:00</updated><id>http://dotcom.software/dockerized-mysql-hot-backup-with-percona-xtrabackup</id><content type="html" xml:base="http://dotcom.software/dockerized-mysql-hot-backup-with-percona-xtrabackup/"><![CDATA[<p>Just created a dockerized tool that wraps Percona Xtrabackup binary and 
periodically does a hot backup of your MySQL/MariaDB database. I already use it on production 
and it works like a charm! Feel free to use and/or contribute. Licensed under MIT so anyone can use.</p>

<p><a href="https://hub.docker.com/r/mikemix/percona-xtrabackup/">Docker image</a> /
<a href="https://github.com/mikemix/percona-xtrabackup-cron">GitHub repository</a></p>

<p>Just mount your cloud bucket to the filesystem, one docker command to run the tool
and don’t worry about your database anymore.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Just created a dockerized tool that wraps Percona Xtrabackup binary and periodically does a hot backup of your MySQL/MariaDB database. I already use it on production and it works like a charm! Feel free to use and/or contribute. Licensed under MIT so anyone can use.]]></summary></entry><entry><title type="html">Conway’s Game of Life implementation in PHP</title><link href="http://dotcom.software/programming-can-be-fun/" rel="alternate" type="text/html" title="Conway’s Game of Life implementation in PHP" /><published>2017-08-29T00:00:00+00:00</published><updated>2017-08-29T00:00:00+00:00</updated><id>http://dotcom.software/programming-can-be-fun</id><content type="html" xml:base="http://dotcom.software/programming-can-be-fun/"><![CDATA[<p>It’s really enjoyable sometimes to lay your daily activities and do anything fun topic. I managed to find some spare time recently so I got my hands on <a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Conway’s Game of Life</a> topic and did a simple implementation in PHP7.</p>

<p>It’s a simple algorithm, just 3 rules honestly, developed by <a href="https://en.wikipedia.org/wiki/John_Horton_Conway">John Conway</a> almost 40 years ago now. I’m not going to cover the topic thoroughly here though.</p>

<p>The results can be found at <a href="https://github.com/mikemix/game-of-life">GitHub</a>. Should you have Docker installed, the whole can be run with just one command.</p>

<p>I’m going to develop this from time to time for sure. I really hope that :)</p>]]></content><author><name></name></author><summary type="html"><![CDATA[It’s really enjoyable sometimes to lay your daily activities and do anything fun topic. I managed to find some spare time recently so I got my hands on Conway’s Game of Life topic and did a simple implementation in PHP7.]]></summary></entry></feed>