TL;DR

Master PHP string functions for searching, formatting, transforming, and parsing text data in web applications.

Key concepts

  • PHP string functions
  • PHP string manipulation
  • PHP regex
  • PHP text processing

String Manipulation

Strings are the backbone of web development. Whether you are processing form input, formatting database results, building URLs, or generating HTML, you will constantly work with text. PHP ships with over one hundred built-in string functions, and knowing the right ones makes the difference between clean, readable code and a tangle of loops. This lesson covers the most practical string tools you will reach for every day.

Basic String Operations

Before diving into functions, recall the two string literal styles PHP offers: single-quoted strings treat almost everything literally, while double-quoted strings interpolate variables and escape sequences.

<?php

$name = "Alice";
$greeting = "Hello, $name!";       // Double-quoted: interpolates variable
$literal  = 'Hello, $name!';       // Single-quoted: treats $ literally

echo $greeting . "\n"; // Hello, Alice!
echo $literal  . "\n"; // Hello, $name!

// Heredoc — useful for multi-line strings with interpolation
$message = <<<EOT
Dear $name,
Welcome to the platform.
Your account is now active.
EOT;

echo $message;

Use single quotes when you do not need interpolation — they signal intent clearly and avoid accidental variable expansion.

Searching and Inspecting Strings

The most common string tasks involve finding whether something exists, where it is, and how long a string is.

<?php

$email = "alice@example.com";

// Length
echo strlen($email) . "\n";              // 17

// Position of first occurrence (returns false if not found)
$atPos = strpos($email, "@");
echo "@ is at index: $atPos\n";          // @ is at index: 5

// Case-insensitive search
$haystack = "The Quick Brown Fox";
$found = stripos($haystack, "quick");
echo "Found 'quick' at index: $found\n"; // Found 'quick' at index: 4

// PHP 8+ helpers — cleaner than strpos() !== false
if (str_contains($email, "@")) {
    echo "Looks like a valid email format.\n";
}

if (str_starts_with($email, "alice")) {
    echo "Email belongs to Alice.\n";
}

if (str_ends_with($email, ".com")) {
    echo "Top-level domain is .com\n";
}

str_contains(), str_starts_with(), and str_ends_with() were added in PHP 8.0. They replace the verbose strpos() !== false pattern and make code much easier to read at a glance.

Transforming Strings

Transformation functions let you normalise, sanitize, and reformat text. These are essential when handling user input or preparing data for display.

<?php

$raw = "  Hello, World!  ";

// Trim whitespace from both ends
$trimmed = trim($raw);
echo "'$trimmed'\n";                     // 'Hello, World!'

// Case conversions
echo strtolower("PHP IS FUN") . "\n";   // php is fun
echo strtoupper("php is fun") . "\n";   // PHP IS FUN
echo ucfirst("hello world") . "\n";     // Hello world
echo ucwords("hello world") . "\n";     // Hello World

// Replace substrings
$sentence = "I love cats. Cats are great.";
echo str_replace("cats", "dogs", $sentence) . "\n";
// I love dogs. Cats are great.

// Case-insensitive replace
echo str_ireplace("cats", "dogs", $sentence) . "\n";
// I love dogs. dogs are great.

// Pad a string to a fixed width (useful for formatting reports)
$price = "9.99";
echo str_pad($price, 10, " ", STR_PAD_LEFT) . "|\n";  //       9.99|

// Repeat a string
echo str_repeat("-", 30) . "\n";        // ------------------------------

Splitting, Joining, and Extracting

explode() and implode() are the workhorses for converting between strings and arrays — essential for processing CSV rows, URL segments, tag lists, and more. substr() gives you precise control over extracting portions of a string by position and length.

<?php

// Split a CSV line into fields
$line = "Alice,30,Engineer,alice@example.com";
$fields = explode(",", $line);

echo $fields[0] . "\n";  // Alice
echo $fields[2] . "\n";  // Engineer

// Limit the number of splits
$limited = explode(",", $line, 2);
// Array ( [0] => Alice [1] => 30,Engineer,alice@example.com )
print_r($limited);

// Join an array back into a string
$tags = ["php", "web", "backend"];
echo implode(", ", $tags) . "\n";       // php, web, backend

// substr — extract by position and length
$url = "https://example.com/products/42";
$domain = substr($url, 8, 11);
echo $domain . "\n";                    // example.com

// Negative offset counts from the end
$id = substr($url, -2);
echo $id . "\n";                        // 42

// Extract a file extension
$filename = "report_2024.pdf";
$ext = substr($filename, strrpos($filename, ".") + 1);
echo $ext . "\n";                       // pdf

// Safer: use pathinfo() for file paths
echo pathinfo($filename, PATHINFO_EXTENSION) . "\n"; // pdf

Formatting with sprintf and number_format

sprintf() builds formatted strings using placeholders — invaluable for generating reports, padding columns, or rendering values with a consistent number of decimal places.

<?php

$name    = "Bob";
$balance = 1234567.891;
$score   = 0.876;
$rank    = 3;

// %s = string, %d = integer, %f = float
echo sprintf("Hello, %s!\n", $name);           // Hello, Bob!
echo sprintf("Rank: %02d\n", $rank);            // Rank: 03  (zero-padded)
echo sprintf("Score: %.1f%%\n", $score * 100);  // Score: 87.6%

// number_format for currency and large numbers
echo number_format($balance, 2) . "\n";          // 1,234,567.89
echo sprintf("Balance: $%s\n", number_format($balance, 2)); // Balance: $1,234,567.89

// Left-align strings with - flag; right-align numbers
$inventory = ["apple" => 3, "banana" => 12, "cherry" => 1];
foreach ($inventory as $item => $qty) {
    echo sprintf("%-10s %3d units\n", $item, $qty);
}
// apple       3 units
// banana     12 units
// cherry      1 units

Try It Yourself

You are building a simple user profile display. Given raw data from a form submission, use string functions to produce clean, formatted output.

<?php

// Raw data from a form submission
$rawName  = "  john doe  ";
$rawBio   = "I LOVE PHP programming and building web apps.";
$rawTags  = "php,web development,open source,backend";
$joinDate = "2023-11-05";

// 1. Clean and format the name
$name = ucwords(trim($rawName));

// 2. Normalise the bio to sentence case
$bio = ucfirst(strtolower($rawBio));

// 3. Parse tags, trim each one, display the first three
$tags        = array_map('trim', explode(",", $rawTags));
$displayTags = array_slice($tags, 0, 3);
$tagLine     = "#" . implode(" #", $displayTags);

// 4. Reformat the ISO date to DD/MM/YYYY
$parts     = explode("-", $joinDate);
$formatted = sprintf("%s/%s/%s", $parts[2], $parts[1], $parts[0]);

// 5. Render the profile card
$separator = str_repeat("=", 42);
echo $separator . "\n";
echo sprintf("  Name : %s\n", $name);
echo sprintf("  Since: %s\n", $formatted);
echo sprintf("  Bio  : %s\n", $bio);
echo sprintf("  Tags : %s\n", $tagLine);
echo $separator . "\n";

Try extending this: add a website field and use str_starts_with() to verify it begins with https:// before displaying it. Then use str_replace() to strip the protocol prefix from the visible label.

Key Takeaways

  • Use str_contains(), str_starts_with(), and str_ends_with() (PHP 8+) for readable substring checks rather than strpos() !== false.
  • trim(), strtolower(), and ucwords() form the essential trio for sanitizing and normalizing user-supplied text before storing or displaying it.
  • explode() and implode() convert cleanly between strings and arrays — reach for them whenever you work with delimited data like CSV, tags, or URL paths.
  • substr() paired with strpos() or strrpos() gives you precise extraction by position; use pathinfo() as a higher-level alternative for file paths.
  • sprintf() is the cleanest way to build formatted strings; prefer it over concatenation when mixing types, controlling decimal places, or aligning columns.
  • Always validate and sanitize string input at the application boundary — never trust raw user data directly from $_GET, $_POST, or external APIs.

Pro Tip: For complex pattern matching and replacement, PHP's preg_match() and preg_replace() with PCRE regular expressions are far more powerful than the basic string functions. Once you are comfortable with the tools in this lesson, regular expressions are the natural next step — they handle cases where str_replace() and strpos() fall short, such as validating email formats, extracting structured tokens, or performing conditional replacements based on context.


## Next Steps

You now have a deep command of PHP's string functions -- searching, slicing, formatting, and transforming text with precision. These tools will serve you in nearly every project.

PHP is evolving rapidly, and PHP 8 introduced a wave of features that make the language more expressive and safer. **PHP 8 features** covers match expressions, named arguments, union types, the nullsafe operator, and constructor property promotion. Understanding these modern features means writing cleaner, more concise code and being able to work confidently with current codebases and frameworks that already use them.

[Continue to PHP 8 Features -->](/lessons/17-php8-features)