<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Christian Mayer&apos;s Weblog</title>
		<description></description>
		<link>https://blog.fox21.at/</link>
		<atom:link href="https://blog.fox21.at/feed.xml" rel="self" type="application/rss+xml" />
		<managingEditor>christian@fox21.at (Christian Mayer)</managingEditor>
		
			<item>
				<title>Rust Alternatives</title>
				<description><![CDATA[<p>However, this same feature can pose challenges for beginners. Rust is definitely not the most suitable programming language for those just starting their coding journey. As a beginner I want to have fast results, not a compiler telling me what I am doing wrong. Its syntax can be particularly complex, especially when it involves <a href="https://doc.rust-lang.org/rust-by-example/scope/lifetime.html">lifetime annotations</a>. So, there must be a good alternative to Rust.</p>

<p>Recently, I asked a question about this on <a href="https://mastodon.social/@TheFox21/114081657999520621">Mastodon</a>:</p>

<blockquote>
  <p>Can I have a #programming language/compiler similar to #Rust, but with less syntactic complexity? Preferably a syntax more like #Python or #PHP.</p>
</blockquote>

<p>In my exploration of other programming languages, I focused on a few key criteria for comparison:</p>

<ul>
  <li>Simple syntax.</li>
  <li>The language must be compilable to binary and not primarily a scripting language.</li>
  <li>It should produce small binaries.</li>
  <li>An active and functional ecosystem, including a package manager, is essential.</li>
</ul>

<h2 id="zig">Zig</h2>

<p>Website: <a href="https://ziglang.org/">https://ziglang.org/</a></p>

<p>Influenced by C, C++, LLVM IR, Go, Rust. [<a href="https://en.wikipedia.org/wiki/Zig_(programming_language)">1</a>] Syntax looks nice and intuitive. The installation on macOS using <a href="https://brew.sh/">Homebrew</a> was as simple as running <code class="language-plaintext highlighter-rouge">brew install zig</code> and then compiling using <code class="language-plaintext highlighter-rouge">zig build-exe test1.zig</code>.</p>

<p>Hello world example:</p>

<div class="language-zig highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">const</span> <span class="n">std</span> <span class="o">=</span> <span class="nb">@import</span><span class="p">(</span><span class="s">"std"</span><span class="p">);</span>
<span class="k">pub</span> <span class="k">fn</span> <span class="n">main</span><span class="p">()</span> <span class="o">!</span><span class="k">void</span> <span class="p">{</span>
    <span class="n">std</span><span class="p">.</span><span class="py">debug</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">"Hello world</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="o">.</span><span class="p">{});</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The binary file is ~873 KB for Zig v0.13.0 under mac OS Ventura 13.6.4. Stripped binary is ~716 KB. On a modern PC this is OK-ish.</p>

<p>Update 2025-03-09: I also ran the same Hello World example using Zig v0.14.0 with different build modes,<br />
<code class="language-plaintext highlighter-rouge">zig build-exe -O Debug -femit-bin=./test1_Debug test1.zig</code>:</p>

<p>original Debug: ~1.1 MB<br />
original ReleaseFast: ~18 KB<br />
original ReleaseSafe: ~267 KB<br />
original ReleaseSmall: 17230 byte</p>

<p>stripped Debug: ~911 KB<br />
stripped ReleaseFast: ~17 KB<br />
stripped ReleaseSafe: ~229 KB<br />
stripped ReleaseSmall: 16608 byte</p>

<p>Thanks <a href="https://hachyderm.io/@levin">@Levin</a> for the hint: <a href="https://hachyderm.io/@levin/114132072733027611">https://hachyderm.io/@levin/114132072733027611</a></p>

<h2 id="crystal">Crystal</h2>

<p>Website: <a href="https://crystal-lang.org/">https://crystal-lang.org/</a></p>

<p>Syntax is also influenced by Go. [<a href="https://en.wikipedia.org/wiki/Crystal_(programming_language)">2</a>] The installation on macOS using Homebrew was as simple as running <code class="language-plaintext highlighter-rouge">brew install crystal</code> and then compiling using <code class="language-plaintext highlighter-rouge">crystal build test1.cr</code>.</p>

<p>Hello world example as simple as Ruby:</p>

<div class="language-crystal highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">puts</span> <span class="s2">"Hello world"</span>
</code></pre></div></div>

<p>The binary is ~1.7 MB for Crystal 1.15.1 under mac OS Ventura 13.6.4. This is huge. ~873 KB stripped, still huge.</p>

<h2 id="go">Go</h2>

<p>Website: <a href="https://go.dev/">https://go.dev/</a></p>

<p>Syntax is also influenced by many. [<a href="https://en.wikipedia.org/wiki/Go_(programming_language)">3</a>] The installation on macOS using Homebrew was as simple as running <code class="language-plaintext highlighter-rouge">brew install golang</code> and then compiling using <code class="language-plaintext highlighter-rouge">go build test1.go</code>.</p>

<p>Hello world example [<a href="https://gobyexample.com/hello-world">4</a>]:</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">package</span> <span class="n">main</span>
<span class="k">import</span> <span class="s">"fmt"</span>
<span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"hello world"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The binary is ~2.3 MB for Go  under mac OS Ventura 13.6.4. ~1.5 MB stripped. This is huge.</p>

<h2 id="conclusion">Conclusion</h2>

<p>In my exploration of various programming languages, I’ve discovered that Zig has become my current favorite alternative to Rust. Despite Zig currently lacking an ecosystem and package manager, it captivates me with its features.</p>
]]></description>
				<pubDate>Sun, 09 Mar 2025 00:00:00 +0100</pubDate>
				<link>https://blog.fox21.at/2025/03/09/rust-alternatives.html</link>
				<guid isPermaLink="true">https://blog.fox21.at/2025/03/09/rust-alternatives.html</guid>
			</item>
		
			<item>
				<title>Mastodon</title>
				<description><![CDATA[<p>I’ve recently become active on social media again. From around 2009 to 2018, I was actively using <a href="https://x.com/">Twitter</a> (now X), years before <a href="https://en.wikipedia.org/wiki/Elon_Musk">Elon Musk</a> took over. Many people, including myself, left Twitter and switched to Mastodon. Since 2019, I have not been active on Twitter. However, about a week ago, I started using Mastodon actively. I created an account in 2023 but wasn’t active at first. Now, I’m really enjoying the platform — it reminds me of the early days of Twitter. I even created two <a href="https://news.ycombinator.com/">Hacker News</a> bots, which uses <a href="https://openai.com/">OpenAI</a> to (a) generate the hashtags and (b) creating posts in the n-gate.com style. See <a href="https://mastodon.social/@h4ckernews">@h4ckernews</a> and <a href="https://mastodon.social/@ngate">@ngate</a> on Mastodon.</p>

<p>With the introduction of the Web 2.0 Twitter interface, my disinterest grew until I eventually abandoned Twitter altogether.</p>

<p>The following is a screenshot I took in the early days of Twitter:</p>

<p><img src="https://img.fox21.at/twitter/twitter_20100915_small.jpg" alt="Twitter 2010" title="Twitter 2010" /></p>
]]></description>
				<pubDate>Sat, 01 Mar 2025 00:00:00 +0100</pubDate>
				<link>https://blog.fox21.at/2025/03/01/mastodon.html</link>
				<guid isPermaLink="true">https://blog.fox21.at/2025/03/01/mastodon.html</guid>
			</item>
		
			<item>
				<title>Project Outlines</title>
				<description><![CDATA[<p>Most of my <a href="https://github.com/TheFox">GitHub projects</a> now have a <em>Project Outlines</em> section in the README file. Not detailed. At least a minimal version, while with time a detailed picture of the outlines will follow for each project.</p>

<p>With <em>outlines</em> I mean which features and functions a project can have. The main purpose of a software. The initial idea why a project was born at all. A list of needed features and features a software project will never cover. What will this software do and don’t. Which problems does it solve and which will never be solved by using it.</p>

<p>This will help users, collaborators and me not to lose the red line for each project’s overall functionality, or not. For some projects the red line will come with time and users. For some other projects it’s clear from the beginning. For example, take my <a href="https://github.com/TheFox/keylogger/blob/255d0e8014fa74c4bc19e13fc281e06456f5d142/README.md#keylogger">Keylogger</a> project. It’s very clear that this will never be anything but a keylogger.</p>

<p>For other projects it’s blurry where to draw the line between feature or not. Maybe it will never be clear. Often a project has to exist several months or even years to become aware of its outlines. This is normal for software.</p>

<p>As soon as I’m aware of outlines for a project I’ll update the list in the README file. I’ll add more outlines to each project while working on it.</p>
]]></description>
				<pubDate>Sun, 07 Apr 2019 00:00:00 +0200</pubDate>
				<link>https://blog.fox21.at/2019/04/07/project-outlines.html</link>
				<guid isPermaLink="true">https://blog.fox21.at/2019/04/07/project-outlines.html</guid>
			</item>
		
			<item>
				<title>CraftCMS Rant</title>
				<description><![CDATA[<p>Popular software does not always has to be well-written. Maybe that’s exactly why a software project is successful at the first place, because programmers do not only focus on well-written code, but rather getting stuff done. As a programmer who works for a company which has time pressure, I understand that. Focusing more on getting features done, even if this means the software has bugs. A common practice in the software industry. The client wants to see results. Project managers pushing developers to have something to show in their next project meeting.</p>

<p>Software written under time pressure is often bad. But you cannot always skip the thinking process. You <strong>have</strong> to think longer and spend time on solutions. Even under time pressure.</p>

<p>CraftCMS is a perfect solution for frontend developers. They do not have to deal with PHP code. Only creating <a href="https://twig.symfony.com/">Twig</a> templates and using existing Craft functionality to query data out of the database. This is fine as long as you don’t have any special cases.</p>

<p>It’s getting dirty when you want to extend the system and write own PHP code. My request to get more documentation for the PHP backend provided has been rejected several times. [<a href="https://github.com/craftcms/commerce/issues/582">1</a>][<a href="https://github.com/craftcms/cms/issues/3523">2</a>] As you can see in <a href="https://github.com/craftcms/commerce/issues/621">GitHub Issue #621</a>, I got forwarded to some core source code instead of a proper backend documentation. When I have a problem to solve, random code from the core does not help me. I don’t know which parts of the shown code are relevant for me. I would like to have better tutorials and best practice documentations for how to solve specific PHP problems. I would not expect to get forwarded to some random position in the PHP core of CraftCMS.</p>

<h3 id="caching">Caching</h3>

<p>It’s mixed how CraftCMS uses caches. The usage of caching techniques differ from one end of the system to the other. At some points CraftCMS forces you to call a refresh function. Like when you want to get the new inserted field it forces you to call <code class="language-plaintext highlighter-rouge">Craft::$app-&gt;getFields()-&gt;refreshFields()</code> [<a href="https://github.com/craftcms/cms/blob/a9867818a34607fa55a440c2a12f6703f7e7a011/src/services/Fields.php#L953">3</a>] first.</p>

<p>At some other points it does not use any caching at all. There is one good example how you should not do it. Let’s dig into <code class="language-plaintext highlighter-rouge">Sections::getSectionByHandle()</code> [<a href="https://github.com/craftcms/cms/blob/a9867818a34607fa55a440c2a12f6703f7e7a011/src/services/Sections.php#L315">4</a>].</p>

<p>What does it do? On the very first call it gets all sections from the database by calling <code class="language-plaintext highlighter-rouge">$this-&gt;getAllSections()</code> [<a href="https://github.com/craftcms/cms/blob/a9867818a34607fa55a440c2a12f6703f7e7a011/src/services/Sections.php#L161">5</a>]. All the sections will be forwarded to a common array helper function called <code class="language-plaintext highlighter-rouge">ArrayHelper::firstWhere()</code> [<a href="https://github.com/craftcms/cms/blob/a9867818a34607fa55a440c2a12f6703f7e7a011/src/helpers/ArrayHelper.php#L102">6</a>]. Then this helper function goes through all rows and uses its arguments to find the desired row. It does this for every request. So, every time you press Reload in your browser, CraftCMS is going to fetch all rows from the table. Unlimited. Imagine the table has thousands of rows, going (in the worst case) through the whole table causes unnecessary PHP workload, and unnecessary traffic between the database and PHP. Instead a real database query using a <code class="language-plaintext highlighter-rouge">WHERE</code> clause should be used.</p>

<p>In fact the <code class="language-plaintext highlighter-rouge">getAllSections()</code> function uses a caching variable, but it is useless since every new request will cause PHP to fetch again all rows from the table.</p>

<p>Beside using <code class="language-plaintext highlighter-rouge">ArrayHelper::firstWhere()</code> is a bad idea, it’s also faulty by design. Have a look at <a href="https://github.com/craftcms/cms/blob/a9867818a34607fa55a440c2a12f6703f7e7a011/src/helpers/ArrayHelper.php#L112">the function arguments</a>. There is one boolean argument named <code class="language-plaintext highlighter-rouge">$strict</code>. It’s bad design to use one argument to change the behaviour of a function. Instead using a second function named <code class="language-plaintext highlighter-rouge">ArrayHelper::strictFirstWhere()</code> would be better design. But anyway, the whole idea of first fetching the whole table and then filtering it in PHP should be considered as bad.</p>

<p>This is only my opinion. I asked <a href="https://www.reddit.com/r/PHPhelp/comments/auwdsn/caching_techniques/">Reddit</a> and <a href="https://stackoverflow.com/questions/54881704/two-php-caching-techniques">Stack Overflow</a> about this topic in an abstract way. The answers vary from one platform to the other. You should read them and form your own opinion about it.</p>

<h3 id="installation">Installation</h3>

<p>I have never done a CraftCMS installation on the first try. It never worked on the first try. Every time I install a new instance an error appears I never saw before. The setup script does not recognize existing variables from the <code class="language-plaintext highlighter-rouge">.env</code> file. Run the setup 10 times (for the same instance) and you have to provide the password and other variables 10 times. Further, do not forget to delete the <strong>entire</strong> database <strong>each time</strong> you restart the installation. This is a pain in the ass. Nothing else to say.</p>

<h3 id="project-config">Project Config</h3>

<p><a href="https://docs.craftcms.com/v3/project-config.html">Project Config</a> is one useless features of CraftCMS version 3.1. This feature is not designed to be used by many developers at a time. The background logic, how this feature is actually working, is not clear. The changes from the <code class="language-plaintext highlighter-rouge">project.yml</code> file are often not applied to the other environments. Even when changes are made in this file and the Modified Timestamp is updated. This caused us too many headaches.</p>

<p>You may first think that this will help you manage the fields in a better way. But when managing large sets of fields and settings and plugins <code class="language-plaintext highlighter-rouge">project.yml</code> becomes a nightmare.</p>

<p>Different values in different environments are required. This is the whole point of using environments. Not to override the same value on all environments, Craft introduced a feature to replace the value of a config field with an environment variable. For instance, instead of <code class="language-plaintext highlighter-rouge">subject: 'Hello World'</code> you can now use <code class="language-plaintext highlighter-rouge">subject: '$SUBJECT'</code>, where <code class="language-plaintext highlighter-rouge">$SUBJECT</code> comes from the <a href="/2018/11/17/parameters.html">.env file</a> or the shell environment. This will set the value of the environment variable <code class="language-plaintext highlighter-rouge">$SUBJECT</code> to the YAML <code class="language-plaintext highlighter-rouge">subject</code> variable. This is cool, it seems on the first glance. Or not so when using it in real world. Because now I would expect also <code class="language-plaintext highlighter-rouge">subject: 'TEST - $SUBJECT'</code> to work. It does not <a href="https://github.com/craftcms/cms/issues/3906">by intention</a>.</p>

<p>The Project Config concept is faulty by design. Instead of first changing something in the Control Panel and then commiting the <code class="language-plaintext highlighter-rouge">project.yml</code> file to Git, it should be, first editing the <code class="language-plaintext highlighter-rouge">project.yml</code> file in a text editor, then run the sync script and commit the file to Git. Without any <em>magic</em> in the background. Things I change in the Control Panel should never affect files. Since we use <a href="/2018/11/29/docker-network.html">Docker</a>, the next deployment will overwrite the changes. It’s one thing to achieve real good <em>magic</em> and another <strong>trying</strong> to make magic and failing like CraftCMS with Project Config.</p>

<p>Keep in mind that this is no replacement for Migrations. It only overrides existing values. Often it does not work how expected.</p>

<h3 id="craft-commerce">Craft Commerce</h3>

<p>The same company, Pixel &amp; Tonic, also produces an e-commerce solution call <a href="https://craftcms.com/commerce">Craft Commerce</a>.</p>

<p>The majority of the Craft users are not going to the edge. This is the <a href="https://en.wikipedia.org/wiki/Pareto_principle">80/20 rule</a>: 80% of the user using 20% of all features. We discovered <a href="https://github.com/craftcms/commerce/issues/621">a 1.5 year old bug</a> in Craft Commerce. No one ever used this feature or tested it in the moment of creating the code for it. Otherwise the developer would have seen that the table does not exist. This bug was only introduced because the Pixel &amp; Tonic developers are <a href="https://github.com/craftcms/commerce/issues/623#issuecomment-453409500">not willing to reuse functions</a>. On each position where table names are needed, they write the full table name instead of calling the function which returns the table name. They argue with <a href="https://github.com/craftcms/commerce/issues/623#issuecomment-453427632">performance reasons</a>. But the truth is that you should not use PHP to be performant. You should not care about performance when writing PHP code. You write PHP code because you don’t want to care about memory management and the other low-level stuff which is needed to be real performant.</p>

<p>A short background. CraftCMS uses the <a href="https://www.yiiframework.com/">Yii2 Framework</a> as a backbone. <a href="https://www.yiiframework.com/doc/guide/2.0/en/db-active-record">Active Records</a> will be used to fetch data from the database. Each Active Record has a static function <a href="https://www.yiiframework.com/doc/guide/2.0/en/db-active-record#setting-a-table-name">to get the database table name</a>.</p>

<p>Instead of using this static function for each extra position where the table name is needed, the CraftCMS code is designed to <strong>not</strong> reuse the <code class="language-plaintext highlighter-rouge">tableName()</code>. Why? This is against <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">Don’t Repeat Yourself</a> (DRY). Pixel &amp; Tonic is acting against Developer Best Practices.</p>

<p>The <a href="https://en.wikipedia.org/wiki/Unit_testing">unit tests</a> are not going to catch such kind of bug, because there are no unit tests at all. No unit tests for a system which deals with numbers and billing and invoices for end-users.</p>

<p>See an example of wrong numbers handling in <a href="https://github.com/craftcms/commerce/issues/695">GitHub Issue #695</a>. How can a big project like CraftCMS not have unit tests? It’s OK not having tests for <strong>all</strong> parts, but especially when dealing with numbers and money there is no excuse for not having unit tests.</p>

<h3 id="conclusion">Conclusion</h3>

<p>In the long-term it hurts projects when developers only focus on new features instead of fixing existing issues. The main focus should always be the core of the system. The core has to be clean and stable and high-performance. Otherwise it will lead to a critical point where huge parts have to be rewritten, with a fresh approach.</p>

<p>CraftCMS has too many open problems, too many features which are not well design enough. Pixel &amp; Tonic often use bad development practice that lead to immature code. This immaturity hurts the project and the trust of the clients in the long-term. Especially for a system like Craft Commerce, which deals with numbers and billing and invoices, by not spending time on quality.</p>

<p>At the company where I’m employed we already spend too much time fixing Pixel &amp; Tonic’s bugs. We often have to find workarounds for CraftCMS and Craft Commerce to not lose the trust our clients are giving us. I’m willing to accept that CraftCMS and Craft Commerce can get better. It’s a long way to go.</p>

<p>We wanted both to cry and laugh at the same time about this code.</p>
]]></description>
				<pubDate>Wed, 06 Mar 2019 00:00:00 +0100</pubDate>
				<link>https://blog.fox21.at/2019/03/06/craftcms.html</link>
				<guid isPermaLink="true">https://blog.fox21.at/2019/03/06/craftcms.html</guid>
			</item>
		
			<item>
				<title>Open Source Software Collaboration</title>
				<description><![CDATA[<p>Recently I got worried about the quality of <a href="https://github.com/TheFox">my open source projects</a>. Especially for the projects I got collaborators. For some of my open source projects on GitHub I accepted code from other people. But some of the code is not the standard I use.</p>

<p>I do not want to reject people on GitHub. When someone wants to collaborate on an open source project of mine I always feel special. The person maybe put a vast amount of time into a feature for a project I created on GitHub. So I cannot reject the code. Even if this makes the quality of a project bad?</p>

<p>What’s the most valuable thing someone has? It’s time. Even if someone had put a vast amount of time and energy into a new feature of my project, I’m (maybe) still in the position to reject a pull request. I never thought about this before, but maybe I should more often reject bad code for <a href="https://github.com/TheFox">my open source projects</a>. It’s not only the other persons time which gets wasted. It’s also my time. It’s my time get wasted if I randomly accept pull requests and I have to rewrite the accepted code at some later point in the lifetime of a project. It’s maybe bullshit code I should not have accepted in the first place. Saving time by rejecting bad quality code? Or saving everyones time by deactivating the Pull Request function on GitHub?</p>

<h3 id="outlines">Outlines</h3>

<p>Each project should have a clear outline of planned features. Which features to a project need? What’s planned for next versions? What will the project NEVER cover. If the README of each project covers the answers to these questions maybe new users and new collaborators have a better understanding of what could be a possible pull request.</p>

<p>A good example for outlines is my <a href="https://github.com/TheFox/keylogger">Keylogger</a> project on GitHub. This Keylogger will never be anything but a Keylogger. Because of this simple rule I rejected several feature requests. [<a href="https://github.com/TheFox/keylogger/issues/1">1</a>][<a href="https://github.com/TheFox/keylogger/issues/3">2</a>] Not all projects have a clear outline like that. For most of the projects even I don’t know what they could become in the future. Writing the outlines down in the README will help the users and me.</p>

<p>But it’s not only about the outlines of a project and its features. <strong>Most of the time I care about the code quality.</strong> It’s most important for all my projects. Rejecting code should happen more often in favor of the code quality. This will disappoint people, but it is also a good training for beginners. So rejecting code should not only be seen as bad. The requester should have a really good reason why he is not sticking to the project outlines.</p>

<h3 id="conclusion">Conclusion</h3>

<p>For future pull requests I will make a very detailed code review. The code quality has to be very good to fit my standards. Even if this means that someone may be mad at me, but this is only in favor of a project’s quality. Rather one is mad for some time, than more people are mad about the overall project quality. I’m not perfect, so maybe your standards will not fit my standards.</p>

<p>Further, I will define outlines for each project in the README file. This will help users and collaborators and me.</p>
]]></description>
				<pubDate>Thu, 21 Feb 2019 00:00:00 +0100</pubDate>
				<link>https://blog.fox21.at/2019/02/21/open-source-software-collaboration.html</link>
				<guid isPermaLink="true">https://blog.fox21.at/2019/02/21/open-source-software-collaboration.html</guid>
			</item>
		
			<item>
				<title>2018 Year in Review</title>
				<description><![CDATA[<h3 id="projects-which-i-founded-this-year">Projects which I founded this year</h3>

<ul>
  <li><a href="https://github.com/TheFox/parameters">Parameters</a></li>
  <li><a href="https://github.com/TheFox/wallet-cpp">WalletCpp</a></li>
  <li><a href="https://github.com/TheFox/nagios-plugins">Nagios Plugins</a></li>
  <li>And 5 other projects that are not listed public.</li>
</ul>

<h3 id="projects-which-i-continued-this-year">Projects which I continued this year</h3>

<ul>
  <li><a href="https://fox21.at/">fox21.at</a> and <a href="https://blog.fox21.at/">Blog</a></li>
  <li><a href="https://github.com/TheFox/flickr-cli">Flickr CLI</a></li>
  <li><a href="https://github.com/TheFox/i8086emu">Intel 8086 CPU Emulator</a></li>
  <li><a href="https://github.com/TheFox/imapd">IMAPd</a></li>
  <li><a href="https://github.com/TheFox/smtpd">SMTPd</a></li>
  <li><a href="https://github.com/TheFox/network">PHP Network Library</a></li>
  <li><a href="https://github.com/TheFox/utilities">PHP Utilities</a></li>
  <li><a href="https://github.com/TheFox/osp">One Shall Pass for Command-line</a></li>
  <li><a href="https://github.com/TheFox/persons">Persons</a></li>
  <li><a href="https://github.com/TheFox/wallet">Wallet</a></li>
  <li>And one project that is not listed public.</li>
</ul>

<h3 id="notable-events">Notable Events</h3>

<ul>
  <li>I contributed to 11 different <a href="http://www.digitalsunray.com/">Digitalsunray</a> projects.</li>
  <li>I started <a href="/2018/11/02/cpp-smart-pointers.html">learning C++ again</a>.</li>
  <li><a href="https://github.com/TheFox/osp">One Shall Pass for Command-line</a> will not be continued.</li>
</ul>
]]></description>
				<pubDate>Mon, 31 Dec 2018 00:00:00 +0100</pubDate>
				<link>https://blog.fox21.at/2018/12/31/2018-year-in-review.html</link>
				<guid isPermaLink="true">https://blog.fox21.at/2018/12/31/2018-year-in-review.html</guid>
			</item>
		
			<item>
				<title>Docker Network</title>
				<description><![CDATA[<p>I’m using <a href="https://www.docker.com/">Docker</a> since around Oktober 2017. Since I started using it I’m constantly searching for a way to get access to the host via the host’s IP address.</p>

<p>I want a solution without any dependencies. This means using as less as possible extra software. The goal is not to rely on tools or scripts other than Docker.</p>

<p>It doesn’t matter what you do with <a href="https://docs.docker.com/network/">Docker Network</a>, it’s always a mess.</p>

<p>For a better understanding, I also use <em>Host</em> as a synonym for the host machine, where the Docker daemon is running. And <em>Container</em> for what’s running inside Docker.</p>

<h3 id="host-lan-ip-address">Host LAN IP address</h3>

<p>This would be the easiest way to access the host: using the host’s LAN IP address inside the container. But I would not use it as the host’s IP address may be assigned dynamically. This is perfect for test cases, but not acceptable as a long-term solution or production.</p>

<p>Also on root-servers with static IP addresses this solution is not very reliable. Consider moving the container to another host machine. You don’t want to change the IP address on multiple locations.</p>

<h3 id="host-loopback-interface-alias">Host Loopback Interface Alias</h3>

<p>The loopback interface is also sometimes called localhost, or <code class="language-plaintext highlighter-rouge">127.0.0.1</code>.</p>

<p>You can set an alias on the host’s loopback interface. Then using this alias IP address inside the container to access the host. You cannot use <code class="language-plaintext highlighter-rouge">127.0.0.1</code> inside the container. This would point inside the container.</p>

<p>Using an alias works well. The problem is when you are working in a team. Every developer has to setup the exact same alias. On each working machine.</p>

<p>To set <code class="language-plaintext highlighter-rouge">10.254.254.254</code> as an alias under macOS use the following command:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo ifconfig lo0 alias 10.254.254.254
</code></pre></div></div>

<h3 id="create-your-own-hostname">Create your own hostname</h3>

<p>Creating your own hostname and using it through all projects is one of the best solutions. Especially when the container has to access the host machine, go for this. Like all other solutions, it requires work to do on the host machine. I would rather do nothing at all on the host system, but sadly, this is how Docker is designed. You have to adapt and prepare stuff on the host system. In most use cases it’s normal to prepare the host as well.</p>

<p>Even more work, when you have different host systems running. But let’s focus only on Debian Linux. The following shell commands have to be executed <em>before</em> the image will be started. So, creating a separate <code class="language-plaintext highlighter-rouge">run_docker.sh</code> script here, to prepare everthing, is a good decision.</p>

<p>This command returns the default network interface of the host system.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>route <span class="nt">-4</span> | <span class="nb">awk</span> <span class="s1">'/^default/ { print $8 }'</span>
</code></pre></div></div>

<p>Or more advanced for Bash scripts:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">default_if</span><span class="o">=</span><span class="si">$(</span>route <span class="nt">-4</span> | <span class="nb">awk</span> <span class="s1">'/^default/ { print $8 }'</span><span class="si">)</span>
</code></pre></div></div>

<p>Next, get the IP address for the default network interface.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">host_ip</span><span class="o">=</span><span class="si">$(</span>ifconfig <span class="s2">"</span><span class="k">${</span><span class="nv">default_if</span><span class="k">}</span><span class="s2">"</span> | <span class="nb">awk</span> <span class="s1">'/inet / { print $2 }'</span> | <span class="nb">head</span> <span class="nt">-1</span><span class="si">)</span>
</code></pre></div></div>

<p>When starting the image, use <code class="language-plaintext highlighter-rouge">$host_ip</code> to set <code class="language-plaintext highlighter-rouge">host.docker.local</code>. This will add a new entry to <code class="language-plaintext highlighter-rouge">/etc/hosts</code> inside the container.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run <span class="se">\</span>
    <span class="nt">--add-host</span><span class="o">=</span><span class="s2">"host.docker.local:</span><span class="nv">$host_ip</span><span class="s2">"</span> <span class="se">\</span>
    ...
</code></pre></div></div>

<p>You can use <code class="language-plaintext highlighter-rouge">host.docker.local</code> as a hardcoded hostname in configurations to access the host machine. Do not use <code class="language-plaintext highlighter-rouge">.localhost</code> as <a href="https://en.wikipedia.org/wiki/Top-level_domain">top-level domain</a> (TLD) here since some DNS servers have a <code class="language-plaintext highlighter-rouge">*.localhost</code> catch-all rule which resolves to <code class="language-plaintext highlighter-rouge">127.0.0.1</code>. Which is senseless in this case.</p>

<p>You are more independent when you already know forefront that the data on the host and the Docker container will always be on the same machine. Even if you move both together you don’t have to change anything in regarding of hostnames because <code class="language-plaintext highlighter-rouge">host.docker.local</code> will always point to the host machine.</p>

<h3 id="use-dns">Use DNS</h3>

<p>The most Docker container I’m working with have to access a MySQL database. The databases are <strong>always</strong> outside of Docker. And they <strong>never</strong> ever will. (It’s the worst idea ever, having a database inside Docker.)</p>

<p>When you have such a container it’s better to use DNS. Even if the database is on the same machine as the Docker container, I would not go with the previous (<em>Create your own hostname</em>) solution. Just add the hostname to your DNS server and use it in the configurations inside the container. For example, <code class="language-plaintext highlighter-rouge">db.your-company.tld</code> will do the job well. It’s more comfortable using a fixed DNS hostname when moving the container to another host machine. At least you have one thing less to change.</p>

<p>Don’t underestimate this. It’s still a shitload of work manually moving a container from one host to another. So being as host independent as possible should be always your intention.</p>

<h3 id="docker-for-mac">Docker for Mac</h3>

<p>From <a href="https://stackoverflow.com/a/45002996/">StackOverflow</a>:</p>

<blockquote>
  <p>On Docker for Mac, as of version 18.03, you can use <code class="language-plaintext highlighter-rouge">host.docker.internal</code> as the host’s IP. […] This is an update from <code class="language-plaintext highlighter-rouge">docker.for.mac.localhost</code>, available since version 17.06, and <code class="language-plaintext highlighter-rouge">docker.for.mac.host.internal</code>, available since version 17.12, which may also still work.</p>
</blockquote>

<p>This is actually very stupid. I want to use the same hostname regardless on which host system I run the container. This is the whole point of Docker, right? To be independent.</p>

<p>As I said above, you always have work to do on the host system. Let’s escalate a bit. I was introduced to Docker like <em>Build it once, run it everywhere</em>. Do not get fooled by that. This is delusional, since you <strong>always</strong> have to configure the host system somehow.</p>

<p>So, <code class="language-plaintext highlighter-rouge">docker.for.mac.localhost</code> is useless since in most cases you don’t have a Linux- or Mac-only environment in your company. It’s mixed. You have developers using Linux and Mac and Windows. This hostname makes no sense since in 99.99 % it’s a mixed Host OS environment. I don’t develop a container under macOS and deploy it to a macOS server. I deploy it to Linux. This is how everyone does. At least in my sphere. What’s even the whole point of <code class="language-plaintext highlighter-rouge">docker.for.mac.localhost</code>? Only a development utility? I cannot even use it on all dev machines. Don’t use it at all.</p>

<h3 id="conclusion">Conclusion</h3>

<p>The best solution would be to use an alias (like <code class="language-plaintext highlighter-rouge">host.docker.internal</code> as in <em>Docker for Mac</em>) provided by Docker as a build-in functionality, for all host systems. Regardless which host system the container is running on. Sadly, this is not a build-in feature of Docker. As long as Docker is not providing such a feature out-of-the-box we have to use our own solution to be host independent. You can see in the solutions above, it’s about which data you want to access from inside the container.</p>

<p>As I said before, being as host independent as possible should be always your intention when dealing with Docker.</p>
]]></description>
				<pubDate>Thu, 29 Nov 2018 00:00:00 +0100</pubDate>
				<link>https://blog.fox21.at/2018/11/29/docker-network.html</link>
				<guid isPermaLink="true">https://blog.fox21.at/2018/11/29/docker-network.html</guid>
			</item>
		
			<item>
				<title>Avoid Dynamic Data structures in PHP</title>
				<description><![CDATA[<p>In the PHP world it’s very common to use build-in arrays (<code class="language-plaintext highlighter-rouge">[]</code> or <code class="language-plaintext highlighter-rouge">array()</code>) for every purpose. It’s PHP’s <em>Swiss Army Knife</em>. But doesn’t look as nice as your wife.</p>

<p>Let’s jump into the code. Consider you have a very long and complex code block. For the purpose of this blog post I’ll make it only 2 levels deep:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">foreach</span> <span class="p">(</span><span class="cm">/* ... */</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">foreach</span> <span class="p">(</span><span class="cm">/* ... */</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Collect Data</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Outside of this block we have an array which collects some data from the inner loops for later use. Let’s concentrate only on the collecting block. Most PHP programmers would now do something like this:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$collection</span> <span class="o">=</span> <span class="p">[];</span> <span class="c1">// For later use.</span>
<span class="k">foreach</span> <span class="p">(</span><span class="cm">/* ... */</span><span class="p">)</span> <span class="p">{</span>
  <span class="nv">$widget</span> <span class="o">=</span> <span class="p">[];</span>
  <span class="k">foreach</span> <span class="p">(</span><span class="cm">/* ... */</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$widget</span> <span class="o">=</span> <span class="mf">...</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="nv">$collection</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$widget</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// Further use of $collection.</span>
</code></pre></div></div>

<p>I’ve seen and self written PHP code like this. It’s very easy to end up with a data structure like this:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$collection</span> <span class="o">=</span> <span class="p">[</span>
  <span class="p">[</span>
    <span class="s1">'order'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">int</span><span class="p">),</span>
    <span class="s1">'original'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">object</span><span class="p">),</span>
    <span class="s1">'info'</span> <span class="o">=&gt;</span> <span class="p">[</span>
      <span class="s1">'message'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">string</span><span class="p">),</span>
      <span class="s1">'created_at'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="nc">DateTime</span><span class="p">),</span>
      <span class="mf">...</span>
    <span class="p">],</span>
    <span class="mf">...</span>
  <span class="p">],</span>
  <span class="mf">...</span>
<span class="p">];</span>
</code></pre></div></div>

<p>This dynamic structure is bad. Later when you (or someone else) have to extend it, you are not sure anymore how the data structure looks like. You have to look up every write position to be sure what you are changing.</p>

<p>So better use Classes here. With Classes you cannot create a dynamically growing data structure. Your structure is fixed. But this approach is not every common in the PHP world. Everyone uses build-in arrays.</p>

<p>But in our example from above it’s better to use Classes. Instead of using a build-in array we now change it to objects.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Collection</span> <span class="p">{</span>
    <span class="cd">/** @var Widget[] */</span>
    <span class="k">private</span> <span class="nv">$widgets</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="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">widgets</span> <span class="o">=</span> <span class="p">[];</span>
    <span class="p">}</span>

    <span class="cd">/** @return Widget[] */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">getWidgets</span><span class="p">():</span> <span class="kt">array</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">widgets</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="cd">/** @param Widget[] $widgets */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">setWidgets</span><span class="p">(</span><span class="kt">array</span> <span class="nv">$widgets</span><span class="p">):</span> <span class="kt">void</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">widgets</span> <span class="o">=</span> <span class="nv">$widgets</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="cd">/** @param Widget $widget */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">addWidget</span><span class="p">(</span><span class="kt">Widget</span> <span class="nv">$widget</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">widgets</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$widget</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Ok, so now we still use an array for the widgets, but at least it’s wraped in a class. Be sure not to miss the initialization of the <code class="language-plaintext highlighter-rouge">$widgets</code> in the constructor. For arrays inside a class there is also an <code class="language-plaintext highlighter-rouge">add()</code> method needed. In this example it’s called <code class="language-plaintext highlighter-rouge">addWidget()</code>.</p>

<p>Next, create the Widget class:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Widget</span> <span class="p">{</span>
    <span class="cd">/** @var int */</span>
    <span class="k">private</span> <span class="nv">$order</span><span class="p">;</span>

    <span class="cd">/** @var SomeObject */</span>
    <span class="k">private</span> <span class="nv">$original</span><span class="p">;</span>

    <span class="cd">/** @var Info */</span>
    <span class="k">private</span> <span class="nv">$info</span><span class="p">;</span>

    <span class="c1">// More properties here.</span>
    <span class="mf">...</span>

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

    <span class="c1">// Getters and Setters here.</span>
    <span class="mf">...</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The same goes for the <code class="language-plaintext highlighter-rouge">info</code> field: create an <code class="language-plaintext highlighter-rouge">Info</code> class.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Info</span> <span class="p">{</span>
    <span class="cd">/** @var string */</span>
    <span class="k">private</span> <span class="nv">$message</span><span class="p">;</span>

    <span class="cd">/** @var \DateTime */</span>
    <span class="k">private</span> <span class="nv">$createdAt</span><span class="p">;</span>

    <span class="c1">// More properties here.</span>
    <span class="mf">...</span>

    <span class="c1">// Getters and Setters here.</span>
    <span class="mf">...</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Now we change our loop to use objects.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$collection</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Collection</span><span class="p">();</span>
<span class="k">foreach</span> <span class="p">(</span><span class="cm">/* ... */</span><span class="p">)</span> <span class="p">{</span>
  <span class="nv">$widget</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Widget</span><span class="p">();</span>
  <span class="k">foreach</span> <span class="p">(</span><span class="cm">/* ... */</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$widget</span><span class="o">-&gt;...</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="nv">$collection</span><span class="o">-&gt;</span><span class="nf">addWidget</span><span class="p">(</span><span class="nv">$widget</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="conclusion">Conclusion</h3>

<p>Instead of using a sub-array of an array we create a separate class. You will end up having more classes than usually. This is fine. Just make sure to use a separate namespace for the data classes. <code class="language-plaintext highlighter-rouge">\App\Data</code> would be good.</p>

<p>The examples in this post are an approach to use clean data structures in your PHP application. It aims to be easy maintainable, also for the long-run, by avoiding dynamic data structures. Sometimes you can only use build-in arrays, but when it’s possible to avoid them, you should.</p>

<p>Actually C++ inspired me for this. Since I’m doing <a href="/2018/11/02/cpp-smart-pointers.html">more</a> <a href="/2018/11/04/cpp-factory-class.html">C++</a> recently I got different views on PHP topics too. In C++ you don’t have something like a general-purpose array which can hold everything, randomly. You have to know forefront which data type you want to use. Using <em>new</em> programming languages will bring you new insights and ideas to already known languages. You get a better understanding.</p>
]]></description>
				<pubDate>Wed, 21 Nov 2018 00:00:00 +0100</pubDate>
				<link>https://blog.fox21.at/2018/11/21/avoid-dynamic-data-structures-in-php.html</link>
				<guid isPermaLink="true">https://blog.fox21.at/2018/11/21/avoid-dynamic-data-structures-in-php.html</guid>
			</item>
		
			<item>
				<title>Parameters</title>
				<description><![CDATA[<p>I am using <a href="https://symfony.com/4">Symfony 4</a> now for awhile. It’s a really cool <a href="https://en.wikipedia.org/wiki/Software_framework">webframework</a>. I like it.</p>

<p>Since version 3 (or so), Symfony is using the <a href="https://symfony.com/doc/current/components/dotenv.html">Dotenv Component</a> to manage parameters for database connection, mail server access, etc. The kind of parameter which you do not want in your Git history.</p>

<p>We put our environment variables into GitLab’s CI variables.</p>

<p><img src="//img.fox21.at/blog/20181104/blog_gitlab_civars_s.png" alt="" /></p>

<p>(This is how the variables look like for my blog. Top secret.)</p>

<p>On deployment these variables, from GitLab CI, will be replaced in a <code class="language-plaintext highlighter-rouge">.env</code>-template file. Let’s call this template file <code class="language-plaintext highlighter-rouge">.env.dist</code>.</p>

<p>Normally <code class="language-plaintext highlighter-rouge">.env</code> can look like this:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># .env</span>
<span class="nv">DB_USER</span><span class="o">=</span>root
<span class="nv">DB_PASS</span><span class="o">=</span>pass
</code></pre></div></div>

<p>Here is an example how the <code class="language-plaintext highlighter-rouge">.env.dist</code> template file could look like:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># .env.dist</span>
<span class="nv">DB_USER</span><span class="o">=</span>@SYMF_DB_USER@
<span class="nv">DB_PASS</span><span class="o">=</span>@SYMF_DB_PASS@
</code></pre></div></div>

<p>The variable names within <code class="language-plaintext highlighter-rouge">@</code> are directly coming from the <a href="https://docs.gitlab.com/ee/ci/variables/">GitLab CI/CD variables</a>.</p>

<h3 id="the-problem">The Problem</h3>

<p>Sometimes you do not just have one single value for the same variable. In most the projects we have multiple environments. For example, <em>Testing</em>, <em>Staging</em> and <em>Production</em>. By using GitLab you cannot distinguish variables based on environments in your <a href="https://docs.gitlab.com/ee/ci/variables/">CI/CD variables</a>. Of course you can put it into your <code class="language-plaintext highlighter-rouge">.gitlab-ci.yml</code>. But here lies the problem: you do not want sensitive data in <code class="language-plaintext highlighter-rouge">.gitlab-ci.yml</code>. This would mean that it’s in Git, forever.</p>

<p>So we need another way to use the same variable for multiple environments. For this purpose I created the Parameters C++ project. To get around this problem we just create multiple variables for one and the same template variable in GitLab CI/CD. Then using the <em>Parameters</em> program to replace the variable based on the environment (Testing, Staging, Production, etc).</p>

<p>Let’s take <code class="language-plaintext highlighter-rouge">@SYMF_DB_PASS@</code> from the example above. We set one default password in GitLab CI/CD variables. For the purpose of this blog post I’ll use bash syntax to describe which GitLab CI/CD variables are set:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># GitLab CI/CD Variables</span>
<span class="nv">SYMF_DB_PASS</span><span class="o">=</span>hello_world
</code></pre></div></div>

<p>For this example we assume that only the Testing environment has a different password. Staging and Production are the same. So set the default password to the once you use on Staging and Production:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># GitLab CI/CD Variables</span>
<span class="nv">SYMF_DB_USER</span><span class="o">=</span>user1
<span class="nv">SYMF_DB_PASS</span><span class="o">=</span>production_password
</code></pre></div></div>

<p>But we want to use the same <code class="language-plaintext highlighter-rouge">@SYMF_DB_USER@</code> string regardless which environment we are deploying. And we neither want to create a separete <code class="language-plaintext highlighter-rouge">.env.dist</code> template file for each environment. So, let’s create another variable for only the Testing environment:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># GitLab CI/CD Variables</span>
<span class="nv">SYMF_DB_USER</span><span class="o">=</span>user1
<span class="nv">SYMF_DB_PASS</span><span class="o">=</span>production_password
<span class="nv">SYMF_DB_PASS_TESTING</span><span class="o">=</span>testing_password
</code></pre></div></div>

<p>We want <code class="language-plaintext highlighter-rouge">@SYMF_DB_PASS@</code> to be replaced on Staging and Production environment and only on Testing to be replaced by the value of the <code class="language-plaintext highlighter-rouge">SYMF_DB_PASS_TESTING</code> environment variable.</p>

<p>And this is exactly what the Parameters program does. It reads the needed environment variables and replaces the variables in the template file based on a given environment.</p>

<p>Based on our <code class="language-plaintext highlighter-rouge">.env.dist</code> file from above, at the end the <code class="language-plaintext highlighter-rouge">.env</code> file for Testing should look like:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># .env Testing</span>
<span class="nv">DB_USER</span><span class="o">=</span>user1
<span class="nv">DB_PASS</span><span class="o">=</span>testing_password
</code></pre></div></div>

<p>For Staging and Production:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># .env Staging/Production</span>
<span class="nv">DB_USER</span><span class="o">=</span>user1
<span class="nv">DB_PASS</span><span class="o">=</span>production_password
</code></pre></div></div>

<p>Ok, this was a very common use case. With this solution we can cover the most simplest project configuration. Let’s move to the next level.</p>

<h3 id="distinguish-variables-based-on-the-environment-and-instance">Distinguish variables based on the environment and instance</h3>

<p>In some rare cases a project setup should not only be distinguished by the environment but also by an <em>instance</em> (or <em>entity</em>).</p>

<p>For example, you have two Shop instances. <em>ShopA</em> and <em>ShopB</em>. Both are based on the exact same source code. And both should be available on all environments (Testing, Staging, Production, etc). In the simplest case these both shops only differ in their database credentials. Regardless how many variables differ, the approach is always the same.</p>

<p>For the purpose of this blog post we assume that both shops are stored in different databases for each environment, Production and Testing.</p>

<p>First, let’s set our template file <code class="language-plaintext highlighter-rouge">.env.dist</code>:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># .env.dist</span>
<span class="nv">DB_USER</span><span class="o">=</span>@SYMF_DB_USER@
<span class="nv">DB_PASS</span><span class="o">=</span>@SYMF_DB_PASS@
<span class="nv">DB_NAME</span><span class="o">=</span>@SYMF_DB_NAME@
</code></pre></div></div>

<p>Now set our GitLab CI/CD variables:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># GitLab CI/CD Variables</span>
<span class="nv">SYMF_DB_USER</span><span class="o">=</span>user1
<span class="nv">SYMF_DB_PASS</span><span class="o">=</span>password1
<span class="nv">SYMF_DB_NAME</span><span class="o">=</span>default_name
<span class="nv">SYMF_DB_NAME_SHOPA</span><span class="o">=</span>my_shop_a_production
<span class="nv">SYMF_DB_NAME_SHOPB</span><span class="o">=</span>my_shop_b_production
<span class="nv">SYMF_DB_NAME_TESTING_SHOPA</span><span class="o">=</span>my_shop_a_testing
<span class="nv">SYMF_DB_NAME_TESTING_SHOPB</span><span class="o">=</span>my_shop_b_testing
</code></pre></div></div>

<p>In this example <em>ShopA</em> has <code class="language-plaintext highlighter-rouge">my_shop_a_testing</code> in the testing environment. Since there is no extra variable set for the Production environment, <em>ShopA</em> would use the <code class="language-plaintext highlighter-rouge">my_shop_a_production</code> database in Production.</p>

<p>The <code class="language-plaintext highlighter-rouge">.env</code> output for each shop and environment will be:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># .env ShopA Production</span>
<span class="nv">DB_USER</span><span class="o">=</span>user1
<span class="nv">DB_PASS</span><span class="o">=</span>password1
<span class="nv">DB_NAME</span><span class="o">=</span>my_shop_a_production
</code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># .env ShopB Production</span>
<span class="nv">DB_USER</span><span class="o">=</span>user1
<span class="nv">DB_PASS</span><span class="o">=</span>password1
<span class="nv">DB_NAME</span><span class="o">=</span>my_shop_b_production
</code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># .env ShopA Testing</span>
<span class="nv">DB_USER</span><span class="o">=</span>user1
<span class="nv">DB_PASS</span><span class="o">=</span>password1
<span class="nv">DB_NAME</span><span class="o">=</span>my_shop_a_testing
</code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># .env ShopB Testing</span>
<span class="nv">DB_USER</span><span class="o">=</span>user1
<span class="nv">DB_PASS</span><span class="o">=</span>password1
<span class="nv">DB_NAME</span><span class="o">=</span>my_shop_b_testing
</code></pre></div></div>

<p>Assuming we would also have a <em>ShopC</em>, using the same variables and the same template file from above:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># .env ShopC Production/Testing</span>
<span class="nv">DB_USER</span><span class="o">=</span>user1
<span class="nv">DB_PASS</span><span class="o">=</span>password1
<span class="nv">DB_NAME</span><span class="o">=</span>default_name
</code></pre></div></div>

<h3 id="fallback-example">Fallback example</h3>

<p>As you can see in the previous example, <em>ShopC</em> got the default name for both environments. This is because we didn’t set a specific variable for <em>ShopC</em>.</p>

<p>Here is another example for fallback variables. (Or sometimes also called <em>default</em> variables.)</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># GitLab CI/CD Variables</span>
<span class="nv">SYMF_DB_NAME</span><span class="o">=</span>name1
<span class="nv">SYMF_DB_NAME_TESTING</span><span class="o">=</span>name2
<span class="nv">SYMF_DB_NAME_TESTING_SHOPA</span><span class="o">=</span>name3
</code></pre></div></div>

<p>In this example the fallback for <em>ShopB</em> in <em>Testing</em> would be <code class="language-plaintext highlighter-rouge">SYMF_DB_NAME_TESTING</code>. Like for every other shop instance except <em>ShopA</em>. If <code class="language-plaintext highlighter-rouge">SYMF_DB_NAME_TESTING</code> is also not set,</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># GitLab CI/CD Variables</span>
<span class="nv">SYMF_DB_NAME</span><span class="o">=</span>name1
<span class="nv">SYMF_DB_NAME_TESTING_SHOPA</span><span class="o">=</span>my_shop_a_testing
</code></pre></div></div>

<p>the fallback would be <code class="language-plaintext highlighter-rouge">SYMF_DB_NAME</code> for <em>ShopB</em> for every environment.</p>

<p>These are just a few examples. There are more combinations. It’s also a good idea to always set a default value. But even better is to set exact those variables which you need.</p>

<h3 id="conclusion">Conclusion</h3>

<p>The goal is to have as less as possible files and everything set as GitLab CI/CD variables. This solution avoids sensitive data to be commited to Git. Sensitive data should <strong>never</strong> be commited to Git. Only as environment variables.</p>

<p>Of course this program is not limited to be used for Symfony. You can use it for whatever configuration files you need to replace variables.</p>

<h3 id="how-to-install-parameters">How to install Parameters</h3>

<p>See the <a href="https://github.com/TheFox/parameters/blob/master/README.md">Parameters GitHub README file</a> for more examples and how to build it from source, install it via <code class="language-plaintext highlighter-rouge">apt-get</code> under Debian, or via <a href="https://brew.sh/">Homebrew</a> under macOS.</p>
]]></description>
				<pubDate>Sat, 17 Nov 2018 00:00:00 +0100</pubDate>
				<link>https://blog.fox21.at/2018/11/17/parameters.html</link>
				<guid isPermaLink="true">https://blog.fox21.at/2018/11/17/parameters.html</guid>
			</item>
		
			<item>
				<title>C++ Factory Class</title>
				<description><![CDATA[<p>As I wrote in my <a href="/2018/11/02/cpp-smart-pointers.html">previous blog post</a>, I’m about to rewrite my Ruby <a href="https://github.com/TheFox/wallet">Wallet</a> project in C++17. See <a href="https://github.com/TheFox/wallet-cpp">WalletCpp</a> on my GitHub profile.</p>

<p>I want to use best practice and the latest standard C++17. So no <em>raw pointers</em> anymore. You should get rid of your raw pointers in your C++ code. You can do almost everything the same way using <a href="https://en.cppreference.com/w/cpp/memory/unique_ptr"><em>smart pointers</em></a>.</p>

<p>Let’s assume you want to create a <em>Command Factory</em> to produce <code class="language-plaintext highlighter-rouge">Command</code> objects from a given name. You need a base class that every command class will derivative from.</p>

<p>Let’s dive straight into the code.</p>

<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Command</span><span class="p">;</span> <span class="c1">// Base class</span>

<span class="k">class</span> <span class="nc">AddCommand</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Command</span> <span class="p">{};</span>
<span class="k">class</span> <span class="nc">EditCommand</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Command</span> <span class="p">{};</span>
<span class="k">class</span> <span class="nc">DeleteCommand</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Command</span> <span class="p">{};</span>
</code></pre></div></div>

<p>In this example above we have 3 commands: Add, Edit and Delete.</p>

<p>We will be able to get a new <code class="language-plaintext highlighter-rouge">Command</code> object for a specific name. For the purpose of this post I assume that the header file is already <a href="https://en.wikipedia.org/wiki/Include_guard">guarded</a>.</p>

<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// command_factory.hpp</span>
<span class="c1">// already guarded</span>

<span class="cp">#include</span> <span class="cpf">&lt;string&gt;</span><span class="c1">      // for std::string</span><span class="cp">
#include</span> <span class="cpf">&lt;map&gt;</span><span class="c1">         // for std::map</span><span class="cp">
#include</span> <span class="cpf">&lt;functional&gt;</span><span class="c1">  // for std::function</span><span class="cp">
</span>
<span class="k">class</span> <span class="nc">CommandFactory</span> <span class="k">final</span>
<span class="p">{</span>
<span class="nl">public:</span>
  <span class="k">static</span> <span class="kt">void</span> <span class="n">setup</span><span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>
  <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">Command</span><span class="o">&gt;</span> <span class="n">makeCommand</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>

<span class="nl">private:</span>
  <span class="k">static</span> <span class="kt">bool</span> <span class="n">isSetup</span><span class="p">;</span>
  <span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">function</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">Command</span><span class="o">&gt;</span><span class="p">()</span><span class="o">&gt;&gt;</span> <span class="n">creators</span><span class="p">;</span>
  <span class="p">};</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Here the corresponding implementation file:</p>

<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// command_factory.cpp</span>

<span class="kt">void</span> <span class="n">CommandFactory</span><span class="o">::</span><span class="n">setup</span><span class="p">()</span> <span class="k">noexcept</span>
<span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">isSetup</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Run setup only once.</span>
    <span class="k">return</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="n">isSetup</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>

  <span class="c1">// Clear creators.</span>
  <span class="n">creators</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>

  <span class="n">creators</span><span class="p">[</span><span class="s">"add"</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]()</span><span class="o">-&gt;</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">Command</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">make_unique</span><span class="o">&lt;</span><span class="n">AddCommand</span><span class="o">&gt;</span><span class="p">();</span>
  <span class="p">};</span>
  <span class="n">creators</span><span class="p">[</span><span class="s">"edit"</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]()</span><span class="o">-&gt;</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">Command</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">make_unique</span><span class="o">&lt;</span><span class="n">EditCommand</span><span class="o">&gt;</span><span class="p">();</span>
  <span class="p">};</span>
  <span class="n">creators</span><span class="p">[</span><span class="s">"delete"</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]()</span><span class="o">-&gt;</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">Command</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">make_unique</span><span class="o">&lt;</span><span class="n">DeleteCommand</span><span class="o">&gt;</span><span class="p">();</span>
  <span class="p">};</span>
<span class="p">}</span>

<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">Command</span><span class="o">&gt;</span> <span class="n">CommandFactory</span><span class="o">::</span><span class="n">makeCommand</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">_name</span><span class="p">)</span> <span class="k">const</span>
<span class="p">{</span>
  <span class="k">auto</span> <span class="n">fn</span> <span class="o">=</span> <span class="n">creators</span><span class="p">[</span><span class="n">_name</span><span class="p">];</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">fn</span> <span class="o">==</span> <span class="nb">nullptr</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">throw</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">{</span><span class="s">"Command not found: "</span><span class="p">}</span> <span class="o">+</span> <span class="n">_name</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="k">return</span> <span class="nf">fn</span><span class="p">();</span> <span class="c1">// Call lambda and return new unique pointer.</span>
<span class="p">}</span>

<span class="c1">// Private</span>
<span class="kt">bool</span> <span class="n">CommandFactory</span><span class="o">::</span><span class="n">isSetup</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">function</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">Command</span><span class="o">&gt;</span><span class="p">()</span><span class="o">&gt;&gt;</span>
  <span class="n">CommandFactory</span><span class="o">::</span><span class="n">creators</span><span class="p">;</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">setup()</code> member function will only add lambda functions to a <code class="language-plaintext highlighter-rouge">&lt;string,function&gt;</code> map. At this point we do not create new objects. Only lambda function. New objects will be created when <code class="language-plaintext highlighter-rouge">makeCommand()</code> is called.</p>

<p>You can now we use it. First, setup the factory:</p>

<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">CommandFactory</span><span class="o">::</span><span class="n">setup</span><span class="p">();</span>
<span class="n">CommandFactory</span> <span class="n">factory</span><span class="p">;</span>
</code></pre></div></div>

<p>Then new commands can be created using a name:</p>

<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">auto</span> <span class="n">addCommand</span> <span class="o">=</span> <span class="n">factory</span><span class="p">.</span><span class="n">makeCommand</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">{</span><span class="s">"add"</span><span class="p">});</span>
<span class="k">auto</span> <span class="n">editCommand</span> <span class="o">=</span> <span class="n">factory</span><span class="p">.</span><span class="n">makeCommand</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">{</span><span class="s">"edit"</span><span class="p">});</span>
</code></pre></div></div>

<p>In this example we use a fixed string to create a new command. A more realistic example:</p>

<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">auto</span> <span class="n">command</span> <span class="o">=</span> <span class="n">factory</span><span class="p">.</span><span class="n">makeCommand</span><span class="p">(</span><span class="n">commandName</span><span class="p">);</span>
</code></pre></div></div>

<p>Where <code class="language-plaintext highlighter-rouge">commandName</code> has a dynamic value and you do not know which object <code class="language-plaintext highlighter-rouge">command</code> holds. See how I used a <em>Factory Class</em> in my <a href="https://github.com/TheFox/wallet-cpp/blob/8f3d8aea60857b0542257ee6249dda151d3e5e8d/src/class/command_factory.cpp">WalletCpp</a> project.</p>
]]></description>
				<pubDate>Sun, 04 Nov 2018 00:00:00 +0100</pubDate>
				<link>https://blog.fox21.at/2018/11/04/cpp-factory-class.html</link>
				<guid isPermaLink="true">https://blog.fox21.at/2018/11/04/cpp-factory-class.html</guid>
			</item>
		
	</channel>
</rss>
