Most of what a website does is text: names, titles, messages and HTML. PHP has a rich set of tools for working with strings.
Single and double quotes
Single-quoted strings are taken literally. Double-quoted strings replace variables with their values (interpolation) and understand escape sequences such as \n:
<?php
$name = 'Sam';
echo 'Hello, $name\n'; // Hello, $name\n
echo "Hello, $name\n"; // Hello, Sam (and a new line)
Use curly braces when the variable is followed by other characters or is an array element:
<?php
$fruit = 'apple';
$user = ['name' => 'Sam'];
echo "Two {$fruit}s\n"; // Two apples
echo "Welcome, {$user['name']}"; // Welcome, Sam
A simple rule: use single quotes for fixed text, double quotes when you insert variables.
Joining strings
The . operator concatenates:
<?php
$first = 'Ada';
$last = 'Lovelace';
$full = $first . ' ' . $last;
$full .= ' (1815 to 1852)';
echo $full;
For anything with several values, sprintf() is often clearer. Placeholders like %s (string), %d (integer) and %.2f (float with two decimals) are filled in order:
<?php
$item = 'Notebook';
$qty = 3;
$price = 2.5;
echo sprintf('%d x %s = £%.2f', $qty, $item, $qty * $price);
// 3 x Notebook = £7.50
printf() works the same but prints directly.
Multi-line strings with heredoc
Heredoc keeps longer text readable and interpolates variables like double quotes:
<?php
$name = 'Sam';
$course = 'PHP for Beginners';
$email = <<<TEXT
Hi {$name},
Thanks for starting {$course}.
Your first lesson is ready.
TEXT;
echo $email;
The closing marker (TEXT;) can be indented; PHP removes the same indentation from every line. Use <<<'TEXT' (nowdoc, with quotes) for literal text with no interpolation.
Everyday string functions
<?php
$text = ' Learn PHP, one lesson at a time. ';
echo strlen($text); // 36 (bytes, including spaces)
echo trim($text); // removes spaces at both ends
echo strtoupper('php'); // PHP
echo ucfirst('hello world'); // Hello world
echo str_replace('PHP', 'Python', $text); // replaces every match
echo substr('Geeks2Smart', 0, 5); // Geeks
Checking for text is easy since PHP 8:
<?php
$email = 'sam@example.com';
var_dump(str_contains($email, '@')); // true
var_dump(str_starts_with($email, 'sam')); // true
var_dump(str_ends_with($email, '.com')); // true
Finding a position returns an integer, or false if not found:
<?php
$position = strpos('hello world', 'world'); // 6
if ($position !== false) {
echo "Found at {$position}";
}
Always compare strpos() with !== false. If the text is found at position 0, a loose check like if ($position) treats 0 as false and wrongly reports "not found".
Splitting and joining
<?php
$csv = 'red,green,blue';
$colours = explode(',', $csv); // ['red', 'green', 'blue']
echo implode(' | ', $colours); // red | green | blue
Text in other languages: mb_ functions
strlen() counts bytes, not characters. Letters like é, ü or 日 take more than one byte in UTF-8, so the byte-based functions give the wrong answer:
<?php
$word = 'café';
echo strlen($word); // 5 (bytes)
echo mb_strlen($word); // 4 (characters)
echo strtoupper($word); // CAFé (wrong)
echo mb_strtoupper($word); // CAFÉ
echo mb_substr($word, 0, 3); // caf
Whenever text might contain more than plain English letters, which on the web means always for user input, use the mb_ version: mb_strlen, mb_substr, mb_strtoupper, mb_strtolower.
Summary
- Single quotes are literal; double quotes interpolate
{$variables}and escapes. - Join with
.and.=, or format withsprintf(). - Heredoc makes multi-line text readable.
str_contains,str_starts_withandstr_ends_withcover most searches; comparestrpos()with!== false.- Use
mb_functions for correct results with non-ASCII characters.