Category: PHP

PHP: when should I use ‘self’ and when should I use ‘$this’?

In PHP, the keyword $this is used to refer to the current instance of the class, while the keyword self is used to refer to the class itself.

You should use $this when referring to instance-level properties or methods within the same class, such as when accessing a property of the current object or calling a method of the current object.

For example:

class MyClass {
    private $name;

    public function __construct($name) {
        $this->name = $name;

    public function sayHello() {
        echo "Hello, my name is " . $this->name;

$obj = new MyClass("John");
$obj->sayHello(); // output: "Hello, my name is John"

On the other hand, you should use self when referring to static properties or methods within the same class, such as when accessing a static property or calling a static method of the class.

For example:

class MyClass {
    private static $count = 0;

    public function __construct() {

    public static function getCount() {
        return self::$count;

$obj1 = new MyClass();
$obj2 = new MyClass();
echo MyClass::getCount(); // output: 2

In summary, $this is used for instance-level properties and methods, while self is used for static properties and methods.


PHP: How to check if a string contains a specific word?

You can check if a string contains a specific word in PHP by using the strpos() function, the preg_match() function or the str_contains() function.

Using strpos()

The strpos() function returns the position of the first occurrence of a substring in a string. If the substring is not found, it returns false. You can use this function to check if a string contains a specific word as follows:

$string = "This is a sample string.";
$word = "sample";

if (strpos($string, $word) !== false) {
    echo "The string contains the word.";
} else {
    echo "The string does not contain the word.";

In this example, we first define a string $string and a word $word. Then, we use the strpos() function to check if the $string contains the $word. If the $word is found in the $string, the function will return a position value that is not false, and the output will be “The string contains the word.” Otherwise, the function will return false, and the output will be “The string does not contain the word.”

Using preg_match()

The preg_match() function searches a string for a pattern and returns true if the pattern is found, and false otherwise. You can use this function to check if a string contains a specific word as follows:

$string = "This is a sample string.";
$word = "/sample/";

if (preg_match($word, $string)) {
    echo "The string contains the word.";
} else {
    echo "The string does not contain the word.";

Using str_contains()

The str_contains() method is available in PHP 8 and higher versions. You can use this method to check if a string contains a specific word as follows:

$string = "This is a sample string.";
$word = "sample";

if (str_contains($string, $word)) {
    echo "The string contains the word.";
} else {
    echo "The string does not contain the word.";

Performance Comparison

When comparing the performance of those three methods, we get the following result:

strpos()1.37e-7 seconds = 0.137 micro seconds
preg_match()1.54e-7 seconds = 0.154 micro seconds
str_contains()1.28e-7 seconds = 0.128 micro seconds

So the new method str_contains() (for PHP 8.0 or higher) is the fastest one.

For the results, the mean execution time in a loop with 1,000,000 cycles was calculated for each method.


Pecl: fixing “fatal error: ‘pcre2.h’ file not found”

When using pecl to install a PHP extension, I always got a “fatal error: ‘pcre2.h’ file not found” after PHP has been updated. The update was done using brew upgrade php. In my case, this happens when I try to install pcov using:

pecl install pcov

The output was:

In file included from /private/tmp/pear/temp/pcov/pcov.c:26:
/opt/homebrew/Cellar/php/8.2.2/include/php/ext/pcre/php_pcre.h:23:10: fatal error: 'pcre2.h' file not found
#include "pcre2.h"

To fix the issue, make sure you have pcre2 installed:

brew install pcre2

After this, create a symlink to the pcre2.h file:

ln -s /opt/homebrew/Cellar/pcre2/10.42/include/pcre2.h /opt/homebrew/Cellar/php/8.2.2/include/php/ext/pcre/pcre2.h

Make sure, to adjust the versions of pcre2 and php (or any other package where you got the error). In my case it’s PHP version 8.2.2 (see the error message) and pcre2 version 10.42.

After the symlink was created, the installation of pcov finished without errors:

Build process completed successfully
Installing '/opt/homebrew/Cellar/php/8.2.2/pecl/20220829/'
install ok: channel://
Extension pcov enabled in php.ini

Foto von Scott Rodgerson auf Unsplash.

PHP: Function utf8_decode() and utf8_encode() have been deprecated

The utf8_encode() and utf8_decode() functions in PHP are used for encoding and decoding strings between ISO-8859-1 (Latin-1) encoding and UTF-8 encoding.

While PHP’s standard library does include utf8_encode and utf8_decode functions, they are limited to converting between ISO-8859-1 (Latin-1) and UTF-8 encodings. It is important to note that these functions cannot be relied upon to detect and convert other character encodings, such as Windows-1252, UTF-16, and UTF-32, to UTF-8. Attempting to use these functions with arbitrary text can introduce bugs that may not produce any warnings or errors, but can result in unexpected and undesired outcomes.

Examples of common bugs that can occur include:

  • The Euro sign (character sequence \xE2\x82\xAC), when passed to utf8_encode function as utf8_encode("€") results in a a garbled (also called as “Mojibake”) text output of â¬.
  • The German Eszett character (ßcharacter sequence \xDF), when passed through utf8_encode("ß") results in Ã.

The utf8_encode and utf8_decode functions have been deprecated in PHP 8.2 due to their misleading function names, lack of error messages and warnings, and their inability to support character encodings other than ISO-8859-1.

As a result, using these functions in PHP 8.2 will emit a deprecation notice. It is recommended to use alternative functions or libraries that provide better support for handling different character encodings. These functions will be removed entirely in PHP 9.0, so it is important to migrate to alternative solutions as soon as possible to avoid compatibility issues in future versions of PHP.


// Function utf8_encode() is deprecated in ... on line ...

// Function uft8_decode() is deprecated in ... on line ...

Replacement for the deprecated functions

Instead, the PHP documentation recommends using the multibyte string functions that are part of the mbstring extension for handling multibyte encodings, including UTF-8. For example, the mb_convert_encoding() function can be used to convert strings between different character encodings, including to and from UTF-8.

Replacement for utf8_encode()

Here is an example of how to use mb_convert_encoding() to encode a string to UTF-8:

$string = "Some string with non-ASCII characters: é, ö, ü";
$utf8_string = mb_convert_encoding($string, 'UTF-8');

Replacement for utf8_decode()

And here is an example of how to use mb_convert_encoding() to decode an UTF-8 string:

$utf8_string = "Some UTF-8 encoded string: é, ö, ü";
$string = mb_convert_encoding($utf8_string, 'ISO-8859-1', 'UTF-8');


PHP: rounding a number and keeping the zeros after comma

In PHP you can use the round() method to round a double. This methods accepts a precision value as second parameter. Some examples:

echo round(3.1415926, 2); // "3.14"
echo round(3.1415926, 3); // "3.142"

When using round() on a value like 3.0000 the conversion to a string will result in just "3":

echo round(3.0000000, 2); // "3"

This is not wrong, but when you want to have a constant precision for different numbers, having an output of "3.00" is much more helpful.

To achieve this, you can use one of the following solutions.


echo number_format(3.1415926, 2); // "3.14"


echo sprintf("%.2f", 3.1415926); // "3.14"

PHP: get version details from composer.json

Let’s say we have a composer.json file as follows:

    "name": "mixable/blog",
    "description": "",
    "homepage": "",
    "version": "4.0.1",
    "type": "project",
    "require": {
        "php": "^8.x",
        "vendor/package": "^4.3",

When using this file to manage the packages of an app, it might be necessary to check for the version of your app. This is possible by using the Composer class \Composer\InstalledVersions. The class provides different methods to access the details of the projects composer.json file.

Get details about the root package

Details about the root package are available through the getRootPackage() method:

$package = \Composer\InstalledVersions::getRootPackage();

This method returns an array with the following details:

name: string
version: string
reference: string
pretty_version: string
aliases: string[]
dev: bool
install_path: string
type: string

To get the apps version, you can use:

$version = \Composer\InstalledVersions::getRootPackage()['version'];

Get details about installed packages

There is a number of methods that provide additional information about the installed packages. Some examples:

Version of an installed package

$version = \Composer\InstalledVersions::getVersion('vendor/package');

Install path of an installed package

$installPath = \Composer\InstalledVersions::getInstallPath('vendor/package');

A detailed description of all methods is available at

Photo by Ilya Pavlov on Unsplash

Adjust text color to be readable on light and dark backgrounds of user interfaces

Most modern user interfaces are supporting different color schemes for day and night: the so called light and dark modes. Selecting a text color for each of those modes is not a big deal and it’s the way to go when designing the user interface.

In some cases, the text color is driven by the displayed contents. In the example below, the tint color is matched to the color of the drink. The global tint color of this app is totally different, but this color adjustment gives a very nice effect. But as you might already see, there is a small problem when it comes to very light or very dark colors: each color either has a good readability on light or dark backgrounds. Some colors might fit to both, but that’s not always the case. In the example below, the light yellow is still visible, but when it comes to small icons or small text, the details are lost.

To overcome this issue, a simple solution is to select two colors for each recipe so that each mode has a different one. That’s fine, but it might totally change the effect of this colored pages.

Can we calculate a suitable color?

Some time ago, there was an article about Black or white text on a colour background? In this one, I described different algorithms to calculate the best text color (black or white) for a colored background. But now, we need the opposite: a colored text that has a good readability on white (light) or black (dark) backgrounds.

When we look at HSL and HSV/HSB color models, we already have a value for ‘lightness’ or ‘brightness’. The idea is to find a color that matches a given hue and saturation and that has a brightness which is readable on light and dark background. For this, we can use different algorithms. Very good results could be achieved with a ‘Weighted W3C Formula‘. This formula take into consideration that the human eye perceives some of the primary colors darker than others.

f'(x) = r ? 0.299 + g ? 0.587 + b ? 0.11

Each color that is located at the border between the black and white overlay is suitable for light and dark backgrounds.

Step 1: convert the given color to HSV/HSB

Step 2: keep hue and saturation constant and adjust the brightness (make the color lighter or darker)

Step 3: convert the HSV/HSB value back to the required color format

Implementation in PHP

A simple calculation for a given RGB color is shown below. The classes used in this snippet are available on GitHub. The code checks the initial brightness of the color and lightens or darkens the values until the ‘border’ calculated by the ‘Weighted W3C Formula’ is reached. This is the case for the value 127, the total range of the brightness is 0 to 255.

$hsv = Convert::rgb2hsv($rgb);

$step = 0.01;
$brightness = Calculate::weightedW3C($rgb);
if ($brightness < 127) {
    while ($brightness < 127 && $hsv[2] >= 0 && $hsv[2] <= 1) {
        $hsv[2] += $step;
        $brightness = Calculate::weightedW3C(Convert::hsv2rgb($hsv));
} else {
    while ($brightness > 127 && $hsv[2] >= 0 && $hsv[2] <= 1) {
        $hsv[2] -= $step;
        $brightness = Calculate::weightedW3C(Convert::hsv2rgb($hsv));

return Convert::hsv2rgb($hsv);

Some examples

But how does this result look for different colors? Let’s start with some dark colors. Those are fine for a light background, but they become unreadable on a dark one. The top colors show the input color (before) and the color below shows the output of the calculation above (after).

Color #632300 adjusted to be readable on light and dark background
Color #454545 adjusted to be readable on light and dark background

And now let’s look at some light colors which are fine for dark backgrounds, but they are totally unreadable on light backgrounds.

Color #73FEFF adjusted to be readable on light and dark background
Color #F0C&96 adjusted to be readable on light and dark background

The last color is similar to the example at the beginning and as you can see, the optimized color has a much better readability. This could be achieved for both light and dark colors. The code example shown above is written in PHP. An adoption should be easily possible for any other coding or scripting language

The algorithm mentioned in this post is also available on GitHub This package is usable with composer:

composer require mixable/color-utils

The optimized color can be calculated with:

use Mixable\Color\Calculate;
// ...

$hex = '#ffcc00';
$optimizedColor = Calculate::readableColorForLightAndDarkBackground($hex);

Enable debugging output in PHPUnit

When running PHPunit there are only dots and letters for each test by default:

To enable debug output and get some more details about the tests running, simply add the logging section to phpunit.xml.dist:

        <log type="testdox-text" target="php://stdout"/>

This will create a debug output and helps to track the tests:

In my case, this helped when my code reached an infinite loop due to an error. This results in a RuntimeException without any outputs or log messages. The process just ended with:

The process has been signaled with signal "11".