Cover of the book Symfony 5: The Fast Track

Symfony 5: The Fast Track is the best book to learn modern Symfony development, from zero to production. +300 pages in full color showing how to combine Symfony with Docker, APIs, queues & async tasks, Webpack, Single-Page Applications, etc.

Buy printed version

New in Symfony 5.0: String Component

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

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

Contributed by
Nicolas Grekas
in #49cf005.

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.

Comments

Forever thank you :) Symfony > PHP.
Awesome!
I tested the String slugger, it is awesomely easy :)
It would be great to be able to restrict the chars used (for instance, generate lower case only strings), maybe in the future?
@Romaric: the future is already the present past :)
$slugger->slug('Стойността трябва', 'bg')->lower();
Great Job
So, Slugger::slug does actually return an object: (Unicode?)String

This means with explicit typing we need to cast it as string before:

$page->setSlug((string)$slug));

??
@Thomas Schulz
Should no be necessary in most cases, this should be done automatically like any other automatic cast with PHP, because String classes implement __toString() magic method that make possible to transform objects into string.
By doing (string) $slug you just force the object to call the __toString() method.
@Nicolas great, I didn't realize it was returning an object. Thanks for the tip :)
I'm in love with this.
Thanks for this great feature. This will make life a lot easier.
Great!
Oh my god, thank you so much!
Do not forget to add "twig/extra-bundle" !

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.