New in Symfony 5.0: String Component
December 19, 2019 • Published by Javier Eguiluz
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
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
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
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.
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
It would be great to be able to restrict the chars used (for instance, generate lower case only strings), maybe in the future?
$slugger->slug('Стойността трябва', 'bg')->lower();
This means with explicit typing we need to cast it as string before:
$page->setSlug((string)$slug));
??
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.