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
<?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";
Output
Hello, $name!\n
Hello, Ada!
It's single-quoted
Tab:	| Quote: " | Dollar: $name
Escape (double quotes)Meaning
\n, \t, \rNewline, tab, carriage return
\\, \", \$Backslash, double quote, dollar sign
\u{1F600}A Unicode character by code point
\x41A 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
<?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
Output
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
<?php

$first = "Grace";
$last = "Hopper";

$full = $first . " " . $last;
$greeting = "Hello, ";
$greeting .= $full;
$greeting .= "!";

echo $greeting, "\n";
echo implode(", ", ["red", "green", "blue"]), "\n";
Output
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
<?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";
Output
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
<?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";
Output
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
<?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";
Output
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
<?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
Output
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.

Try it yourself · main.php
Edit the code, copy it into main.php, then run it with php main.php (PHP 8.5). How to install PHP
Output
Initials: GBH
Username: grace.hopper
Length: 21