Write Portable code across PHP versions with Symfony Polyfill component
If you want to use str_starts_with in your project, you have to run this project on an environment where PHP version is at least 8.0. The problem is that PHP 7 for example is used in more than 1/3 of the projects on Packagist ecosystem1. So to support as many PHP versions as possible, you should not use that function, right ?
The answer is No. You can still use this function, your code will run on PHP 7 if you are using Symfony’s Polyfill components.
Those components will allow you to write code that will work across PHP versions.
According to Symfony docs :
This project backports features found in the latest PHP versions and provides compatibility layers for some extensions and functions. It is intended to be used when portability across PHP versions and extensions is desired.
In this article, we are going to see one of the Polyfills components in action. We will write a simple script where we will use str_starts_with function, run it on 2 different PHP versions : 8.0 and 7.1 to see if we will have problems (spoiler alert, we will have a problem for 7.1). Then we will introduce our Polyfill component and rerun our script to see its benefit.
Let’s get started !
You need to have git and docker to be able to follow along.
I have created a small GitHub project, so let’s clone it and see what’s within :
git clone https://github.com/zizoujab/polyfill-demo.gitIt’s a simple composer project, nothing special. The two interesting files within the project are src/polyfill-test.php and docker-compose.yaml
#docker-compose.yaml
name: zizoujab
services:
php71:
image: php:7.1-cli
tty: true
volumes:
- .:/app
php80:
image: php:8.0-cli
tty: true
volumes:
- .:/appThanks to docker we can run 2 services, each has its own PHP version, that’s what docker-compose.yaml file will do for us. We will have 2 services : php71 and php80 that will have PHP 7.1 and 8.0 versions respectively.
// src/polyfill-test.php
<?php
require_once 'vendor/autoload.php';
if (str_starts_with("hello world ", "hello"))
echo "Yes\n";
else
echo "NO\n" ;This script will check the existence of the string “hello” within the string “hello world”. The key here is the usage of str_starts_with which is a function available only in PHP 8.0+ : https://www.php.net/manual/en/function.str-starts-with.php
We will run the script polyfill-test.php on 2 different PHP versions and see what output we will be getting.
First, let’s start our services with docker-compose, open a terminal and type this command :
$ docker compose up -d This will start the 2 services defined in docker-compose.yaml, it will do it in the background so if you want to see the logs you have to type : docker compose logs -f
To be sure that the services are up and running, execute this command and check its output :
$ docker compose ps You should have a STATUS column where with two “Up”, indicating that our services are up and running:
Now let’s test our code on PHP 7.1 :
$ docker-compose exec php71 php /app/src/polyfill-test.php
Fatal error: Uncaught Error: Call to undefined function str_starts_with() in /app/src/polyfill-test.php:5
Stack trace:
#0 {main}
thrown in /app/src/polyfill-test.php on line 5We have an exception saying that the function is undefined.
Now let’s try PHP 8.0:
$ docker-compose exec php80 php /app/src/polyfill-test.php
YesOK for 8.0 which makes sense since this function is added in this version.
Now let’s introduce our saviour : symfony/polyfill-php80 , we will require this package with composer :
composer require symfony/polyfill-php80Then re-execute our command for PHP 7.1 :
$ docker-compose exec php71 php /app/src/polyfill-test.php
YesWe don't have the error any more, meaning that our polyfill component added the missing function for PHP 7.1 which is cool.
If you are curious and want to see where this function is added, you chan go to vendor/symfony/polyfill-php80/bootstrap.php, you will find this code :
if (!function_exists('str_starts_with')) {
function str_starts_with(?string $haystack, ?string $needle): bool { return p\Php80::str_starts_with($haystack ?? '', $needle ?? ''); }
}Which checks on the existence of the function if it’s not there, it defines it.
So as a conclusion, Symfony Polyfills components allow us to write code compatible with older PHP buy backporting some functions and extensions.
Now to the questions part :
Answers are : 4, 4, 3
YouTube Video :
GitHub Repo : https://github.com/zizoujab/polyfill-demo
Source : https://stitcher.io/blog/php-version-stats-january-2023






