Nicolas Grekas Hugo Hamon Gregor Harlan
Contributed by Nicolas Grekas , Hugo Hamon and Gregor Harlan in #33553

Symfony 5.0 was released on November 21, 2019. Unlike Symfony 4.0, it doesn't completely change any directory structures or add any ground-breaking new way of developing. Instead, Symfony 5 builds on top of the shoulders of Symfony 4 and provides new features to make life easier.

According to the Symfony release process, Symfony 5.0 has all the new features introduced in Symfony 4.4. Check out the New in Symfony 4.4 series to learn about all these great features. In addition, Symfony 5.0 adds some exclusive features which are not available in Symfony 4.4. This blog post introduces one of those features: the new String component.

Working with strings is difficult

Languages like English require a very limited set of characters and symbols to display any content. However, other languages require thousands of symbols to display their contents. They need complex encoding standards such as Unicode and you have to deal with "code points", "grapheme clusters" and "bytes". Read the String component documentation for an introduction about those terms.

The String component abstracts that complexity and provides three simple classes to create any strings according to your needs:

1
2
3
4
5
6
7
8
9
10
use Symfony\Component\String\ByteString;
use Symfony\Component\String\CodePointString;
use Symfony\Component\String\UnicodeString;

$content = new CodePointString('Hello world');
$content = new UnicodeString('नमस्ते दुनिया');
$content = new ByteString('さよなら');

$content = (new CodePointString('hello'))->toUnicodeString();
$content = UnicodeString::fromCodePoints(0x68, 0x65, 0x6C, 0x6C, 0x6F)->toByteString();

The component also provides some shortcut functions to quickly create strings:

1
2
3
4
5
6
7
8
9
10
use function Symfony\Component\String\b;
use function Symfony\Component\String\u;

// both are equivalent
$content = b('hello');
$content = new ByteString('hello');

// both are equivalent
$content = u('hello');
$content = new UnicodeString('hello');

Object-oriented strings

Creating strings is only the first step. This component also provides a carefully crafted API to work with strings in an object-oriented fashion. This API can make your code much more readable. See for example how to check if a string ends with another substring:

1
2
3
4
5
6
7
8
9
// using PHP functions
if ('.html' === substr($theString, -strlen('.html'))) {
    // ...
}

// using Symfony's String
if (u($theString)->endsWith('.html')) {
    // ...
}

You can chain all the methods to perform advanced string transformations (and with the certainty that it will work for any string in any language and any script):

1
2
3
4
5
$text =u('This is a déjà-vu situation.')
    ->trimEnd('.')
    ->replace('déjà-vu', 'jamais-vu')
    ->append('!');
// $text = 'This is a jamais-vu situation!'

If you work with strings regularly, the String component is a dream come true. The component provides tens of methods to solve all your needs related to string search, replace, append, prepend, pad, trim, split, truncate, etc.

Some of those methods solve remarkably complex problems. Imagine that your application supports different languages and you need to do case-insensitive comparisons. Applying strtolower() or mb_strtolower() before making the comparison won't work for some languages. Why? Because languages define three cases (lower, upper, title), some characters have no case, case is context-sensitive and locale-sensitive, etc.

Symfony abstracts this mind-blowing complexity into a single method called folded() which always returns the right value to do case-insensitive comparisons:

1
2
u('FOO Bar')->folded();             // 'foo bar'
u('Die O\'Brian Straße')->folded(); // "die o'brian strasse"

Take a moment to check out the String component method reference and you'll want to start using it in your projects right away!

String Slugger

Titouan Galopin
Contributed by Titouan Galopin in #33768

Sluggers are a popular need for many applications. They take any string and transform them into another string which can be used safely in places where not all Unicode characters are allowed (URLs, file or directory names, etc.)

The String component includes an AsciiSlugger() that transforms and transliterates any string into another ASCII-only string:

1
2
3
4
5
6
7
use Symfony\Component\String\Slugger\AsciiSlugger;

$slugger = new AsciiSlugger();
$slugger->slug('Стойността трябва', '-', 'bg');  // 'Stoinostta-tryabva'
$slugger->slug('Αυτή η τιμή πρέπει', '-', 'el'); // 'Avti-i-timi-prepi'
$slugger->slug('该变量的值应为', '-', 'zh');       // 'gai-bian-liang-de-zhi-ying-wei'
$slugger->slug('Wôrķšƥáçè sèťtïñğš');            // 'Workspace-settings'

This slugger provides seamless integration with the Symfony framework, so you can autowire it in your services, it auto-detects the current locale, etc.

Twig Integration

Nicolas Grekas
Contributed by Nicolas Grekas

Sometimes you need to handle strings in templates too. That's why Twig 2.12.1 added a new filter called u which wraps the given content into a UnicodeString class so you have access to all String methods:

1
2
3
4
5
{{ 'Lorem ipsum'|u.truncate(8, '...') }}
{# prints: Lorem... #}

{{ 'SymfonyStringWithTwig'|u.snake }}
{# prints: symfony_string_with_twig #}

This filter is part of the StringExtension which is not installed by default. Install it first with composer require twig/string-extra and read the documentation of the "u" filter.

String Component Compatibility

The String component has been introduced as a Symfony experimental feature in Symfony 5.0. This means that it's stable enough to use it in production, but its public API could change a bit before freezing it in Symfony 5.1.

Experimental features can't be introduced in long-term support versions. That's why it was introduced in Symfony 5.0 instead of Symfony 4.4. In any case, you don't have to upgrade to Symfony 5 to use this component. The String component is ready to be used in any PHP 7.2.5 or higher application.

Published in #Living on the edge