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.

php
use Slenix\Supports\Helpers\Str;

Case Conversion

Str::camel()

Converts a string to camelCase. Results are memoized internally for repeated calls.

php
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.

php
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.

php
Str::snake('FooBarBaz');          // 'foo_bar_baz'
Str::snake('FooBar', '-');        // 'foo-bar'

Str::kebab()

Converts a string to kebab-case. Shorthand for Str::snake($value, '-').

php
Str::kebab('FooBarBaz');   // 'foo-bar-baz'
Str::kebab('hello world'); // 'hello-world'

Str::screaming()

Converts a string to SCREAMING_SNAKE_CASE.

php
Str::screaming('fooBar');      // 'FOO_BAR'
Str::screaming('hello world'); // 'HELLO_WORLD'

Str::title()

Converts a string to Title Case using multibyte-safe conversion.

php
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).

php
Str::upper('hello');   // 'HELLO'
Str::lower('HELLO');   // 'hello'

Str::ucfirst() / Str::lcfirst()

Capitalises or lowercases only the first character of the string (multibyte-safe).

php
Str::ucfirst('hello world');   // 'Hello world'
Str::lcfirst('HELLO WORLD');   // 'hELLO WORLD'

Str::swapCase()

Inverts the case of each character.

php
Str::swapCase('Hello World');   // 'hELLO wORLD'

Str::headline()

Converts a string into a human-readable headline, splitting on underscores, hyphens, spaces, and camelCase boundaries.

php
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.

php
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.

php
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.

php
Str::limit('Hello, World!', 7);           // 'Hello, ...'
Str::limit('Hello, World!', 7, ' [...]'); // 'Hello,  [...]'

Str::words()

Truncates a string to the specified number of words.

php
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.

php
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.

php
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.

php
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.

php
Str::containsAll('Hello World', ['Hello', 'World']); // true
Str::containsAll('Hello World', ['Hello', 'Earth']); // false

Str::startsWith()

Checks whether the string begins with a given value or any value from an array.

php
Str::startsWith('Hello World', 'Hello');            // true
Str::startsWith('/api/users', ['/api', '/v1']);     // true

Str::endsWith()

Checks whether the string ends with a given value or any value from an array.

php
Str::endsWith('image.png', '.png');             // true
Str::endsWith('file.jpg', ['.png', '.jpg']);    // true

Str::is()

Checks whether the string matches a pattern. Supports the * wildcard.

php
Str::is('*.php', 'index.php');      // true
Str::is('/api/*', '/api/users');    // true
Str::is(['*.jpg', '*.png'], 'photo.png'); // true

Str::isEmpty() / Str::isNotEmpty()

Checks whether the string is blank (empty or whitespace-only).

php
Str::isEmpty('   ');     // true
Str::isEmpty('hello');   // false
Str::isNotEmpty('hi');   // true

Str::isEmail()

Returns true if the string is a syntactically valid email address.

php
Str::isEmail('user@example.com');   // true
Str::isEmail('not-an-email');       // false

Str::isUrl()

Returns true if the string is a valid URL.

php
Str::isUrl('https://example.com');   // true
Str::isUrl('example.com');           // false

Str::isAlpha()

Returns true if the string contains only Unicode letters.

php
Str::isAlpha('Hello');     // true
Str::isAlpha('Hello1');    // false

Str::isAlphaNum()

Returns true if the string contains only Unicode letters and digits.

php
Str::isAlphaNum('Hello123');   // true
Str::isAlphaNum('Hello!');     // false

Str::isNumeric()

Returns true if the string represents a numeric value.

php
Str::isNumeric('42');       // true
Str::isNumeric('3.14');     // true
Str::isNumeric('12abc');    // false

Str::isJson()

Returns true if the string is valid JSON.

php
Str::isJson('{"name":"Claudio"}');   // true
Str::isJson('not json');             // false

Str::isUuid()

Returns true if the string is a valid UUID v4.

php
Str::isUuid('f47ac10b-58cc-4372-a567-0e02b2c3d479');   // true
Str::isUuid('not-a-uuid');                              // false

Extraction

Str::before() / Str::beforeLast()

Returns the portion of the string before the first or last occurrence of the search value.

php
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.

php
Str::after('foo@bar.com', '@');       // 'bar.com'
Str::afterLast('images/2025/photo.jpg', '/'); // 'photo.jpg'

Str::between()

Returns the substring found between two values.

php
Str::between('<b>text</b>', '<b>', '</b>');   // 'text'
Str::between('[value]', '[', ']');            // 'value'

Str::betweenAll()

Returns an array of all substrings found between two values.

php
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).

php
Str::charAt('Hello', 0);    // 'H'
Str::charAt('Hello', -1);   // 'o'

Str::take()

Returns the first N characters of the string.

php
Str::take('Hello World', 5);   // 'Hello'

Str::position()

Returns the position of the first occurrence of a substring, or false if not found.

php
Str::position('Hello World', 'World');    // 6
Str::position('Hello World', 'missing'); // false

Replacement & Manipulation

Str::replaceFirst()

Replaces only the first occurrence of a search string.

php
Str::replaceFirst('bar', 'baz', 'bar bar bar');   // 'baz bar bar'

Str::replaceLast()

Replaces only the last occurrence of a search string.

php
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.

php
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.

php
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.

php
Str::start('foo', '/');    // '/foo'
Str::start('/foo', '/');   // '/foo'

Str::finish()

Appends the suffix to the string, but only if it is not already present.

php
Str::finish('path', '/');    // 'path/'
Str::finish('path/', '/');   // 'path/'

Str::stripStart() / Str::stripEnd()

Removes a prefix or suffix from the string if present.

php
Str::stripStart('/foo/bar', '/');   // 'foo/bar'
Str::stripEnd('file.php', '.php');  // 'file'

Str::wrap()

Wraps the string with a prefix and an optional suffix.

php
Str::wrap('world', 'Hello ', '!');   // 'Hello world!'
Str::wrap('value', '"');             // '"value"'

Str::unwrap()

Removes a wrapping prefix and suffix if both are present.

php
Str::unwrap('"value"', '"');         // 'value'
Str::unwrap('<b>text</b>', '<b>', '</b>'); // 'text'

Str::repeat()

Repeats the string N times.

php
Str::repeat('ab', 3);   // 'ababab'

Str::reverse()

Reverses the string, correctly handling multibyte characters.

php
Str::reverse('Hello');    // 'olleH'
Str::reverse('Olá');      // 'álO'

Str::squish()

Trims the string and collapses all internal whitespace sequences into a single space.

php
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.

php
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.

php
Str::splitBy('one1two2three', '/\d/');   // ['one', 'two', 'three']

Str::chunk()

Splits the string into an array of fixed-size character groups.

php
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.

php
Str::lines("line1\nline2\r\nline3");   // ['line1', 'line2', 'line3']

Str::split()

Splits the string into an array of individual characters (multibyte-safe).

php
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.

php
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.

php
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.

php
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.

php
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.

php
Str::pluralStudly('User', 1);   // '1 User'
Str::pluralStudly('User', 3);   // '3 Users'

Str::interpolate()

Replaces :placeholder tokens in a template string.

php
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.

php
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.

php
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.

php
Str::uuid();   // 'f47ac10b-58cc-4372-a567-0e02b2c3d479'

Str::random()

Generates a random alphanumeric string of the specified length using a cryptographically secure source.

php
Str::random();      // 16-character string, e.g. 'A3kLmN9pQrTuVwXy'
Str::random(32);    // 32-character string

Str::token()

Generates a URL-safe base64 token of the specified length. Useful for email verification links, API keys, and similar tokens.

php
Str::token();      // 40-character URL-safe token
Str::token(64);    // 64-character URL-safe token

Str::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.

php
Str::ulid();   // '01ARYZ6S41TPTWF1BGDD2ZST9N'

Str::password()

Generates a random password with configurable character sets.

php
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.

php
Str::escape('<script>alert(1)</script>');
// '&lt;script&gt;alert(1)&lt;/script&gt;'

Str::unescape()

Reverts HTML entity escaping.

php
Str::unescape('&lt;b&gt;Hello&lt;/b&gt;');   // '<b>Hello</b>'

Str::encodeUrl() / Str::decodeUrl()

Percent-encodes and decodes a string for use in a URL.

php
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).

php
$encoded = Str::base64Encode('secret data');
$decoded = Str::base64Decode($encoded);   // 'secret data'

Str::stripTags()

Removes HTML tags from the string, with an optional allowlist.

php
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.

php
Str::trim('  Hello  ');       // 'Hello'
Str::trim('***Hello***', '*'); // 'Hello'

Str::normalizeLineEndings()

Normalises all line endings (\r\n, \r) to Unix-style \n.

php
Str::normalizeLineEndings("line1\r\nline2\rline3");
// "line1\nline2\nline3"

Str::decodeHtml()

Converts HTML entities back to their character equivalents.

php
Str::decodeHtml('&quot;Hello&quot; &amp; &#039;World&#039;');
// '"Hello" & \'World\''

Metrics

Str::length()

Returns the number of characters in the string (multibyte-safe).

php
Str::length('Hello');    // 5
Str::length('Olá');      // 3

Str::substrCount()

Returns the number of times a substring appears in the string.

php
Str::substrCount('banana', 'an');   // 2

Str::wordCount()

Returns the number of words in the string.

php
Str::wordCount('Hello beautiful World');   // 3

Str::similarity()

Returns a float between 0.0 and 1.0 representing how similar two strings are.

php
Str::similarity('Hello', 'Hello');   // 1.0
Str::similarity('Hello', 'World');   // 0.2222

Str::levenshtein()

Returns the Levenshtein distance between two strings — the minimum number of single-character edits required to change one string into the other.

php
Str::levenshtein('kitten', 'sitting');   // 3
Str::levenshtein('hello', 'hello');      // 0

Advanced Utilities

Str::pipe()

Passes the string through one or more callbacks in sequence.

php
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.

php
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.

php
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.

php
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.

php
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.

php
Str::test('/^\d+$/', '12345');   // true
Str::test('/^\d+$/', '123ab');   // false

Str::equals()

Compares two strings in constant time, preventing timing attacks. Use this when comparing secrets, tokens, or hashes.

php
Str::equals($userToken, $storedToken);   // true or false

Str::hash()

Hashes a string using the specified algorithm, returning a prefixed string of the form algorithm:hash.

php
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.

php
Str::flushCache();

Quick Reference

MethodSummary
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