<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Programming on ma.ttias.be</title><link>https://ma.ttias.be/categories/programming/</link><description>Recent content in Programming on ma.ttias.be</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><managingEditor>mattias@ma.ttias.be (Mattias Geniar)</managingEditor><webMaster>mattias@ma.ttias.be (Mattias Geniar)</webMaster><lastBuildDate>Wed, 03 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://ma.ttias.be/categories/programming/index.xml" rel="self" type="application/rss+xml"/><item><title>Lessons learned: don't mix $timeout attributes and properties on queued Laravel jobs</title><link>https://ma.ttias.be/dont-mix-timeout-attributes-and-properties-laravel-jobs/</link><pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/dont-mix-timeout-attributes-and-properties-laravel-jobs/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; the fix described in this post has since been &lt;a href="https://github.com/laravel/framework/pull/60369" target="_blank" rel="noopener noreferrer"&gt;merged into Laravel&lt;/a&gt;
and ships in the next &lt;code&gt;13.x&lt;/code&gt; release. From that release on, a child class&amp;rsquo;s plain &lt;code&gt;$timeout&lt;/code&gt; property correctly overrides an attribute inherited from a parent, so the specific footgun below no longer bites. This post stays up as a historical write-up: how the bug behaved, the subtle PHP reflection edge case behind it, and the fix that closed it.&lt;/p&gt;</description></item><item><title>More time to think</title><link>https://ma.ttias.be/more-time-to-think/</link><pubDate>Mon, 01 Jun 2026 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/more-time-to-think/</guid><description>&lt;p&gt;I&amp;rsquo;m finding myself thinking &lt;em&gt;longer&lt;/em&gt; about the code I write and the features that get developed, than I did &lt;em&gt;before&lt;/em&gt; the agentic coding era.&lt;/p&gt;</description></item><item><title>Finding Dutch audio across streaming services</title><link>https://ma.ttias.be/finding-dutch-audio-across-streaming-services/</link><pubDate>Tue, 28 Apr 2026 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/finding-dutch-audio-across-streaming-services/</guid><description>&lt;p&gt;We have 4 streaming services at home: Netflix, Disney+, Prime Video, and Apple TV+. Try finding &lt;em&gt;which&lt;/em&gt; films and series are actually available with Dutch audio.&lt;/p&gt;</description></item><item><title>Imposter: a single-phone party game, free and open source</title><link>https://ma.ttias.be/imposter-game/</link><pubDate>Mon, 27 Apr 2026 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/imposter-game/</guid><description>&lt;p&gt;Our babysitter recently played a fun game with our kids called &amp;ldquo;Fake It&amp;rdquo;. It&amp;rsquo;s a simple party game, not too complex, and doesn&amp;rsquo;t require any props. The app store is full of them, but they all hide ads or have a €9.99/week (week!) subscription model, all trying to trick you into buying or paying. But it&amp;rsquo;s such a simple game. Surely, I can just make my own version, right?&lt;/p&gt;</description></item><item><title>How we implemented a mobile-friendly Oh Dear UI with AI</title><link>https://ma.ttias.be/mobile-friendly-oh-dear-ui-with-ai/</link><pubDate>Fri, 06 Mar 2026 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/mobile-friendly-oh-dear-ui-with-ai/</guid><description>&lt;p&gt;We just shipped a &lt;a href="https://ohdear.app/news-and-updates/oh-dear-is-now-mobile-friendly?utm_source=ma.ttias.be&amp;amp;utm_medium=referral&amp;amp;utm_campaign=blogpost-mobile-friendly-oh-dear-ui-with-ai" target="_blank" rel="noopener noreferrer"&gt;mobile-friendly version of Oh Dear&lt;/a&gt;
. It touched 226 files, added over 5,000 lines, and modified 160+ Blade templates. The PR took three weeks from first commit to merge.&lt;/p&gt;</description></item><item><title>Catching SQL performance issues in PHPUnit and Pest, as part of your test infrastructure</title><link>https://ma.ttias.be/catching-sql-performance-issues-in-phpunit-and-pest-as-part-of-your-test-infrastructure/</link><pubDate>Mon, 26 Jan 2026 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/catching-sql-performance-issues-in-phpunit-and-pest-as-part-of-your-test-infrastructure/</guid><description>&lt;p&gt;I&amp;rsquo;ve been on a bit of a SQL performance kick lately. Over at &lt;a href="https://ohdear.app?utm_source=ma.ttias.be&amp;amp;utm_medium=referral&amp;amp;utm_campaign=blogpost-catching-sql-performance-issues-in-phpunit-and-pest-as-part-of-your-test-infrastructure" target="_blank" rel="noopener noreferrer"&gt;Oh Dear&lt;/a&gt;
, I wrote a &lt;a href="https://ohdear.app/news-and-updates/our-3-part-series-on-sql-performance-optimisations?utm_source=ma.ttias.be&amp;amp;utm_medium=referral&amp;amp;utm_campaign=blogpost-catching-sql-performance-issues-in-phpunit-and-pest-as-part-of-your-test-infrastructure" target="_blank" rel="noopener noreferrer"&gt;3-part series about finding, fixing, and automatically detecting SQL performance issues&lt;/a&gt;
. The last part of that series covers how we catch regressions &lt;em&gt;before&lt;/em&gt; they hit production by running checks in our test suite.&lt;/p&gt;</description></item><item><title>Using AI is no longer optional</title><link>https://ma.ttias.be/ai-no-longer-optional/</link><pubDate>Fri, 09 Jan 2026 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/ai-no-longer-optional/</guid><description>&lt;p&gt;We&amp;rsquo;ve gone from generating funny images to AI being a core part of being a developer quite fast, haven&amp;rsquo;t we?&lt;/p&gt;</description></item><item><title>Web development is fun again</title><link>https://ma.ttias.be/web-development-is-fun-again/</link><pubDate>Sat, 03 Jan 2026 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/web-development-is-fun-again/</guid><description>&lt;p&gt;I remember when PHP 4 was a thing. jQuery was new and shiny. Sites were built with tables, not divs. Dreamweaver felt like a life hack. Designs were sliced in Photoshop. Databases lived in phpMyAdmin.&lt;/p&gt;</description></item><item><title>cargo: no such subcommand: +nightly</title><link>https://ma.ttias.be/cargo-no-such-subcommand-nightly/</link><pubDate>Mon, 23 Nov 2020 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/cargo-no-such-subcommand-nightly/</guid><description>&lt;p&gt;I was trying to run the following command:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ cargo +nightly install [package]
error: no such subcommand: `+nightly`
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But &amp;hellip; that didn&amp;rsquo;t work. This was my fix:&lt;/p&gt;</description></item><item><title>Could not find directory of OpenSSL installation</title><link>https://ma.ttias.be/could-not-find-directory-of-openssl-installation/</link><pubDate>Mon, 23 Nov 2020 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/could-not-find-directory-of-openssl-installation/</guid><description>&lt;p&gt;Ran into this error when compiling some software from source:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Could not find directory of OpenSSL installation, and this `-sys` crate cannot
proceed without this knowledge. If OpenSSL is installed and this crate had
trouble finding it, you can set the `OPENSSL_DIR` environment variable for the
compilation process.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The fix is, luckily, rather easy.&lt;/p&gt;</description></item><item><title>wabt-sys compile: error: CMAKE_PROJECT_VERSION was not declared in this scope on Ubuntu 18.04 LTS</title><link>https://ma.ttias.be/wabt-sys-compile-error-cmake-project-version-not-declared-in-scope-ubuntu-18-04/</link><pubDate>Mon, 23 Nov 2020 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/wabt-sys-compile-error-cmake-project-version-not-declared-in-scope-ubuntu-18-04/</guid><description>&lt;p&gt;When trying to compile WebAssembly (&lt;code&gt;wabt-rs&lt;/code&gt;) for a dependent package, it failed on Ubuntu 18.04 LTS due to this error message.&lt;/p&gt;</description></item><item><title>Git commit without the pre-commit hook</title><link>https://ma.ttias.be/git-commit-without-pre-commit-hook/</link><pubDate>Mon, 29 Jun 2020 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/git-commit-without-pre-commit-hook/</guid><description>&lt;p&gt;Quick tip if you want to skip the pre-commit validations and quickly want to get a commit out there.&lt;/p&gt;</description></item><item><title>Want to improve? Add a delay</title><link>https://ma.ttias.be/want-to-improve-add-a-delay/</link><pubDate>Thu, 11 Jun 2020 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/want-to-improve-add-a-delay/</guid><description>&lt;p&gt;If you&amp;rsquo;re a bit like me, you&amp;rsquo;re probably impatient. You want things to move quickly. &lt;em&gt;There&amp;rsquo;s no time to waste!&lt;/em&gt;&lt;/p&gt;</description></item><item><title>A PHP package to simplify working with percentages</title><link>https://ma.ttias.be/php-package-simplify-working-percentages/</link><pubDate>Mon, 01 Jun 2020 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/php-package-simplify-working-percentages/</guid><description>&lt;p&gt;I created a PHP package that can make it easier to work with percentages in any PHP application.&lt;/p&gt;</description></item><item><title>Dissecting the code responsible for the Bitcoin halving</title><link>https://ma.ttias.be/dissecting-code-bitcoin-halving/</link><pubDate>Sun, 10 May 2020 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/dissecting-code-bitcoin-halving/</guid><description>&lt;p&gt;When I wrote this in May 2020, the Bitcoin network was a few hours away from its third &amp;ldquo;halving&amp;rdquo;. So what is it and how does it work under the hood?&lt;/p&gt;</description></item><item><title>Creating a 2-of-3 multisig with raw transactions on EOSIO</title><link>https://ma.ttias.be/creating-2-of-3-multisig-raw-transactions-eos/</link><pubDate>Tue, 05 May 2020 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/creating-2-of-3-multisig-raw-transactions-eos/</guid><description>&lt;p&gt;These instructions can be followed to create a 2-out-of-3 multisignature address on the EOS blockchain (or any derivative thereof). This means you will need at least 2 out of the 3 keyholders to sign off on a transaction before any funds can be spent.&lt;/p&gt;</description></item><item><title>Selecting all checkboxes on a page with the Developer Console</title><link>https://ma.ttias.be/selecting-all-checkboxes-developer-console/</link><pubDate>Sun, 03 May 2020 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/selecting-all-checkboxes-developer-console/</guid><description>&lt;p&gt;A quick reminder to myself that the Developer Console in Chrome or Firefox is useful to mass-select a bunch of checkboxes, if the site doesn&amp;rsquo;t have a &amp;ldquo;select all&amp;rdquo;-option (which really, it should).&lt;/p&gt;</description></item><item><title>Composer require specific version while ignoring package dependencies</title><link>https://ma.ttias.be/composer-require-specific-version-while-ignoring-dependencies/</link><pubDate>Thu, 16 Apr 2020 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/composer-require-specific-version-while-ignoring-dependencies/</guid><description>&lt;p&gt;I&amp;rsquo;m working on some new versions of PHP packages, and for that I&amp;rsquo;m working of a temporary branch. I wanted to update my local &lt;code&gt;composer&lt;/code&gt; packages, but ran into a package constraint.&lt;/p&gt;</description></item><item><title>Forcing a Content-Type header with Guzzle's form_params</title><link>https://ma.ttias.be/force-content-type-header-guzzle-form-params/</link><pubDate>Mon, 09 Mar 2020 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/force-content-type-header-guzzle-form-params/</guid><description>&lt;p&gt;I just lost an hour or 2 of my life to this, so I figure I&amp;rsquo;ll do a small write-up to save &lt;em&gt;future me&lt;/em&gt; from having to do the same dance.&lt;/p&gt;</description></item><item><title>Adding a sticky table of contents in Hugo to posts</title><link>https://ma.ttias.be/adding-a-sticky-table-of-contents-in-hugo-to-posts/</link><pubDate>Wed, 26 Feb 2020 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/adding-a-sticky-table-of-contents-in-hugo-to-posts/</guid><description>&lt;p&gt;&lt;a href="https://www.bram.us" target="_blank" rel="noopener noreferrer"&gt;Bram Van Damme&lt;/a&gt;
recently &lt;a href="https://www.bram.us/2020/01/10/smooth-scrolling-sticky-scrollspy-navigation/" target="_blank" rel="noopener noreferrer"&gt;shared a really cool method of showing a table of contents&lt;/a&gt;
on a page and I&amp;rsquo;ve wanted to implement it on this blog ever since.&lt;/p&gt;</description></item><item><title>Making a JSON prettifier in pure JavaScript</title><link>https://ma.ttias.be/making-a-json-prettifier-in-pure-javascript/</link><pubDate>Fri, 20 Dec 2019 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/making-a-json-prettifier-in-pure-javascript/</guid><description>&lt;p&gt;A few weeks ago I toyed with the idea of making a JSON prettifier myself. I often use these to re-format and debug a minified JSON payload.&lt;/p&gt;</description></item><item><title>How to use ffmpeg to combine multiple videos to one</title><link>https://ma.ttias.be/use-ffmpeg-combine-multiple-videos/</link><pubDate>Sat, 09 Nov 2019 00:00:00 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/use-ffmpeg-combine-multiple-videos/</guid><description>&lt;p&gt;Here&amp;rsquo;s a quick tip on how to combine multiple separate videos into a single one, using &lt;code&gt;ffmpeg&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>A github CI workflow tailored to modern PHP applications (Laravel, Symfony, …)</title><link>https://ma.ttias.be/a-github-ci-workflow-tailored-to-laravel-applications/</link><pubDate>Thu, 03 Oct 2019 11:45:56 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/a-github-ci-workflow-tailored-to-laravel-applications/</guid><description>&lt;p&gt;Last year we wrote a blogpost about our setup we use for &lt;a href="https://ohdear.app/" target="_blank" rel="noopener noreferrer"&gt;Oh Dear!&lt;/a&gt;
with Gitlab, and &lt;a href="https://ohdear.app/blog/our-gitlab-ci-pipeline-for-laravel-applications" target="_blank" rel="noopener noreferrer"&gt;how we use their pipelines for running our CI tests&lt;/a&gt;
. Since then, we&amp;rsquo;ve moved back to Github since they introduced their free private repositories.&lt;/p&gt;</description></item><item><title>Benchmarking websocket server performance with Artillery</title><link>https://ma.ttias.be/benchmarking-websocket-server-performance-with-artillery/</link><pubDate>Tue, 04 Dec 2018 22:18:20 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/benchmarking-websocket-server-performance-with-artillery/</guid><description>&lt;p&gt;We recently deployed a custom websocket server for &lt;a href="https://ohdear.app" target="_blank" rel="noopener noreferrer"&gt;Oh Dear!&lt;/a&gt;
and wanted to test its ability to handle requests under load. This blogpost will explain how we performed that load test using &lt;a href="https://www.artillery.io/" target="_blank" rel="noopener noreferrer"&gt;Artillery&lt;/a&gt;
.&lt;/p&gt;</description></item><item><title>Tracking SQL queries</title><link>https://ma.ttias.be/tracking-sql-queries/</link><pubDate>Thu, 22 Nov 2018 12:00:33 +0000</pubDate><author>mattias@ma.ttias.be (Mattias Geniar)</author><guid>https://ma.ttias.be/tracking-sql-queries/</guid><description>&lt;p&gt;This is a very clever technique that allows you to add meta data (or &amp;ldquo;comments&amp;rdquo;) to SQL queries from within your application or framework.&lt;/p&gt;</description></item></channel></rss>