Str

Overview

The Str class provides a full suite of string utilities built for multilingual applications. Every method is multibyte-safe and handles Unicode text correctly — Arabic, Hindi, Bengali, Chinese, or any UTF-8 language.

  • Class: JiFramework\Core\Utilities\Str
  • Access: $app->str (lazy-loaded instance)
  • Encoding: all text methods use mb_* functions with explicit UTF-8 encoding
  • Security: all random generation methods use random_bytes() / random_int() — cryptographically secure by default
$str = $app->str;

// Works with any language
$str->length('مرحبا');        // 5 characters, not 10 bytes
$str->truncate('مرحبا بالعالم', 8); // correct character cut

// Secure random generation
$token = $str->randomToken(32);   // 64-char hex token
$code  = $str->randomString(8);   // 'aB3xY7mQ'

// Slug from any language title
$str->slugify('Cafe au lait!'); // 'cafe-au-lait'

escape()

escape(mixed $data): mixed

Escape special HTML characters in a string, array, or object. Recursive — safely sanitises nested structures before rendering user-supplied data in HTML.

  • $data(mixed) String, array, or object to escape. Non-string scalars are returned unchanged.

Returns: the escaped value (same type as input).

$str->escape('<script>alert("xss")</script>');
// '&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;'

// Recursive on arrays
$str->escape(['name' => '<b>Alice</b>']);
// ['name' => '&lt;b&gt;Alice&lt;/b&gt;']

length()

length(string $string): int

Return the character count of a string. Uses mb_strlen() — counts Unicode characters, not bytes, so Arabic and Hindi strings return the correct count.

  • $string(string) The input string.

Returns: number of characters.

$str->length('hello');    // 5
$str->length('مرحبا');    // 5  (not 10 bytes)
$str->length('नमस्ते'); // 6
$str->length('');         // 0

wordCount()

wordCount(string $string): int

Count the number of words in a string. Uses Unicode-aware regex splitting — works correctly with Arabic, Hindi, and other scripts.

  • $string(string) The input string.

Returns: number of words.

$str->wordCount('hello world foo');    // 3
$str->wordCount('  too  many  spaces'); // 3

countOccurrences()

countOccurrences(string $haystack, string $needle): int

Count how many times a substring appears in a string.

  • $haystack(string) The string to search in.
  • $needle(string) The substring to count. Returns 0 if empty.

Returns: number of occurrences.

$str->countOccurrences('ababab', 'ab'); // 3
$str->countOccurrences('hello', '');   // 0

words()

words(string $string, int $count = 10): string

Extract the first N words from a string. Useful for previews and summaries.

  • $string(string) The input string.
  • $count(int) Number of words to return (default 10). If the string has fewer words, the full string is returned.

Returns: the first $count words joined by single spaces.

$str->words('one two three four five', 3);
// 'one two three'

$str->words('hello', 10);
// 'hello'  (fewer words than $count -- no change)

plainText()

plainText(string $html, int $wordCount = 10): string

Strip HTML tags, decode HTML entities, and return the first N words as plain text. Ideal for generating meta descriptions or search result snippets from rich content.

  • $html(string) HTML content to process.
  • $wordCount(int) Maximum number of words to return (default 10).

Returns: plain text excerpt.

$str->plainText('<b>Hello</b> <i>world foo bar</i>', 3);
// 'Hello world foo'

$str->plainText('&amp; &lt;safe&gt;', 2);
// '& <safe>'

before() / after() / between()

Extract parts of a string relative to a delimiter. All three methods are multibyte-safe.

before(string $string, string $search): string

Returns everything before the first occurrence of $search. Returns the full string if not found.

after(string $string, string $search): string

Returns everything after the first occurrence of $search. Returns the full string if not found.

between(string $string, string $start, string $end): string

Returns the content between the first $start and the following $end. Returns an empty string if either delimiter is missing.

$str->before('2024-03-15', '-');         // '2024'
$str->after('[email protected]', '@');    // 'example.com'
$str->between('[token_value]', '[', ']'); // 'token_value'

// Parsing a log line
$log  = '[2024-03-15] ERROR: Connection timeout';
$date = $str->between($log, '[', ']');  // '2024-03-15'
$msg  = $str->after($log, 'ERROR: ');    // 'Connection timeout'

extractInteger()

extractInteger(string $string): int

Pull all digit characters out of a string and return them as a single integer. Useful for parsing IDs or order numbers from mixed strings.

  • $string(string) The input string containing digits.

Returns: integer composed of all digits found, or 0 if none.

$str->extractInteger('Order #007');     // 7
$str->extractInteger('abc123def456');   // 123456
$str->extractInteger('no digits here'); // 0

truncate()

truncate(string $string, int $length, string $ellipsis = '...'): string

Shorten a string to a maximum character length, appending an ellipsis if the string was cut. Counts characters, not bytes — works correctly with Arabic, Hindi, and all Unicode text.

  • $string(string) The input string.
  • $length(int) Maximum number of characters in the output (including the ellipsis).
  • $ellipsis(string) String to append when truncated (default '...').

Returns: truncated string, or the original if it fits within $length.

$str->truncate('Hello World', 7);  // 'Hell...'
$str->truncate('Hi', 10);          // 'Hi'  (no change)
$str->truncate('Hello World', 7, '…'); // 'Hello W…'

mask()

mask(string $string, int $unmaskedChars = 4, string $maskingCharacter = 'X'): string

Mask a string, leaving only the last N characters visible. Useful for safely displaying card numbers, phone numbers, or email addresses. Multibyte-safe.

  • $string(string) The value to mask.
  • $unmaskedChars(int) Number of trailing characters to leave visible (default 4).
  • $maskingCharacter(string) Character used for masking (default 'X').

Returns: masked string, or the original if $unmaskedChars exceeds the string length.

$str->mask('1234567890123456', 4);        // 'XXXXXXXXXXXX3456'
$str->mask('[email protected]', 10, '*'); // '******@example.com' (approx)

zeroPad()

zeroPad(int $number, int $targetLength): string

Left-pad an integer with zeros to reach a target string length. Commonly used for order numbers, invoice IDs, and reference codes.

  • $number(int) The integer to pad.
  • $targetLength(int) Desired total length of the output string.

Returns: zero-padded string. If $number already meets or exceeds the target length, it is returned as-is.

$str->zeroPad(7, 5);     // '00007'
$str->zeroPad(42, 6);    // '000042'
$str->zeroPad(12345, 5); // '12345'

reverse()

reverse(string $string): string

Reverse a string character by character. Multibyte-safe — Arabic, Hindi, and all Unicode strings are reversed correctly without corrupting multi-byte sequences.

  • $string(string) The string to reverse.

Returns: the reversed string.

$str->reverse('hello'); // 'olleh'
$str->reverse('12345'); // '54321'

replaceFirst() / replaceLast()

Replace only the first or only the last occurrence of a search string. Standard str_replace() replaces all occurrences — these methods give precise control.

replaceFirst(string $search, string $replace, string $subject): string
replaceLast(string $search, string $replace, string $subject): string
  • $search(string) The substring to find.
  • $replace(string) The replacement string.
  • $subject(string) The string to search in.

Returns: modified string, or the original if $search is not found.

$str->replaceFirst('a', 'X', 'banana'); // 'bXnana'
$str->replaceLast('a',  'X', 'banana'); // 'bananX'

$str->replaceFirst('is', 'was', 'This is nice'); // 'Thwas is nice'
$str->replaceLast('is',  'was', 'This is nice'); // 'This was nice'

toCamelCase() / toPascalCase()

Convert a string to camelCase or PascalCase. Both methods recognise spaces, hyphens, and underscores as word boundaries.

toCamelCase(string $string): string

First word is lowercased, subsequent words are capitalised.

toPascalCase(string $string): string

Every word is capitalised (UpperCamelCase). Internally calls toCamelCase() and uppercases the first character.

$str->toCamelCase('hello world foo'); // 'helloWorldFoo'
$str->toCamelCase('my-class-name');   // 'myClassName'
$str->toCamelCase('hello_world');     // 'helloWorld'

$str->toPascalCase('hello world'); // 'HelloWorld'
$str->toPascalCase('my-api-key');  // 'MyApiKey'

toSnakeCase() / toKebabCase()

Convert a string to snake_case or kebab-case. Both handle camelCase, PascalCase, acronyms, spaces, and hyphens as input.

toSnakeCase(string $string): string
toKebabCase(string $string): string

toKebabCase() calls toSnakeCase() internally and replaces underscores with hyphens.

$str->toSnakeCase('helloWorldFoo'); // 'hello_world_foo'
$str->toSnakeCase('HTMLParser');    // 'html_parser'
$str->toSnakeCase('Hello World');   // 'hello_world'

$str->toKebabCase('Hello World Foo'); // 'hello-world-foo'
$str->toKebabCase('myClassName');     // 'my-class-name'

toTitleCase()

toTitleCase(string $string): string

Convert a string to Title Case — the first letter of every word is capitalised. Uses mb_convert_case() with MB_CASE_TITLE for correct Unicode behaviour.

  • $string(string) The input string.

Returns: title-cased string.

$str->toTitleCase('hello world');         // 'Hello World'
$str->toTitleCase('the quick brown fox'); // 'The Quick Brown Fox'

contains() / startsWith() / endsWith()

Three boolean search methods — all multibyte-safe and Unicode-aware.

contains(string $haystack, string $needle): bool

Returns true if $needle appears anywhere in $haystack.

startsWith(string $haystack, string $needle): bool

Returns true if $haystack begins with $needle.

endsWith(string $haystack, string $needle): bool

Returns true if $haystack ends with $needle. Always returns true for an empty needle.

$str->contains('hello world', 'world');       // true
$str->contains('hello', 'xyz');               // false

$str->startsWith('https://example.com', 'https'); // true
$str->startsWith('hello', 'world');               // false

$str->endsWith('image.jpg', '.jpg'); // true
$str->endsWith('hello', '');         // true

isJson()

isJson(string $string): bool

Determine whether a string is valid JSON. Useful for validating API payloads or cached data before decoding.

  • $string(string) The string to test.

Returns: true if the string decodes without error, false otherwise.

$str->isJson('{"key":"value"}'); // true
$str->isJson('[1, 2, 3]');       // true
$str->isJson('{bad json}');      // false
$str->isJson('hello');           // false

slugify()

slugify(string $string): string

Convert a string into a URL-friendly slug. Lowercases the input, removes HTML tags, replaces non-alphanumeric characters with hyphens, and transliterates accented Latin characters to ASCII.

  • $string(string) The title or phrase to slugify.

Returns: URL-safe slug. Returns 'n-a' if no usable characters remain after processing (e.g. a pure Arabic or Devanagari string with no ASCII equivalent).

$str->slugify('Hello World!');    // 'hello-world'
$str->slugify('cafe au lait');    // 'cafe-au-lait'
$str->slugify('foo   bar---baz'); // 'foo-bar-baz'

formatCurrency()

formatCurrency(float $number, int $decimalPlaces = 2, string $currencySymbol = '', string $decimalPoint = '.', string $thousandsSep = ','): string

Format a number as a localised currency string. Supports any currency symbol including multibyte symbols.

  • $number(float) The amount to format.
  • $decimalPlaces(int) Decimal precision (default 2).
  • $currencySymbol(string) Symbol to prepend, e.g. '$', 'EUR ' (default empty).
  • $decimalPoint(string) Decimal separator (default '.').
  • $thousandsSep(string) Thousands separator (default ',').

Returns: formatted currency string.

$str->formatCurrency(1234.5, 2, '$');          // '$1,234.50'
$str->formatCurrency(9999.99, 2, 'EUR ');       // 'EUR 9,999.99'
$str->formatCurrency(9.99, 2, 'EUR', ',', '.'); // 'EUR9,99'

Random Generation

Four cryptographically secure random generation methods — all use PHP's random_int() or random_bytes() internally.

randomInt(int $min, int $max): int

Generate a secure random integer between $min and $max (inclusive).

randomString(int $length = 10): string

Generate a random alphanumeric string of $length characters (A-Z, a-z, 0-9).

randomToken(int $length = 32): string

Generate a random hex token. $length is the number of bytes — the output string will be $length × 2 hex characters long.

randomColor(): string

Generate a random hexadecimal colour code (e.g. #a3f1b2).

$str->randomInt(1, 100);    // e.g. 42
$str->randomString(16);     // e.g. 'aB3xY7mQpL9wZk2R'
$str->randomToken(32);      // 64-character hex string
$str->randomColor();        // e.g. '#3a8fdc'

Examples

Practical examples combining multiple Str methods.

Blog post slug from a title
$title = 'Hello World -- My First Post!';
$slug  = $str->slugify($title); // 'hello-world-my-first-post'
Safe display of user input
$userInput = '<script>alert("xss")</script>';
echo $str->escape($userInput);
Article preview from HTML body
$body    = '<p>Welcome to our new website. We offer the best content.</p>';
$preview = $str->plainText($body, 8);
// 'Welcome to our new website. We offer'
Mask a phone number for display
$phone  = '+8801712345678';
$masked = $str->mask($phone, 4, '*');
// '*********5678'
Secure API key and human-readable order ID
$apiKey  = $str->randomToken(32);  // 64-char hex token
$orderId = 'ORD-' . $str->zeroPad($str->randomInt(1, 99999), 5);
// e.g. 'ORD-07423'
Parse structured log line
$log  = '[2024-03-15] ERROR: Connection timeout';
$date = $str->between($log, '[', ']'); // '2024-03-15'
$msg  = $str->after($log, 'ERROR: ');   // 'Connection timeout'
Database column name from a form field label
$label  = 'First Name';
$column = $str->toSnakeCase($label); // 'first_name'