Don't use substr Posted in Tips on Apr 11, 2021.

Luke Towers

If you're trying to trim a string to a specified length within a Winter CMS (or even just plain Laravel) project, don't use substr().

It doesn't support multibyte characters (such as unicode and emojis), and while you're unlikely to test with multibyte characters; users have a funny way of using emojis all over the place. This can cause additional headaches beyond just mangling emojis on display, since using substr() on a multibyte string will cause it to mangle the string, and then PHP will internally change the type of the string to a binary string (represented by being prefixed with a b when dumping the string, so it becomes b"""string content""" instead of just "string content"). Once you've got a binary string on your hands, you're primed and ready to have all sorts of other problems.

The biggest of these potential problems would probably be that json_encode() will fail with "Malformed UTF-8 characters, possibly incorrectly encoded" if it encounters a binary string. This is then made even more difficult to debug if you are returning this malformed string in an AJAX response, as the response object has to be JSON encoded before being passed to the underlying Symfony Request object; and prior to Laravel 8.34.1 the exception thrown would simply be that $request->setContent() doesn't allow booleans, which doesn't make sense; until you realize that json_encode() will return false if it fails by default.

Long story short, don't use substr. Use Str::limit($string, $length, [$appends]) if you're trying to limit the length of a string, and Str::substr($string, $start, $end) for any other use of substr(). These methods are multibyte aware and will be a lot cleaner and more readable than throwing mb_substr($string, $start, $end, 'UTF-8'); all over the place in your codebase.

Keep informed

Sign up to our newsletter to receive updates on Winter CMS releases, new features in the works, and much more.
We'll never spam or give this address away.

Latest blog post

Winter: 16 Months Later

Published July 14, 2022
With the first year of Winter behind us, let's take a look at what we were able to achieve in 2021.

View this post Read all posts

Latest Winter CMS release

v1.2.1

Released October 20, 2022
14 UX/UI Improvements, 25 API Changes, 33 Bug Fixes, 4 Security Improvements, 5 Translation Improvements, 1 Performance Improvement, 2 Community Improvements, 2 Dependencies, 0 New Contributors * @cstorus made their first contribution in https://github.com/wintercms/winter/pull/616 * @simonmannsfeld made their first contribution in https://github.com/wintercms/winter/pull/623 * @quangtrongonline made their first contribution in https://github.com/wintercms/winter/pull/636 * @nathanlesage made their first contribution in https://github.com/wintercms/winter/pull/665 * @vllvll made their first contribution in https://github.com/wintercms/winter/pull/669 * @robertalexa made their first contribution in https://github.com/wintercms/winter/pull/668 * @iamyigitkoc made their first contribution in https://github.com/wintercms/winter/pull/624 * @hecc127 made their first contribution in https://github.com/wintercms/winter/pull/682 * @prsuhas made their first contribution in https://github.com/wintercms/winter/pull/723

View details View all releases