Dynamic OpenGraph Images in Astro

If you’ve ever shared a link on social media, you know how critical OpenGraph (OG) images are. They’re the first thing people see – often before they even click.
Static OG images are fine as a start, but what if you want custom images for every blog post or content collection item?

For Astro there is astro-og-canvas, a nice and useful Astro plugin that utilizes Canvas to create dynamic OG images.

In this post, I’ll walk you through how to generate dynamic OG images for your Astro site, inspired by Aidan Kinzett’s excellent post.
I’ll also share some odds and learned lessons.

Continue reading “Dynamic OpenGraph Images in Astro”

Symfony HTTP Client default timeout


Small Service Post:

The default timeout of the Symfony HTTP Client is 60s (seconds)!

Sure, it is mentioned in the Symfony HTTP Client docs, that PHP’s default_socket_timeout is taken as default value.
So what is the default_socket_timeout then, you might wonder?

One click away in PHP Runtime Configuration docs you will find that in the php.ini the default value is “60”.
In case you wonder what unit these “60” is, you will find (in seconds) a bit down below the config table.
– Yeah, seconds was my first guess, but I need to assure it is not microseconds by any chance. –

And thats it! Thats the post.

P.S: It is funny how scattered information sometimes is, although is all there.
AI did know, but did not name a source.
And since AI is not to trust, I still had to look it up via Search.

From Xubuntu to Lubuntu

I have this old, super-cheap laptop: Lenovo E145, which I use as my travel and breakfast laptop. It has 8GB of RAM and a very weak CPU (AMD E1-2500 APU). Any modern mobile phone probably has more resources these days.

For surfing the web, checking mails, editing and uploading some fotos it is sufficient and I prefer using a laptop for this.

I used to run Xubuntu on it, but lately it had performance issues and all programs and actions were lagging very significantly. So I decided to reinstall the OS and try Lubuntu, since it should be even more lean.

I grabbed the current Lubuntu image (25.04 Plucky Puffin), created a bootable USB stick, and installed Lubuntu. So far, so good. And indeed, everything felt much smoother and faster.

But, as usual, there are some post-installation hiccups which needed a bit more tuning.

Continue reading “From Xubuntu to Lubuntu”

Yazi PDF preview not working

Yazi is a terminal-based file manager (TUI) that I use heavily because it’s fast and lets me navigate files and folders without needing a mouse. (…and I really dislike the OSX Finder)

Yazi can render previews for images and PDF files, but in my case, PDF previews weren’t showing up. Yazi requires Poppler for PDF previewing–and it was already installed on my system–the previews still didn’t work.

So I began debugging by running yazi --debug, which provides detailed information about your Yazi installation. Under the Dependencies section, I noticed a suspicious message:

pdftoppm      : ExitStatus(unix_wait_status(25344)),"pdftoppm version 4.0...
Continue reading “Yazi PDF preview not working”

Patch dependencies with composer-patches

Sometimes, you may encounter a bug or an unwanted functionality in a PHP vendor dependency, and forking the package and maintaining upstream changes can be too cumbersome. In such cases, using composer-patches is a good solution.

Composer-patches is a handy Composer plugin that applies diff patches to specific packages during installation.

Basically, you store a diff patch in your project, specify which vendor package it should be applied to in your composer.json, and the plugin will apply the patch to the original code of the vendor package after it got installed by composer.

Continue reading “Patch dependencies with composer-patches”

Doctrine: WHERE IN with array of integers

Since I stumbled across this the other day, here’s how you build an SQL query with a WHERE IN condition for an array of integers.

This is surprisingly not intuitive, as you cannot simply pass an array of integers to a prepared statement. Instead, you need to add special binding types to inform Doctrine that this is indeed an array of integers.

It’s very well explained in the documentation under the Parameters Conversion section:
https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/data-retrieval-and-manipulation.html#list-of-parameters-conversion
But it is rather hard to find and it took me a while.

The trick is to add the array binding types to the the types parameters to the query method. In the case of integers, it is \Doctrine\DBAL\ArrayParameterType::INTEGER.
Now Doctrine knows how to handle the types in the array while binding the values.

Continue reading “Doctrine: WHERE IN with array of integers”

Typed Arrays with PHPStan types

When dealing with legacy data, you often encounter arrays or associative arrays. These arrays are untyped, which PHPStan, of course, does not accept, resulting in numerous PHPStan errors.

PHPStan, by the way, is a static analysis tool for PHP that enforces strict typing and checks for compliance with PHPDoc annotations, ensuring code is robust and maintainable.
For any serious project you should use it.

For this code:

$array = $this->getUntypedArray();
$res = $this->funcWithInt($array['number']);
...
private function funcWithInt(int $number):int {
    return $number++;
}Code language: PHP (php)

A typical error could be:

Parameter #1 $number of method TestClass::funcWithInt expects int, mixed given.Code language: PHP (php)
Continue reading “Typed Arrays with PHPStan types”

Deploy local build with Deployer7


Deployer is a great tool to deploy your PHP Project.

Deployer executes a set of commands on the target server to build your project and enable the newly built version. A typical deployment process with Deployer involves SSHing into the target machine, where it performs a Git checkout of the project, installs dependencies via Composer, runs build commands, and possibly triggers some database migrations. When everything is successful, it will symlink the webroot to the new release.

On some servers, however, there are limitations that make this process unfeasible. For instance, you can’t install Composer, Git isn’t available, the CLI PHP version is different and can’t be changed, or certain asset-building processes aren’t possible because Node.js isn’t installed. This is often the case with shared hosting.

Continue reading “Deploy local build with Deployer7”