RSS Amplifier

Blog

Home | BackEndTea

Home

backendtea.comRSS feed ↗75 posts

Latest posts

Immutable by default: How to avoid hidden state bugs in OOP

One of the harder bugs to debug are bugs dealing with mutable data. A while ago we ran into a problem where the last_modified date of entities was always 1 day off. See if you can spot the issue in the code below: class MyEntity { public function __construct ( public DateTime $lastModified ) {} } function saveEntity ( Notifier $notifier ) { $now = new DateTime (); $entity = new MyEntity ( $now );…

Add an element from an array in JavaScript

In JavaScript, there are a few ways to add an element to an array. Depending on whether you want to add an element to the start or the end, or even in the middle. Using Array.push() or Array.unshift() to add elements to the array With Array.push() you add an item to the end of an array, and with Array.unshift() you add an item to the begin of the array. const cities = [ 'Stormwind' , 'Orgrimmar' ,…

Types are documentation

Adding types to your PHP code base is more than just runtime validation. It helps both developers and static analysis tools, by making the code clearer and easier to understand. Adding types makes code more self-explanatory and gives you a form of documentation. A function with proper types will help clarify what it is supposed to do. It becomes easier to determine what a function does from…

See all the queries mysql does with the query log.

When debugging an older application, just reading the code might not be enough to find all the queries it does. Sometimes queries are done in a worker as well, so finding out exactly what happens can be difficult. Thankfully we can enable mysql query log, to see the results. And its easy to enable as well. All you need are the following SQL statements: SET GLOBAL log_output = 'TABLE' ; SET GLOBAL…

Stop firefox from exiting full screen on pressing escape

A while ago I got a new macbook, and installed firefox again. But I quickly ran into the issue where if you press escape, it closes the fullscreen. Which to me is an insane default, as I might press escape to try and close a modal for example. Thankfully the fix is pretty easy. Just go to about:config (put it in the address bar). You might have to press an Accept the risk and continue button. In…

Why I prefer array functions over loops

I’ve come to prefer using array functions over foreach loops in PHP. And while the syntax isn’t as nice as in JavaScript, I still think they work better than a ’normal’ loop. What are array functions In PHP you have quite some array functions , each with their own use. For this post I’m talking about the functions that loop over an array, and execute a function for…

Being a software engineer is a lot like being a butcher

I was a butcher for roughly four years before I became a software engineer. (And nowadays, I’m a vegetarian.) And while one of the jobs doesn’t require you to work inside a refrigerator half the time, there are actually quite some similarities in how we keep our work environment clean. Keeping your work environment clean Both as a butcher and as a software engineer I see four different…

Change extensions of all files in a folder

This week I wanted to change all the .js files to .ts recursively in a folder. To change all .js files in the assets folder. With a bit of bash, using a for loop and mv I got the following command to rename all my .js to .ts files. for f in assets/*.js ; do mv -- ' $f ' ' ${ f %.js } .ts' ; done If you want to get notified of the next blog post, join the newsletter.

Keep retrying a bash command until it fails

This week I noticed a test was flaky, and was occasionally failing in CI. So I wanted to re-run my script until it failed. I had no clue how to do this, so after a bit of trying, I got the following script. This keeps running vendor/bin/phpunit until it fails. You can save it as run.sh and then just run sh ./run.sh in your terminal, and it will keep running. #!/bin/sh set -e while [ true ] do…

Break the rules! (but only if you understand them)

There are a lot of ‘rules’ in software engineering. Don’t copy-paste your code, don’t use goto , your code should be easily understandable, and many more. Generally these rules make sense, but every once in a while someone will have a hot take, and post about how you should copy-paste your code everywhere, how goto is the greatest invetion ever, or how variable names should…

PHP 8.2 changes to iterator functions I missed

This week I learned of a small change that got introduced in PHP 8.2 that I completely missed. The iterator_*() functions got an update, which make them actually usable when dealing with the iterable type. Now this is only really relevant if you are dealing with iterables that might not be arrays, but you need to use them as an array. The big change is that a function like iterator_to_array , it…

"Just use Psl for that"

Something I’ve been hearing myself says in every project that I have installed Psl in, is “Just use Psl for that”. And while some bits and bobs like array_find are getting into PHP 8.4, the library does so much more. In this post I’ll go over the bits that I use often, and maybe convince you to give it a try as well. What is Psl Psl is a php composer package that can be…

Why you should be typing your arrays in PHP

We have been able to natively type parameters of methods and functions in PHP for quite some time. In basically any version of PHP you should be running we can do something like the following: function getNames ( array $input ) : array { return array_map ( function ( $item ) { return $item -> getName (); }, $input ) } Basic array types This however tells us very little about the types that we are…

How to fix "connect to host github.com port 22: Operation timed out"

The problem This weekend I was at a holiday resort. In the morning I wanted to do a little bit of work, and encountered the following error when I tried to pull a repo. $ git pull ssh: connect to host github.com port 22: Operation timed out fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. At first, I assumed my internet…

What is PHP's declare(strict_types=1); and why you should use it

You may have had people tell you that you should use declare(strict_types=1); in your PHP files, but what exactly does it do, and why should (or shouldn’t) you use it? History A long, long time ago PHP didn’t have scalar types, or even return types. In PHP 7.0 both of these got introduced. In 5.6 and before we had to use annotations, and couldn’t add it in the language. (If you…

Backing up files with one bash command

Recently I wanted to make some changes to my SSH config, but I didn’t want to accidentally break anything, and lose my correct config. So I manually did an mv ~/.ssh/config ~/.ssh/config_back , made some changes, and moved it back again. I had to do this a couple of times to try out different things, and realized I had done things like this quite some times just to make a quick backup with…

Get a rough estimation of how many rows are in a table, without using count

When you want to know how many rows a table in MySQL has, the easiest way is: SELECT COUNT ( 1 ) FROM < table_name > ; However, if the table is massive, this might take a long time, as it needs to look at all rows. Thankfully there is another way in mysql, where you can get a rough estimation of the row numbers: SELECT TABLE_ROWS FROM information_schema . tables WHERE TABLE_NAME = '<table_name>'…

Adding PHPStan to a legacy project

PHPStan PHPStan is a static analysis tool for PHP. It helps you find problems in your code base, like passing wrong types, calling methods that don&rsquo;t exist, detect wrong annotations, and so much more. I would argue you shouldn&rsquo;t be writing PHP code these days without having a static analyzer to help you. It reduces the errors you create, and speeds up your development significantly.…

What ive been reading: Deep work by Cal Newport

Deep work I finished reading deep work about a week ago. If you want to become a mythical 10x developer (or 10x anything really), this book provides you with the tool on how to succeed in just that. A lot of us fall into a trap of doing mostly, what this book calls, shallow work. We have meetings that aren&rsquo;t really important, we do meaningless tasks, and spend half our day in meeting that…

5 Tips for better code reviews

A big part of software engineering is code review. Good code reviews will help your code base become better and help you and your colleagues learn from each other. Let&rsquo;s take a look at some code review best practices and tips! 1: Have your tools check the code for you The best way to have good code review is to reduce what needs to be reviewed as much as possible. When reviewing code, I…

Allowing failure in GitLab CI

In GitLab, sometimes you want to (temporarily) allow a script to fail. It may be that you are running your tests against a newer PHP/NodeJs version, which you are not yet compatible with. In that case you can allow the pipeline to fail, without blocking anything else, or turning it red and blocking your merges. As mentioned in a previous post , you shouldn&rsquo;t be abusing it, but sometimes you…

Check if an array contains an element in JavaScript

In JavaScript, there are a few ways to check if an array contains an element. Depending on if you need to know if it contains an exact value, or match a criteria, you have different options. Using Array.includes to check for an exact value With Array.includes() you can check that your array contains an exact value you are looking for. For example: const trees = [ 'oak' , 'willow' , 'maple' , 'yew'…

Remove an element from an array in javascript

In JavaScript, there are a few ways to remove an element from an array. Depending on whether you want to remove elements by value, by index, or based on a condition, you have different options to choose from. Using Array.splice() or Array.toSpliced() to remove elements by index With Array.splice() you can remove an element from an array by telling it from what index you want to start removing and…

Analyze your tests with PHPStan

Hopefully you are already using PHPStan to analyze your source code. But you shouldn&rsquo;t stop there, in fact, you should also make sure you are analyzing your test code. Why analyze your tests If you are already using PHPStan to analyze your source code, then you probably see the value in static analysis. The same reasons for analyzing your source code are true for your tests. You can find…

The difference between for .. in and for .. of in javascript

If you want to do a for loop over an array in javascript you generally want to do a for (const value of array) { . Because this will loop over all the items of an array. A for (const key in array) { will instead loop over the keys of an array (or of an object). const letters = [ 'a' , 'b' , 'c' ]; for ( const value of letters ) { console . log ( value ); // 'a', 'b', 'c' } for ( const key in…

How to create a random string in PHP

There are a lot of ways to generate a random string in PHP. In this post we&rsquo;ll take a look at two options we have, and how to use them. The Randomizer The Randomizer class (introduced in PHP 8.2) is arguably the best way in OOP PHP to use randomness, and should be used whenever possible. It comes with 2 methods for creating random strings. Where getBytes will give you a random set of bytes…

Finding the last element of an array in javascript

In javascript there is a few ways of getting the last item in an array. In this post we&rsquo;ll go over them Using Array.at() Array.at has been available in the major browsers and node, since mid 2021 (except safari which introduced it in safari 15.4 in early 2022). With Array.at you can simply pass -1 to get the last element, or -2 to get the second to last element, and so on. Or if that item…

Mastering PHPUnit: Using Mocks and Stubs

This is part 4 of a series on PHPUnit testing, you can find part 3 here . In this post we&rsquo;ll focus on the use of mocks. We&rsquo;ll cover why we need them, the different types of mocks, and how to use them. Why do we need mocks? A mock is a stand in for a dependency that you dont want to (currently) test. The most commonly used example might be the database. In your unit tests, you…

Mastering PHPUnit: Using data providers

This is part 3 of a series on PHPUnit testing, you can find part 2 here . In this post we&rsquo;ll focus on the use of data providers. I have written about them before, but for earlier PHPUnit versions. This post is relevant for PHPUnit version 10 or higher. For version 9 or lower check out the original data provider post What are data providers? A data provider is a function or method that, as…

Mastering PHPUnit: Writing Your First Test with PHPUnit

This is part 2 of a series on PHPUnit testing, you can find part 1 here . This post will have us writing our first unit test, and explain some of the basics in doing so. TestCase class Every test we write has to extend the PHPUnit\Framework\TestCase class. PHPUnit will look for classes in its configured folders that extend from this class, to execute tests. Within your class it will look for all…

Books

Here you can find books that I highly recommend any software developer to read. Clean Code Clean code by Robert Martin is probably the single most influential book for me as a software engineer. I read it while in college, and it changed the way I write code tremendously. It especially opened my eyes on how I wrote comments. You can find it on Amazon . Working Effectively with Legacy Code Working…

Mastering PHPUnit: an introduction

In this blog series we&rsquo;ll go from writing our first unit test to being a PHPUnit master. This first post will go over the basics, and introduce you to PHPUnit What is PHPUnit? PHPUnit is the de facto testing framework for PHP. It initially started in 2001, over 23 years ago at this point. And even today it is still under active development. All its development is done on , where you can open…

Never deploy an untagged dependency again

Today we ran into an issue with a build in one of our projects. Composer could no longer install, as a dependency was gone. When we opened our pipeline logs we saw the following error: failed to execute git checkout '<ref>' - - && git reset --hard '<ref>' -- fatal: reference is not a tree: <ref> It looks like the commit hash is not available in the repository, maybe the commit was removed from the…

Uses

The idea of a Uses page is to tell you about the stuff I use. Make sure to check out uses.tech for a list of everyone&rsquo;s Uses pages! I often get asked about what software or hardware I use, so this page will serve as a living document and a place to point curious readers to when I get asked. Hardware I&rsquo;m using a 14" M3 Pro MacBook Pro with 11‑core CPU, 14‑core GPU with 36GB RAM . So far…

Stop (ab)using allow failure

We&rsquo;ve all had our CI fail due to an issue that couldn&rsquo;t be fixed right away. Usually something like a security issue in a downstream package that can&rsquo;t be updated yet. This then causes the build to fail, making us unable to merge or deploy. allow_failure seems like a great way to solve this, but it is not. allow_failure is setting us up for failure. Because now any issue with…

Creating better services

When writing code, you generally want to split up the logic in to different classes. You have your controller classes which take a request, and return a response. You write value objects to represent information which is important to your application. You may write commands, command handlers, repositories and more. The most important group of classes you write are probably your services, which…

Differential serving with webpack encore

Recently we&rsquo;ve been looking into differential serving. With our set up there were a few complications, so in this post i&rsquo;ll share how we overcame those, and how to set up differential serving with webpack encore. If you want an explanation of what differential serving is, or how to do with with a normal webpack setup, i suggest reading this post . In our project we use webpack encore .…

PHP needs an "unknown" type

If you are familiar with Typescript, you may know their any type. With any you can do anything. It signals that you don&rsquo;t know about the actual type, and that anything goes. The following code is completely valid in Typescript. const doTheThing = ( input : any ) => { input + input ; input . toString (); Object . keys ( input ). map (( key ) => { return input . foo [ key ]; }); const [ one ,…

Using CSS modules in react when testing with enzyme

We&rsquo;ve been using CSS modules in a react project, and wanted to use those classes in our tests. However we quickly ran into the problem that none of the classes were found. Any wrapper.exists would be false. The problem was with our css modules, as they were not imported correctly during tests. Our code looked like this: import styles from './QA.scss?module' ; interface QAProps { question :…

Testing Exceptions in PHPUnit

Last week i gave 10 phpunit tips . This week we&rsquo;ll take a look at testing exceptions, which wasn&rsquo;t covered in that post. Lets start with some example code that we will be testing. We have the Email and EmailValidator classes. Email is a value object that makes sure it is a valid email. We use the EmailValidator to make sure that the emails are only from our company. //Email.php final…

10 PHPUnit Tips

PHPUnit is the defacto testing framework for PHP. In this post i want to share with you my top 10 tips for PHPUnit. I&rsquo;m using PHPUnit 9.5, but most of these apply to older versions as well. So, lets get this party started. 1: Stop using assertEquals One of the most common mistakes is using assertEquals . Instead, you should be using assertSame . When using equals we are doing an == check,…

Help my Doctrine migrations are broken!

Recently we ran into a problem with doctrine migrations. The schema was manually edited, and wrong migrations were committed to the repository. For a dev (and even staging) env you could just drop the database, fix the migrations, and run them again. But we didn&rsquo;t want to lose our production data. So how do we fix this? We really had 2 problems. Our migrations were wrong, and the…

A problem with Twig

I&rsquo;m a fan of twig, and wouldn&rsquo;t consider moving back to plain php. But, it does come with a few problems. In this post we&rsquo;ll explore one of the problems i have with twig, and how to work around it. The problem When you use a twig file, you do not know what variables it needs, what variables i can use, and what types those variables should be. You have to read the template, or…

Explore Your Types

Don&rsquo;t worry, this isn&rsquo;t a &lsquo;what type of sandwich are you?&rsquo; kinda post. Instead we&rsquo;ll look at how we can safely add types to our legacy code. Adding types There are really two ways of adding types. You either declare what you want your types to be, or you declare what the types can be. When writing new code we should always be precise in our types, so we declare what…

You should be using PHPStans bleeding edge

Does your project use PHPStan? Then you really should be using the bleeding edge config, regardless of what level you are running. It will make transition to the newer version much easier. What is bleeding edge To preserve backwards compatibility as much as possible, new rules, and new settings are delayed until the next major version. For example, using null coalesce on a variable that can not be…

PHPUnit beyond basics: Dataproviders

Once you have set up your first unit tests, and you have a good configuration , its time to add a lot of tests. Lets take a look at using data providers, as a way to test with a lot of data. For this example we&rsquo;ll test a piece of code that is supposed to do the following. Given the array ['a', 'b', 'c'] , return the string a a-b a-b-c b b-c c . This function has to combine the array values…

PHPUnit beyond basics: configuration

If you just got started with PHPUnit, its configuration file may be a bit daunting. Today we&rsquo;re gonna walk through (what i consider) the ideal config file. If you&rsquo;re just here to copy paste the config, then you can find it at the bottom &#x1f447;. A minimum phpunit.xml may look like this: <?xml version='1.0' encoding='UTF-8'?> <phpunit> <testsuites> <testsuite name= 'Tests' >…

Every day design pattern: Builder

Just like the factory pattern, the builder is a creational pattern, meaning it is about how objects are created. But unlike a factory, a builder allows you to build an object in parts. I tend to use it for creating objects that take a configuration. Lets start with an example. This class builds a guzzle client, with a certain config. Normally we have a timeout of 10 seconds, with a 5 second…

Every day design pattern: Factory

The previous two chapter of this blog series were about the decorator and the adapter . These are structural design patterns. Meaning they deal with the structure of a system. They can help with simplifying relationships, and moving responsibilities. The factory is a completely different type of design pattern. Its a creational pattern . A creation pattern is intended to make creation of objects…

Every Day Design Pattern: Adapter

This is the second post in a series of design patterns i use (almost) daily. You will find the other posts at the bottom of this article. On wikipedia , the adapter pattern is described like so: the adapter pattern is a software design pattern (&hellip;) that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others…