Strings
Strings are everywhere in PHP: HTML output, form input, URLs, file contents, database values. PHP offers four ways to write a string literal — single quotes, double quotes, heredoc and nowdoc — and they differ in whether variables and escape sequences are expanded. This lesson covers them all, plus joining strings and reaching individual characters.
Single and double quotes
In single-quoted strings, almost everything is literal: variables aren't replaced and only \' and \\ are escapes. In double-quoted strings, variables are interpolated and escapes like \n work:
<?php $name = "Ada"; echo 'Hello, $name!\n', "\n"; echo "Hello, $name!\n"; echo 'It\'s single-quoted', "\n"; echo "Tab:\t| Quote: \" | Dollar: \$name\n";
Hello, $name!\n Hello, Ada! It's single-quoted Tab: | Quote: " | Dollar: $name
| Escape (double quotes) | Meaning |
|---|---|
\n, \t, \r | Newline, tab, carriage return |
\\, \", \$ | Backslash, double quote, dollar sign |
\u{1F600} | A Unicode character by code point |
\x41 | A byte in hexadecimal |
Use single quotes for fixed text, double quotes when you want interpolation or escapes. The performance difference is negligible.
Interpolation in detail
Simple variables are found automatically. For array elements with string keys, object properties chains, or anything more complex, wrap the expression in curly braces:
<?php $user = ['name' => 'Lin', 'city' => 'Oslo']; $items = ['apple', 'pear']; $count = 3; echo "User: {$user['name']} from {$user['city']}\n"; echo "First item: $items[0]\n"; echo "{$count}x discount\n"; // braces separate the name from following text echo "Total: " . $count * 2 . "\n"; // expressions need concatenation
User: Lin from Oslo First item: apple 3x discount Total: 6
Interpolation only inserts variables, not arbitrary expressions or function calls — for those, concatenate, or use sprintf (lesson 18).
Concatenation
The dot operator joins strings, and .= appends:
<?php $first = "Grace"; $last = "Hopper"; $full = $first . " " . $last; $greeting = "Hello, "; $greeting .= $full; $greeting .= "!"; echo $greeting, "\n"; echo implode(", ", ["red", "green", "blue"]), "\n";
Hello, Grace Hopper! red, green, blue
implode joins an array of strings with a separator — the tidy way to build lists.
Heredoc and nowdoc
For multi-line text, heredoc (<<<LABEL) behaves like a double-quoted string and nowdoc (<<<'LABEL') like a single-quoted one. The closing label's indentation is removed from every line, so you can indent them with your code:
<?php $product = "Desk lamp"; $price = 34.50; $email = <<<TEXT Hi there, Your order for "$product" ({$price} EUR) has shipped. Thanks for shopping with us! TEXT; $code = <<<'CODE' echo "$product"; // shown literally CODE; echo $email, "\n---\n", $code, "\n";
Hi there, Your order for "Desk lamp" (34.5 EUR) has shipped. Thanks for shopping with us! --- echo "$product"; // shown literally
Heredocs are perfect for email bodies, SQL queries and blocks of HTML. Quotes inside don't need escaping.
Length and characters
strlen gives the length and square brackets read single characters, counting from 0. Negative indexes count from the end:
<?php $word = "Banana"; echo strlen($word), "\n"; echo $word[0], "\n"; echo $word[-1], "\n"; echo substr($word, 1, 3), "\n"; $word[0] = 'C'; // strings are mutable in PHP echo $word, "\n";
6 B a ana Canana
Strings are bytes
A PHP string is a sequence of bytes, not characters. For plain ASCII text that's the same thing, but in UTF-8 an accented letter or emoji takes several bytes, so strlen and [] work on bytes:
<?php $word = "café"; echo strlen($word), "\n"; // bytes echo mb_strlen($word), "\n"; // characters echo strtoupper($word), "\n"; // byte-based: é unchanged echo mb_strtoupper($word), "\n";
5 4 CAFé CAFÉ
For text that may contain non-English characters — names, user comments, anything international — use the mb_* functions. Lesson 19 covers them.
Comparing strings
<?php var_dump("apple" === "apple"); var_dump("Apple" === "apple"); var_dump(strcmp("apple", "banana")); // < 0: before var_dump(strcasecmp("HELLO", "hello")); // 0: equal ignoring case var_dump(strnatcmp("file10", "file9")); // natural order: 10 after 9
bool(true) bool(false) int(-1) int(0) int(1)
The comparison functions return a negative number, zero or a positive number — "before", "equal" or "after" — which is what sorting needs.
Try it yourself
Build initials and a username from a full name.
Initials: GBH Username: grace.hopper Length: 21