String Functions
PHP includes a large library of built-in functions for working with strings — well over a hundred in the core string extension alone, plus the multibyte (mb_*) versions. You do not need to memorize them. What matters is knowing which categories exist, recognizing the most common functions, and understanding the behaviors that cause bugs.
This lesson groups the most useful functions by purpose and explains each with examples. Searching, replacing, concatenating, and slicing have their own dedicated lessons, so they are only summarized here.
How String Functions Work
Before looking at individual functions, three rules apply to almost all of them:
- They return a new value; they do not modify the original. Assign the result:
$name = trim($name); - Most work on bytes. Functions such as
strlen(),strtoupper(), andsubstr()treat each byte as a character. For UTF-8 text containing non-English characters, use themb_*equivalent. - Some return
falseon failure. Check such results with=== false, because a valid result might be0or"".
Single-Byte vs Multibyte Equivalents
| Purpose | Byte Function | Multibyte Function |
|---|---|---|
| Length | strlen() | mb_strlen() |
| Lowercase / uppercase | strtolower() / strtoupper() | mb_strtolower() / mb_strtoupper() |
| Substring | substr() | mb_substr() |
| Find position | strpos() | mb_strpos() |
| Split into characters | str_split() | mb_str_split() (PHP 7.4+) |
| Pad | str_pad() | mb_str_pad() (PHP 8.3+) |
| Trim | trim() | mb_trim() (PHP 8.4+) |
| Uppercase first letter | ucfirst() | mb_ucfirst() (PHP 8.4+) |
Changing Case
| Function | Effect |
|---|---|
strtolower($s) | All letters lowercase |
strtoupper($s) | All letters uppercase |
ucfirst($s) | First character uppercase |
lcfirst($s) | First character lowercase |
ucwords($s, $delimiters) | First letter of each word uppercase |
Example
<?php
$title = "learn php the RIGHT way";
echo strtolower($title) . "\n";
echo strtoupper($title) . "\n";
echo ucfirst($title) . "\n";
echo ucwords(strtolower($title)) . "\n";
echo lcfirst("UserName") . "\n";
Output
learn php the right way
LEARN PHP THE RIGHT WAY
Learn php the RIGHT way
Learn Php The Right Way
userName
How It Works
ucfirst()changes only the first character and leaves the rest as they are, which is whyRIGHTstays uppercase.- To get consistent title case, lowercase the whole string first and then apply
ucwords(). lcfirst()is useful for convertingPascalCasenames tocamelCase.
Custom Word Delimiters in ucwords()
By default, ucwords() treats only whitespace as word boundaries. The second parameter adds more delimiters:
<?php
$name = "mary-jane o'neil";
echo ucwords($name) . "\n";
echo ucwords($name, " -'") . "\n";
Output
Mary-jane O'neil
Mary-Jane O'Neil
Including - and ' as delimiters capitalizes the letters after them, which is correct for many hyphenated and apostrophe names.
Case Conversion and Non-English Text
<?php
$word = "café";
echo strtoupper($word) . "\n";
echo mb_strtoupper($word) . "\n";
Output
CAFé
CAFÉ
Since PHP 8.2, strtolower(), strtoupper(), ucfirst(), lcfirst(), and ucwords() convert only ASCII letters (a–z, A–Z) and ignore locale settings. This makes them fast and predictable, but they leave characters like é, ß, or Cyrillic letters unchanged. Use mb_strtolower() and mb_strtoupper() for international text.
Practical Use: Case-Insensitive Matching
<?php
$storedEmail = "Priya.R@Example.com";
$enteredEmail = "priya.r@example.COM";
if (strtolower($storedEmail) === strtolower($enteredEmail)) {
echo "Emails match";
}
Output
Emails match
Email addresses are usually treated as case-insensitive in applications. Normalizing both values to lowercase before comparing (and before storing) prevents duplicate accounts that differ only by case.
Trimming Whitespace and Characters
| Function | Removes From |
|---|---|
trim($s, $chars) | Both ends |
ltrim($s, $chars) | The start (left) |
rtrim($s, $chars) | The end (right) |
Default Behavior
Without a second argument, these functions remove the following characters:
| Character | Escape | Meaning |
|---|---|---|
" " | — | Space |
"\t" | \t | Tab |
"\n" | \n | Newline |
"\r" | \r | Carriage return |
"\0" | \0 | Null byte |
"\v" | \v (or \x0B) | Vertical tab |
Example
<?php
$input = " \t hello@example.com \n";
var_dump(strlen($input));
var_dump(trim($input));
Output
int(24)
string(17) "hello@example.com"
The original value is 24 bytes long: 17 characters of email address plus 7 invisible whitespace characters. Users often paste values with extra spaces, tabs, or line breaks. Trimming input before validation prevents "invalid email" errors for values that look correct.
Removing Specific Characters
<?php
echo trim("---Title---", "-") . "\n";
echo rtrim("apple,banana,cherry,", ",") . "\n";
echo ltrim("000452", "0") . "\n";
echo rtrim("/var/www/html/", "/") . "\n";
echo trim("[note]", "[]") . "\n";
Output
Title
apple,banana,cherry
452
/var/www/html
note
How the Character List Works
The second argument is a list of individual characters, not a word. trim("---Title---", "-") removes any number of - characters from both ends. trim($s, "[]") removes both [ and ].
A range can be written with ..: trim($s, "a..z") removes lowercase letters from the ends.
Note: Because the argument is a character list,
rtrim("report.txt", ".txt")does not remove the extension — it removes any trailing.,t, orxcharacters, producing"repor". To remove a suffix, check it withstr_ends_with()and cut it withsubstr().
Padding and Repeating
str_pad()
str_pad(string $string, int $length, string $pad_string = " ", int $pad_type = STR_PAD_RIGHT): string
Example
<?php
echo str_pad("7", 3, "0", STR_PAD_LEFT) . "\n";
echo str_pad("Hi", 8, "*", STR_PAD_BOTH) . "\n";
echo str_pad("Name", 10) . "|\n";
echo str_pad("Order", 12, ".") . " ₹450\n";
Output
007
***Hi***
Name |
Order....... ₹450
How It Works
$lengthis the final length, not the number of characters to add. If the string is already that long or longer, it is returned unchanged.STR_PAD_LEFTpads the start,STR_PAD_RIGHT(default) pads the end, andSTR_PAD_BOTHsplits the padding between both sides.- Leading zeros (
007) are common for codes, IDs, and times.sprintf('%03d', 7)produces the same result for numbers.
str_repeat()
<?php
echo str_repeat("=", 20) . "\n";
echo str_repeat("ab", 3) . "\n";
$rating = 4;
echo str_repeat("★", $rating) . str_repeat("☆", 5 - $rating) . "\n";
Output
====================
ababab
★★★★☆
str_repeat() returns the string repeated the given number of times. The rating example builds a five-star display from a number.
Splitting and Joining
explode() — Split a String Into an Array
explode(string $separator, string $string, int $limit = PHP_INT_MAX): array
<?php
$tags = "php,mysql,laravel,api";
$parts = explode(",", $tags);
print_r($parts);
echo count($parts) . " tags\n";
Output
Array
(
[0] => php
[1] => mysql
[2] => laravel
[3] => api
)
4 tags
Using the Limit
<?php
$line = "2026-10-08|ERROR|Database connection failed | retrying";
print_r(explode("|", $line, 3));
print_r(explode(",", "a,b,c,d", -1));
Output
Array
(
[0] => 2026-10-08
[1] => ERROR
[2] => Database connection failed | retrying
)
Array
(
[0] => a
[1] => b
[2] => c
)
- A positive limit returns at most that many elements; the last element contains the rest of the string. This is useful when the final field itself may contain the separator, such as the log message above.
- A negative limit returns all elements except the last
n.
implode() — Join an Array Into a String
<?php
$skills = ["PHP", "MySQL", "JavaScript"];
echo implode(", ", $skills) . "\n";
echo implode(" | ", $skills) . "\n";
echo "<li>" . implode("</li><li>", $skills) . "</li>\n";
Output
PHP, MySQL, JavaScript
PHP | MySQL | JavaScript
<li>PHP</li><li>MySQL</li><li>JavaScript</li>
implode() places the separator between elements only, so there is no trailing comma to remove. join() is an alias of implode().
str_split() and mb_str_split() — Split Into Chunks
<?php
print_r(str_split("ABCDEFGH", 3));
print_r(mb_str_split("தமிழ்"));
Output
Array
(
[0] => ABC
[1] => DEF
[2] => GH
)
Array
(
[0] => த
[1] => ம
[2] => ி
[3] => ழ
[4] => ்
)
str_split() splits by bytes; mb_str_split() splits by characters (Unicode code points). Note that in scripts like Tamil, a visible letter can be built from more than one code point (மி = ம + ி). Splitting by user-perceived characters requires grapheme_str_split() from the intl extension (PHP 8.4+).
Counting
<?php
$text = "PHP is popular. PHP is practical.";
echo str_word_count($text) . "\n";
echo substr_count($text, "PHP") . "\n";
echo substr_count(strtolower($text), "p") . "\n";
Output
6
2
7
str_word_count()counts words. It recognizes only ASCII letters, so it is unreliable for other languages. A Unicode-aware alternative iscount(preg_split('/\s+/u', trim($text), -1, PREG_SPLIT_NO_EMPTY)).substr_count()counts how many times a substring appears. It is case-sensitive, so convert the case first for case-insensitive counting: the lowercase text contains sevenpcharacters (two in eachphp, two inpopular, one inpractical).
Comparing
| Function | Comparison | Returns 0 When |
|---|---|---|
strcmp($a, $b) | Case-sensitive | Equal |
strcasecmp($a, $b) | Case-insensitive | Equal ignoring case |
strncmp($a, $b, $n) | First $n bytes, case-sensitive | First $n bytes are equal |
strncasecmp($a, $b, $n) | First $n bytes, case-insensitive | Equal ignoring case |
strnatcmp($a, $b) | "Natural" order (numbers as numbers) | Equal |
strnatcasecmp($a, $b) | Natural order, case-insensitive | Equal |
These functions return a negative number if $a sorts before $b, 0 if they are equal, and a positive number if $a sorts after $b. That makes them ideal as comparison callbacks for sorting:
<?php
$versions = ["v1.10", "v1.2", "v1.9"];
usort($versions, 'strnatcmp');
print_r($versions);
Output
Array
(
[0] => v1.2
[1] => v1.9
[2] => v1.10
)
A plain strcmp() would sort v1.10 before v1.2. For comparing actual version numbers, PHP also provides version_compare().
Formatting Text for Display
nl2br() — Show Line Breaks in HTML
<?php
$message = "Hello Team,\nThe meeting is at 3 PM.\nThanks";
echo nl2br(htmlspecialchars($message));
Output (HTML)
Hello Team,<br />
The meeting is at 3 PM.<br />
Thanks
nl2br() inserts <br /> before each newline, so text typed in a <textarea> keeps its line breaks when displayed. Escape first with htmlspecialchars(), then apply nl2br() — the other order would escape the <br /> tags themselves.
wordwrap() — Wrap Long Text
<?php
$text = "The quick brown fox sat";
echo wordwrap($text, 10, "\n", true);
Output
The quick
brown fox
sat
wordwrap() breaks text into lines of at most the given width (10), breaking at spaces. The fourth argument true forces long words (such as URLs) to be cut if they exceed the width. It is used for plain-text emails and fixed-width output. It counts bytes, so it is not suitable for multibyte text.
strip_tags() — Remove HTML Tags
<?php
$html = "<p>Hello <b>World</b>! <a href='#'>Read more</a></p>";
echo strip_tags($html) . "\n";
echo strip_tags($html, ['b']) . "\n";
Output
Hello World! Read more
Hello <b>World</b>! Read more
strip_tags() removes HTML and PHP tags, optionally keeping allowed tags. It is useful for generating plain-text previews.
Warning:
strip_tags()is not a security filter. Allowed tags keep their attributes, including dangerous ones likeonclick. To output untrusted text safely, usehtmlspecialchars(). To allow safe HTML from users, use a dedicated sanitizer library such as HTML Purifier.
Other Useful Functions
| Function | Purpose | Example | Result |
|---|---|---|---|
strrev($s) | Reverse (bytes) | strrev("hello") | olleh |
levenshtein($a, $b) | Number of edits to change one string into another | levenshtein("kitten", "sitting") | 3 |
similar_text($a, $b, $pct) | Similarity, with optional percentage | similar_text("World", "Word") | 4 |
soundex($s) / metaphone($s) | Phonetic keys for "sounds like" matching (English) | soundex("Robert") === soundex("Rupert") | true |
number_format($n, $d) | Format numbers with separators | number_format(1234.5, 2) | 1,234.50 |
htmlspecialchars($s) | Escape for HTML | htmlspecialchars("<b>") | <b> |
addslashes($s) | Escape quotes with backslashes | addslashes("O'Neil") | O\'Neil |
bin2hex($s) | Convert bytes to hexadecimal | bin2hex("A") | 41 |
base64_encode($s) | Encode binary data as text | base64_encode("PHP") | UEhQ |
urlencode($s) | Encode for URL query strings | urlencode("a b&c") | a+b%26c |
Practical Use: "Did You Mean?" Suggestions
<?php
$commands = ["install", "update", "remove", "search"];
$typed = "instal";
$best = null;
$bestDistance = PHP_INT_MAX;
foreach ($commands as $command) {
$distance = levenshtein($typed, $command);
if ($distance < $bestDistance) {
$bestDistance = $distance;
$best = $command;
}
}
if ($bestDistance <= 2) {
echo "Unknown command '$typed'. Did you mean '$best'?";
}
Output
Unknown command 'instal'. Did you mean 'install'?
levenshtein() counts the minimum number of single-character insertions, deletions, or substitutions needed to turn one string into another. "instal" needs one insertion to become "install", so it is the closest match. Command-line tools such as Composer use this technique to suggest corrections.
Searching, Replacing, and Slicing (Summary)
These operations have their own lessons:
| Task | Key Functions | Lesson |
|---|---|---|
| Check whether text contains, starts, or ends with something | str_contains(), str_starts_with(), str_ends_with() | Search in Strings |
| Find the position of text | strpos(), stripos(), strrpos(), mb_strpos() | Search in Strings |
| Replace text | str_replace(), str_ireplace(), strtr(), substr_replace() | Modify Strings |
| Join strings | ., .=, implode(), sprintf() | Concatenate Strings |
| Extract parts | substr(), mb_substr(), strstr(), strrchr() | Slicing Strings |
| Pattern matching | preg_match(), preg_replace(), preg_split() | PHP RegEx |
Practical Example: Preparing Text for a Blog Listing
<?php
function initials(string $fullName): string
{
$parts = array_filter(explode(' ', trim($fullName)));
$letters = array_map(fn($part) => mb_strtoupper(mb_substr($part, 0, 1)), $parts);
return implode('', $letters);
}
function excerpt(string $html, int $maxChars = 40): string
{
$text = trim(preg_replace('/\s+/', ' ', strip_tags($html)));
if (mb_strlen($text) <= $maxChars) {
return $text;
}
$cut = mb_substr($text, 0, $maxChars);
$lastSpace = mb_strrpos($cut, ' ');
if ($lastSpace !== false) {
$cut = mb_substr($cut, 0, $lastSpace);
}
return rtrim($cut, ' ,.;:') . '…';
}
$author = " ravi kumar ";
$content = "<p>PHP is a popular general-purpose scripting language that is especially suited to web development.</p>";
echo initials($author) . "\n";
echo excerpt($content) . "\n";
echo excerpt($content, 60) . "\n";
echo excerpt("Short text") . "\n";
Output
RK
PHP is a popular general-purpose…
PHP is a popular general-purpose scripting language that is…
Short text
Step-by-Step Explanation
initials()
trim()removes the outer spaces.explode(' ', ...)splits on single spaces. Because the name contains several spaces in a row, some elements are empty strings.array_filter()removes those empty elements (empty strings are falsy).array_map()takes the first character of each part withmb_substr()and uppercases it withmb_strtoupper(), which also works for non-English names.implode('', ...)joins the letters with no separator.
excerpt()
strip_tags()removes HTML, andpreg_replace('/\s+/', ' ', ...)collapses all runs of whitespace into single spaces.- If the text is already short enough, it is returned unchanged.
- Otherwise,
mb_substr()cuts to the maximum length in characters. mb_strrpos()finds the last space in the cut text, and the text is shortened to that point so no word is broken in half.rtrim($cut, ' ,.;:')removes trailing punctuation before adding the ellipsis….
Common Mistakes
Using Byte Functions on UTF-8 Text
Effect: Wrong lengths, broken characters, unchanged accented letters.
Fix: Use the mb_* equivalents for user-facing text.
Treating the trim() Character List as a Word
Effect: rtrim("report.txt", ".txt") returns "repor".
Fix: Use str_ends_with() with substr() to remove a specific suffix.
Forgetting That str_pad() Length Is the Total Length
Effect: str_pad("Hi", 2, "*") returns "Hi" unchanged.
Fix: Pass the desired final length.
Relying on strip_tags() for Security
Effect: XSS through allowed tags' attributes.
Fix: Escape output with htmlspecialchars().
Applying nl2br() Before Escaping
Effect: The inserted <br /> tags are escaped and appear as text.
Fix: nl2br(htmlspecialchars($text)).
Best Practices
- Learn the categories, and look up exact signatures in the PHP manual when needed.
- Assign function results; string functions do not modify their input.
- Use
mb_*functions for any text a person reads or types. - Trim and normalize input before validating or comparing it.
- Use
implode()instead of building comma-separated strings by hand. - Escape output for its context (
htmlspecialchars()for HTML); formatting functions are not security tools.
Official reference: https://www.php.net/manual/en/ref.strings.php