String
Introduction
The Str class provides a rich collection of static utility methods for working with strings in PHP. It handles everything from case conversion and slug generation to regular expression matching, random token generation, and multibyte-safe character manipulation. All methods are UTF-8 aware unless noted otherwise.
use Slenix\Supports\Helpers\Str;Case Conversion
Str::camel()
Converts a string to camelCase. Results are memoized internally for repeated calls.
Str::camel('foo_bar_baz'); // 'fooBarBaz'
Str::camel('hello-world'); // 'helloWorld'
Str::camel('user full name'); // 'userFullName'Str::studly()
Converts a string to StudlyCase (also known as PascalCase). Results are memoized.
Str::studly('foo_bar'); // 'FooBar'
Str::studly('hello-world'); // 'HelloWorld'Str::snake()
Converts a string to snake_case. An optional second argument sets the delimiter.
Str::snake('FooBarBaz'); // 'foo_bar_baz'
Str::snake('FooBar', '-'); // 'foo-bar'Str::kebab()
Converts a string to kebab-case. Shorthand for Str::snake($value, '-').
Str::kebab('FooBarBaz'); // 'foo-bar-baz'
Str::kebab('hello world'); // 'hello-world'Str::screaming()
Converts a string to SCREAMING_SNAKE_CASE.
Str::screaming('fooBar'); // 'FOO_BAR'
Str::screaming('hello world'); // 'HELLO_WORLD'Str::title()
Converts a string to Title Case using multibyte-safe conversion.
Str::title('hello world'); // 'Hello World'
Str::title('foo bar baz'); // 'Foo Bar Baz'Str::upper() / Str::lower()
Converts the entire string to uppercase or lowercase (multibyte-safe).
Str::upper('hello'); // 'HELLO'
Str::lower('HELLO'); // 'hello'Str::ucfirst() / Str::lcfirst()
Capitalises or lowercases only the first character of the string (multibyte-safe).
Str::ucfirst('hello world'); // 'Hello world'
Str::lcfirst('HELLO WORLD'); // 'hELLO WORLD'Str::swapCase()
Inverts the case of each character.
Str::swapCase('Hello World'); // 'hELLO wORLD'Str::headline()
Converts a string into a human-readable headline, splitting on underscores, hyphens, spaces, and camelCase boundaries.
Str::headline('hello_world_foo'); // 'Hello World Foo'
Str::headline('emailAddress'); // 'Email Address'
Str::headline('user-profile-page'); // 'User Profile Page'Slugs & URLs
Str::slug()
Generates a URL-friendly slug from the given string. Handles accented characters via transliteration.
Str::slug('Olá, Mundo!'); // 'ola-mundo'
Str::slug('Hello World'); // 'hello-world'
Str::slug('Hello World', '_'); // 'hello_world'Str::unslug()
Converts a slug back to a human-readable title.
Str::unslug('foo-bar-baz'); // 'Foo Bar Baz'
Str::unslug('hello_world', '_'); // 'Hello World'Truncation & Padding
Str::limit()
Truncates a string to the specified number of characters, appending a suffix.
Str::limit('Hello, World!', 7); // 'Hello, ...'
Str::limit('Hello, World!', 7, ' [...]'); // 'Hello, [...]'Str::words()
Truncates a string to the specified number of words.
Str::words('Hello beautiful World', 2); // 'Hello beautiful...'
Str::words('One two three four', 3, ' →'); // 'One two three →'Str::truncate()
Truncates at the nearest word boundary so words are not cut mid-way.
Str::truncate('The quick brown fox jumps', 15); // 'The quick...'
Str::truncate('The quick brown fox jumps', 15, ' →'); // 'The quick →'Str::padLeft() / Str::padRight() / Str::padBoth()
Pads a string to the given total length.
Str::padLeft('42', 5, '0'); // '00042'
Str::padRight('Hi', 6, '.'); // 'Hi....'
Str::padBoth('Hi', 8, '-'); // '---Hi---'Search & Verification
Str::contains()
Checks whether a string contains a substring or any value from an array. Optionally case-insensitive.
Str::contains('Hello World', 'World'); // true
Str::contains('Hello World', ['Earth', 'World']); // true
Str::contains('Hello World', 'world', true); // true (case-insensitive)Str::containsAll()
Returns true only if the string contains all of the given needles.
Str::containsAll('Hello World', ['Hello', 'World']); // true
Str::containsAll('Hello World', ['Hello', 'Earth']); // falseStr::startsWith()
Checks whether the string begins with a given value or any value from an array.
Str::startsWith('Hello World', 'Hello'); // true
Str::startsWith('/api/users', ['/api', '/v1']); // trueStr::endsWith()
Checks whether the string ends with a given value or any value from an array.
Str::endsWith('image.png', '.png'); // true
Str::endsWith('file.jpg', ['.png', '.jpg']); // trueStr::is()
Checks whether the string matches a pattern. Supports the * wildcard.
Str::is('*.php', 'index.php'); // true
Str::is('/api/*', '/api/users'); // true
Str::is(['*.jpg', '*.png'], 'photo.png'); // trueStr::isEmpty() / Str::isNotEmpty()
Checks whether the string is blank (empty or whitespace-only).
Str::isEmpty(' '); // true
Str::isEmpty('hello'); // false
Str::isNotEmpty('hi'); // trueStr::isEmail()
Returns true if the string is a syntactically valid email address.
Str::isEmail('user@example.com'); // true
Str::isEmail('not-an-email'); // falseStr::isUrl()
Returns true if the string is a valid URL.
Str::isUrl('https://example.com'); // true
Str::isUrl('example.com'); // falseStr::isAlpha()
Returns true if the string contains only Unicode letters.
Str::isAlpha('Hello'); // true
Str::isAlpha('Hello1'); // falseStr::isAlphaNum()
Returns true if the string contains only Unicode letters and digits.
Str::isAlphaNum('Hello123'); // true
Str::isAlphaNum('Hello!'); // falseStr::isNumeric()
Returns true if the string represents a numeric value.
Str::isNumeric('42'); // true
Str::isNumeric('3.14'); // true
Str::isNumeric('12abc'); // falseStr::isJson()
Returns true if the string is valid JSON.
Str::isJson('{"name":"Claudio"}'); // true
Str::isJson('not json'); // falseStr::isUuid()
Returns true if the string is a valid UUID v4.
Str::isUuid('f47ac10b-58cc-4372-a567-0e02b2c3d479'); // true
Str::isUuid('not-a-uuid'); // falseExtraction
Str::before() / Str::beforeLast()
Returns the portion of the string before the first or last occurrence of the search value.
Str::before('foo@bar.com', '@'); // 'foo'
Str::beforeLast('images/2025/photo.jpg', '/'); // 'images/2025'Str::after() / Str::afterLast()
Returns the portion of the string after the first or last occurrence of the search value.
Str::after('foo@bar.com', '@'); // 'bar.com'
Str::afterLast('images/2025/photo.jpg', '/'); // 'photo.jpg'Str::between()
Returns the substring found between two values.
Str::between('<b>text</b>', '<b>', '</b>'); // 'text'
Str::between('[value]', '[', ']'); // 'value'Str::betweenAll()
Returns an array of all substrings found between two values.
Str::betweenAll('<b>one</b> and <b>two</b>', '<b>', '</b>');
// ['one', 'two']Str::charAt()
Returns the character at the specified index. Supports negative indices (counted from the end).
Str::charAt('Hello', 0); // 'H'
Str::charAt('Hello', -1); // 'o'Str::take()
Returns the first N characters of the string.
Str::take('Hello World', 5); // 'Hello'Str::position()
Returns the position of the first occurrence of a substring, or false if not found.
Str::position('Hello World', 'World'); // 6
Str::position('Hello World', 'missing'); // falseReplacement & Manipulation
Str::replaceFirst()
Replaces only the first occurrence of a search string.
Str::replaceFirst('bar', 'baz', 'bar bar bar'); // 'baz bar bar'Str::replaceLast()
Replaces only the last occurrence of a search string.
Str::replaceLast('bar', 'baz', 'bar bar bar'); // 'bar bar baz'Str::remove()
Removes all occurrences of a string or array of strings. Optionally case-insensitive.
Str::remove('!', 'Hello!'); // 'Hello'
Str::remove(['a', 'e'], 'banane'); // 'bnn'
Str::remove('hello', 'Hello World', false); // ' World' (case-insensitive)Str::swap()
Replaces multiple search values simultaneously using an associative array.
Str::swap(['{name}' => 'Claudio', '{lang}' => 'PHP'], 'Hello {name}, you use {lang}!');
// 'Hello Claudio, you use PHP!'Str::start()
Prepends the prefix to the string, but only if it is not already present.
Str::start('foo', '/'); // '/foo'
Str::start('/foo', '/'); // '/foo'Str::finish()
Appends the suffix to the string, but only if it is not already present.
Str::finish('path', '/'); // 'path/'
Str::finish('path/', '/'); // 'path/'Str::stripStart() / Str::stripEnd()
Removes a prefix or suffix from the string if present.
Str::stripStart('/foo/bar', '/'); // 'foo/bar'
Str::stripEnd('file.php', '.php'); // 'file'Str::wrap()
Wraps the string with a prefix and an optional suffix.
Str::wrap('world', 'Hello ', '!'); // 'Hello world!'
Str::wrap('value', '"'); // '"value"'Str::unwrap()
Removes a wrapping prefix and suffix if both are present.
Str::unwrap('"value"', '"'); // 'value'
Str::unwrap('<b>text</b>', '<b>', '</b>'); // 'text'Str::repeat()
Repeats the string N times.
Str::repeat('ab', 3); // 'ababab'Str::reverse()
Reverses the string, correctly handling multibyte characters.
Str::reverse('Hello'); // 'olleH'
Str::reverse('Olá'); // 'álO'Str::squish()
Trims the string and collapses all internal whitespace sequences into a single space.
Str::squish(' Hello World '); // 'Hello World'
Str::squish("line\n\nbreak"); // 'line break'Splitting & Joining
Str::explode()
Splits a string by a separator, with an optional limit.
Str::explode(',', 'a,b,c'); // ['a', 'b', 'c']
Str::explode(',', 'a,b,c', 2); // ['a', 'b,c']Str::splitBy()
Splits a string using a regular expression pattern. Empty parts are discarded.
Str::splitBy('one1two2three', '/\d/'); // ['one', 'two', 'three']Str::chunk()
Splits the string into an array of fixed-size character groups.
Str::chunk('Hello', 2); // ['He', 'll', 'o']
Str::chunk('Hello'); // ['H', 'e', 'l', 'l', 'o']Str::lines()
Splits the string into an array of lines, handling \r\n, \r, and \n.
Str::lines("line1\nline2\r\nline3"); // ['line1', 'line2', 'line3']Str::split()
Splits the string into an array of individual characters (multibyte-safe).
Str::split('Hello'); // ['H', 'e', 'l', 'l', 'o']
Str::split('Olá', 1); // ['O', 'l', 'á']Formatting
Str::number()
Formats a numeric value as a human-readable string with custom decimal and thousands separators.
Str::number(1234567.891, 2); // '1.234.567,89'
Str::number(1234567.891, 2, '.', ','); // '1,234,567.89'Str::fileSize()
Converts a byte count to a human-readable size string.
Str::fileSize(1024); // '1 KB'
Str::fileSize(1048576); // '1 MB'
Str::fileSize(1536, 1); // '1.5 KB'Str::mask()
Replaces a segment of the string with a repeating mask character.
Str::mask('joao@email.com', '*', 2, 8); // 'jo********mail.com'
Str::mask('4111111111111111', '*', 0, 12); // '************1111'Str::plural()
Returns the singular or plural form of a word based on a count. Includes basic Portuguese irregular nouns and common suffix rules.
Str::plural('user', 1); // 'user'
Str::plural('user', 2); // 'users'
Str::plural('pão', 3); // 'pães'
// Custom irregulars
Str::plural('child', 2, ['child' => 'children']); // 'children'Str::pluralStudly()
Returns the count followed by the correctly inflected word.
Str::pluralStudly('User', 1); // '1 User'
Str::pluralStudly('User', 3); // '3 Users'Str::interpolate()
Replaces :placeholder tokens in a template string.
Str::interpolate('Hello, :name! You are :age years old.', [
'name' => 'Claudio',
'age' => 30,
]);
// 'Hello, Claudio! You are 30 years old.'Str::format()
Replaces {key} tokens in a template string.
Str::format('Hello {name}, you use {lang}!', [
'name' => 'Claudio',
'lang' => 'PHP',
]);
// 'Hello Claudio, you use PHP!'Str::fmt()
Replaces positional {0}, {1}, etc. tokens with the provided arguments.
Str::fmt('Hello {0}, you are {1} years old.', 'Claudio', 30);
// 'Hello Claudio, you are 30 years old.'Generation
Str::uuid()
Generates a random UUID v4.
Str::uuid(); // 'f47ac10b-58cc-4372-a567-0e02b2c3d479'Str::random()
Generates a random alphanumeric string of the specified length using a cryptographically secure source.
Str::random(); // 16-character string, e.g. 'A3kLmN9pQrTuVwXy'
Str::random(32); // 32-character stringStr::token()
Generates a URL-safe base64 token of the specified length. Useful for email verification links, API keys, and similar tokens.
Str::token(); // 40-character URL-safe token
Str::token(64); // 64-character URL-safe tokenStr::ulid()
Generates a ULID (Universally Unique Lexicographically Sortable Identifier). ULIDs are sortable by creation time, making them a useful alternative to UUIDs for database primary keys.
Str::ulid(); // '01ARYZ6S41TPTWF1BGDD2ZST9N'Str::password()
Generates a random password with configurable character sets.
Str::password(); // 16 chars, all sets enabled
Str::password(24); // 24 chars
Str::password(16, letters: true, numbers: true, symbols: false, uppercase: true);Encoding & Sanitisation
Str::escape()
Escapes HTML special characters to prevent XSS.
Str::escape('<script>alert(1)</script>');
// '<script>alert(1)</script>'Str::unescape()
Reverts HTML entity escaping.
Str::unescape('<b>Hello</b>'); // '<b>Hello</b>'Str::encodeUrl() / Str::decodeUrl()
Percent-encodes and decodes a string for use in a URL.
Str::encodeUrl('hello world!'); // 'hello%20world%21'
Str::decodeUrl('hello%20world%21'); // 'hello world!'Str::base64Encode() / Str::base64Decode()
Encodes and decodes using URL-safe base64 (replaces +, /, and strips = padding).
$encoded = Str::base64Encode('secret data');
$decoded = Str::base64Decode($encoded); // 'secret data'Str::stripTags()
Removes HTML tags from the string, with an optional allowlist.
Str::stripTags('<p>Hello <b>World</b></p>'); // 'Hello World'
Str::stripTags('<p>Hello <b>World</b></p>', '<b>'); // 'Hello <b>World</b>'Str::trim()
Trims characters from both sides of the string.
Str::trim(' Hello '); // 'Hello'
Str::trim('***Hello***', '*'); // 'Hello'Str::normalizeLineEndings()
Normalises all line endings (\r\n, \r) to Unix-style \n.
Str::normalizeLineEndings("line1\r\nline2\rline3");
// "line1\nline2\nline3"Str::decodeHtml()
Converts HTML entities back to their character equivalents.
Str::decodeHtml('"Hello" & 'World'');
// '"Hello" & \'World\''Metrics
Str::length()
Returns the number of characters in the string (multibyte-safe).
Str::length('Hello'); // 5
Str::length('Olá'); // 3Str::substrCount()
Returns the number of times a substring appears in the string.
Str::substrCount('banana', 'an'); // 2Str::wordCount()
Returns the number of words in the string.
Str::wordCount('Hello beautiful World'); // 3Str::similarity()
Returns a float between 0.0 and 1.0 representing how similar two strings are.
Str::similarity('Hello', 'Hello'); // 1.0
Str::similarity('Hello', 'World'); // 0.2222Str::levenshtein()
Returns the Levenshtein distance between two strings — the minimum number of single-character edits required to change one string into the other.
Str::levenshtein('kitten', 'sitting'); // 3
Str::levenshtein('hello', 'hello'); // 0Advanced Utilities
Str::pipe()
Passes the string through one or more callbacks in sequence.
Str::pipe(' hello world ', 'trim', 'strtoupper'); // 'HELLO WORLD'
Str::pipe('hello-world', fn($s) => Str::studly($s), fn($s) => Str::lower($s));
// 'helloworld'Str::when()
Applies a callback to the string only when the condition is true.
Str::when('hello', true, fn($s) => strtoupper($s)); // 'HELLO'
Str::when('hello', false, fn($s) => strtoupper($s)); // 'hello'Str::unless()
Applies a callback to the string only when the condition is false.
Str::unless('hello', false, fn($s) => strtoupper($s)); // 'HELLO'
Str::unless('hello', true, fn($s) => strtoupper($s)); // 'hello'Str::match()
Returns the first capturing group of a regex match, or the full match if there are no groups.
Str::match('/\d+/', 'Order #42'); // '42'
Str::match('/user-(\d+)/', 'user-99'); // '99'Str::matchAll()
Returns an array of all capturing group matches, or full matches if there are no groups.
Str::matchAll('/\d+/', 'a1 b22 c333'); // ['1', '22', '333']
Str::matchAll('/<b>(.*?)<\/b>/', '<b>a</b> <b>b</b>'); // ['a', 'b']Str::test()
Returns true if the string matches a regular expression.
Str::test('/^\d+$/', '12345'); // true
Str::test('/^\d+$/', '123ab'); // falseStr::equals()
Compares two strings in constant time, preventing timing attacks. Use this when comparing secrets, tokens, or hashes.
Str::equals($userToken, $storedToken); // true or falseStr::hash()
Hashes a string using the specified algorithm, returning a prefixed string of the form algorithm:hash.
Str::hash('my-value'); // 'sha256:abc123...'
Str::hash('my-value', 'md5'); // 'md5:5d41402abc4b2a76b9719d911017c592'Str::flushCache()
Clears the internal memoization cache for camel(), studly(), and snake(). Rarely needed in normal usage.
Str::flushCache();Quick Reference
| Method | Summary |
|---|---|
camel(value) | Convert to camelCase |
studly(value) | Convert to StudlyCase |
snake(value, delimiter?) | Convert to snake_case |
kebab(value) | Convert to kebab-case |
screaming(value) | Convert to SCREAMINGSNAKECASE |
title(value) | Convert to Title Case |
upper(value) | Convert to UPPERCASE |
lower(value) | Convert to lowercase |
ucfirst(value) | Capitalise first character |
lcfirst(value) | Lowercase first character |
swapCase(value) | Invert each character's case |
headline(value) | Human-readable headline from any format |
slug(value, sep?, lang?) | Generate URL-friendly slug |
unslug(value, sep?) | Convert slug back to title |
limit(value, limit, end?) | Truncate by character count |
words(value, words, end?) | Truncate by word count |
truncate(value, length, end?) | Truncate at word boundary |
padLeft(value, length, pad?) | Left-pad to length |
padRight(value, length, pad?) | Right-pad to length |
padBoth(value, length, pad?) | Centre-pad to length |
contains(haystack, needles, ci?) | Check for substring presence |
containsAll(haystack, needles, ci?) | Check all substrings are present |
startsWith(haystack, needles) | Check for prefix |
endsWith(haystack, needles) | Check for suffix |
is(pattern, value) | Wildcard pattern matching |
isEmpty(value) | True if blank |
isNotEmpty(value) | True if not blank |
isEmail(value) | Validate email format |
isUrl(value) | Validate URL format |
isAlpha(value) | Check letters only |
isAlphaNum(value) | Check letters and digits only |
isNumeric(value) | Check numeric value |
isJson(value) | Check valid JSON |
isUuid(value) | Check valid UUID v4 |
before(subject, search) | Get text before first match |
beforeLast(subject, search) | Get text before last match |
after(subject, search) | Get text after first match |
afterLast(subject, search) | Get text after last match |
between(subject, from, to) | Get text between two values |
betweenAll(subject, from, to) | Get all occurrences between two values |
charAt(value, index) | Get character at index |
take(value, limit) | Get first N characters |
position(haystack, needle, offset?) | Find substring position |
replaceFirst(search, replace, subject) | Replace first occurrence |
replaceLast(search, replace, subject) | Replace last occurrence |
remove(search, subject, cs?) | Remove all occurrences |
swap(map, subject) | Replace multiple values at once |
start(value, prefix) | Ensure prefix is present |
finish(value, cap) | Ensure suffix is present |
stripStart(value, prefix) | Remove prefix if present |
stripEnd(value, suffix) | Remove suffix if present |
wrap(value, before, after?) | Wrap with prefix and suffix |
unwrap(value, before, after?) | Remove wrapping |
repeat(value, times) | Repeat string N times |
reverse(value) | Reverse string |
squish(value) | Collapse whitespace |
explode(sep, value, limit?) | Split by separator |
splitBy(value, pattern) | Split by regex |
chunk(value, size?) | Split into character chunks |
lines(value) | Split into lines |
split(value, chunkSize?) | Split into character array |
number(number, dec?, dp?, ts?) | Format number as string |
fileSize(bytes, precision?) | Format bytes as human-readable size |
mask(string, char, index, length?) | Mask part of a string |
plural(value, count, irregulars?) | Pluralise word |
pluralStudly(value, count) | Pluralise with count prefix |
interpolate(template, replacements, prefix?) | Replace :placeholder tokens |
format(template, data) | Replace {key} tokens |
fmt(template, ...args) | Replace {0}, {1} tokens |
uuid() | Generate UUID v4 |
random(length?) | Generate random alphanumeric string |
token(length?) | Generate URL-safe token |
ulid() | Generate sortable ULID |
password(length?, ...) | Generate random password |
escape(value) | Escape HTML special characters |
unescape(value) | Unescape HTML entities |
encodeUrl(value) | Percent-encode for URL |
decodeUrl(value) | Decode percent-encoded URL |
base64Encode(value) | URL-safe base64 encode |
base64Decode(value) | URL-safe base64 decode |
stripTags(value, allowed?) | Remove HTML tags |
trim(value, characters?) | Trim characters |
normalizeLineEndings(value) | Normalise line endings to \n |
decodeHtml(value) | Decode HTML entities |
length(value) | Character count (multibyte) |
substrCount(haystack, needle) | Count substring occurrences |
wordCount(value) | Count words |
similarity(a, b) | String similarity score (0.0–1.0) |
levenshtein(a, b) | Edit distance between two strings |
pipe(value, ...callbacks) | Apply callbacks in sequence |
when(value, condition, callback) | Conditionally apply callback |
unless(value, condition, callback) | Apply callback when condition is false |
match(pattern, subject) | First regex match |
matchAll(pattern, subject) | All regex matches |
test(pattern, subject) | Test regex match |
equals(a, b) | Constant-time string comparison |
hash(value, algorithm?) | Hash string with algorithm prefix |
flushCache() | Clear memoization cache |