← All docs

Strings

String types, escape sequences, interpolation, heredoc/nowdoc, and built-in string functions.

Double-quoted strings

Support escape sequences:

<?php
echo "Hello\n";      // newline
echo "Tab\there";    // tab
echo "Return\r";     // carriage return
echo "Vert\v";       // vertical tab
echo "Esc\e";        // escape byte
echo "Form\f";       // form feed
echo "Quote: \"";    // escaped quote
echo "Backslash: \\"; // backslash
echo "\x41";         // hex byte: A
echo "\101";         // octal byte: A
echo "\u{1F600}";    // Unicode codepoint: 😀

Single-quoted strings

No escape sequences except \\ and \':

<?php
echo 'Hello\n';      // prints: Hello\n (literal)
echo 'It\'s here';   // prints: It's here

String interpolation

Double-quoted strings and heredocs interpolate variables. Both the simple and complex syntaxes are supported:

<?php
$name = "World";
echo "Hello, $name\n";          // simple: $variable

$user = ["name" => "Ada", "age" => 36];
echo "Name: $user[name]\n";     // simple: one $var[offset] (bareword key, no quotes)

class Point { public int $x = 1; }
$p = new Point();
echo "x = $p->x\n";             // simple: one $var->prop

echo "Sum: {$user['age']}\n";   // complex: {$expr} allows full expressions

// PHP 8.x deprecated forms are accepted for compatibility:
echo "Hello, ${name}\n";        // deprecated ${var}
echo "Sum: ${1 + 2}\n";         // deprecated ${expr}

The ${var} and ${expr} forms behave like PHP 8.x: they still work, but are deprecated. Prefer $var or {$expr} in new code.

Variable and identifier names may contain non-ASCII letters, matching PHP:

<?php
$café = "espresso";
echo "Order: $café\n";

Heredoc strings

Multi-line with escape processing (like double-quoted):

<?php
echo <<<EOT
Hello World
This is line 2
EOT;

The closing label closes the heredoc when it is at the start of a line and followed by any non-identifier character, so a heredoc can be used as an expression — for example as a function argument or in a concatenation:

<?php
echo strtoupper(<<<EOT
hello
EOT) . "!";

PHP 7.3+ flexible (indented) heredocs are supported: the closing marker may be indented, and that indentation is stripped from every body line.

<?php
function describe(): string {
    return <<<EOT
        line one
        line two
        EOT;   // -> "line one\nline two"
}

Nowdoc strings

Multi-line without escape processing (like single-quoted):

<?php
echo <<<'EOT'
Hello World
No escapes: \n \t stay literal
EOT;

String indexing

<?php
$s = "hello";
echo $s[1];    // e
echo $s[-1];   // o
echo "[" . $s[99] . "]";  // []

Read-only. Negative indices count from end. Out-of-bounds returns empty string.

Built-in string functions

FunctionSignatureDescription
strlen()strlen($str): intReturns string length
substr()substr($str, $start [, $len]): stringExtract substring
strpos()strpos($hay, $needle): int|falseFind first occurrence. Returns false if not found
strrpos()strrpos($hay, $needle): int|falseFind last occurrence. Returns false if not found
strstr()strstr($hay, $needle): stringFind first occurrence and return rest
str_replace()str_replace($search, $replace, $subject): stringReplace all occurrences
str_ireplace()str_ireplace($search, $replace, $subject): stringCase-insensitive replace
substr_replace()substr_replace($str, $repl, $start [, $len]): stringReplace substring
strtolower()strtolower($str): stringConvert to lowercase
strtoupper()strtoupper($str): stringConvert to uppercase
ucfirst()ucfirst($str): stringUppercase first character
lcfirst()lcfirst($str): stringLowercase first character
ucwords()ucwords($str): stringUppercase first letter of each word
trim()trim($str [, $chars]): stringStrip the default mask (" \n\r\t\v\f\0") or explicit characters from both ends
ltrim()ltrim($str [, $chars]): stringStrip the default mask (" \n\r\t\v\f\0") or explicit characters from the left
rtrim()rtrim($str [, $chars]): stringStrip the default mask (" \n\r\t\v\f\0") or explicit characters from the right
chop()chop($str [, $chars]): stringAlias of rtrim()
str_repeat()str_repeat($str, $times): stringRepeat a string
str_pad()str_pad($str, $len [, $pad, $type]): stringPad string to length
str_split()str_split($str [, $len]): arraySplit into chunks
strrev()strrev($str): stringReverse a string
grapheme_strrev()grapheme_strrev($str): string|falseReverse a UTF-8 string by grapheme clusters, preserving embedded NUL bytes and keeping combining marks, emoji modifiers, and ZWJ sequences with their base cluster. Returns false on malformed UTF-8.
strcmp()strcmp($a, $b): intBinary-safe string comparison
strcasecmp()strcasecmp($a, $b): intCase-insensitive comparison
str_contains()str_contains($hay, $needle): boolCheck if string contains substring
str_starts_with()str_starts_with($hay, $prefix): boolCheck prefix
str_ends_with()str_ends_with($hay, $suffix): boolCheck suffix
ord()ord($char): intASCII value of first character
chr()chr($code): stringCharacter from ASCII code
explode()explode($delim, $str): arraySplit string into array
implode()implode($glue, $arr): stringJoin array into string
number_format()number_format($n [, $dec [, $dec_point, $thou_sep]]): stringFormat number
sprintf()sprintf($fmt, ...): stringFormat string (%s, %d, %f, %x, %e, %g, %o, %c, %%)
printf()printf($fmt, ...): intFormat and print
vsprintf()vsprintf($fmt, array $values): stringLike sprintf(), with the arguments supplied as an array. Each element becomes one format argument — int/float/bool/string, including the elements of a mixed array.
vprintf()vprintf($fmt, array $values): intLike printf(), with the arguments supplied as an array; prints the result and returns the byte count.
sscanf()sscanf($str, $fmt): arrayParse string with format (%d, %f, %s, %%). Matched fields are returned as substrings (e.g. %f yields "3.14"), mirroring the existing %d behavior.
addslashes()addslashes($str): stringEscape quotes and backslashes
stripslashes()stripslashes($str): stringRemove escape backslashes
nl2br()nl2br($str): stringInsert <br /> before newlines
wordwrap()wordwrap($str [, $width [, $break [, $cut]]]): stringWrap text at word boundaries; set $cut to break over-long words
bin2hex()bin2hex($str): stringConvert binary to hex
hex2bin()hex2bin($str): stringConvert hex to binary
long2ip()long2ip($ip): stringFormat a 32-bit integer as a dotted-quad IPv4 address
ip2long()ip2long($ip): int|falseParse a decimal dotted-quad IPv4 string into an integer, or false if invalid
inet_pton()inet_pton($ip): string|falsePack a dotted-quad IPv4 address into a 4-byte binary string, or false if invalid
inet_ntop()inet_ntop($binary): string|falseRender a 4-byte IPv4 binary string as a dotted-quad address, or false if the length is not 4
md5()md5($str, $binary = false): stringMD5 hash — 32-char lowercase hex by default, or the raw 16 digest bytes when $binary is true
sha1()sha1($str, $binary = false): stringSHA1 hash — 40-char lowercase hex by default, or the raw 20 digest bytes when $binary is true
crc32()crc32($str): intCRC-32 checksum (standard zlib/PHP polynomial), returned as a non-negative 32-bit integer
hash()hash($algo, $data, $binary = false): stringHash $data with the named algorithm (md5, sha1, sha2 family, sha3 family, ripemd, crc32/crc32b, and more). Returns lowercase hex by default, or the raw digest bytes when $binary is true. An unknown algorithm throws \ValueError.
hash_hmac()hash_hmac($algo, $data, $key, $binary = false): stringKeyed-hash message authentication code of $data under $key using the named cryptographic algorithm. Returns lowercase hex by default, or the raw digest bytes when $binary is true. An unknown algorithm, or a non-cryptographic checksum (crc32/adler/fnv/joaat), throws \ValueError.
hash_file()hash_file($algo, $filename, $binary = false): string|falseHash a file’s contents with the named algorithm; returns the digest (hex, or raw bytes when $binary), or false if the file cannot be read.
hash_equals()hash_equals($known, $user): boolTiming-safe string comparison — constant-time for equal-length strings, returns false immediately on a length mismatch.
hash_algos()hash_algos(): arrayReturn the list of supported hash algorithm names.
hash_init()hash_init($algo): HashContextOpen an incremental hashing context. An unknown algorithm throws \ValueError. (The HASH_HMAC flag form is not supported — use hash_hmac().)
hash_update()hash_update($context, $data): boolFeed data into an incremental hashing context.
hash_final()hash_final($context, $binary = false): stringFinalize a context and return the digest (hex, or raw bytes when $binary).
hash_copy()hash_copy($context): HashContextClone an incremental hashing context so the original and copy can diverge.
htmlspecialchars()htmlspecialchars($str, $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, $encoding = "UTF-8"): stringEscape HTML special chars: & < > " ' (single quote as &#039;). The ENT_* flag constants (ENT_QUOTES, ENT_COMPAT, ENT_NOQUOTES, ENT_HTML401, ENT_HTML5, ENT_XHTML, ENT_XML1, ENT_SUBSTITUTE, ENT_IGNORE) are defined with PHP’s values; $flags and $encoding are accepted but the escaper currently always applies ENT_QUOTES behaviour
htmlentities()htmlentities($str, $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, $encoding = "UTF-8"): stringAlias for htmlspecialchars
html_entity_decode()html_entity_decode($str): stringDecode HTML entities
urlencode()urlencode($str): stringURL-encode (spaces as +)
urldecode()urldecode($str): stringURL-decode
rawurlencode()rawurlencode($str): stringURL-encode (spaces as %20)
rawurldecode()rawurldecode($str): stringURL-decode (RFC 3986)
base64_encode()base64_encode($str): stringBase64 encode
base64_decode()base64_decode($str): stringBase64 decode
gzcompress()gzcompress(string $data, int $level = -1): stringCompress a string with zlib (system libz); $level is -1 (default) or 09
gzuncompress()gzuncompress(string $data): string|falseDecompress a gzcompress()-produced string; false on a zlib error
gzdeflate()gzdeflate(string $data, int $level = -1): stringCompress a string into raw DEFLATE — no zlib header or trailer; $level is -1 (default) or 09
gzinflate()gzinflate(string $data): string|falseDecompress a raw DEFLATE string from gzdeflate() or the zlib.deflate stream filter; false on a zlib error
ctype_alpha()ctype_alpha($str): boolAll chars are A-Z/a-z
ctype_digit()ctype_digit($str): boolAll chars are 0-9
ctype_alnum()ctype_alnum($str): boolAll chars are alphanumeric
ctype_space()ctype_space($str): boolAll chars are whitespace

Regex functions are documented separately in Regex, including the PCRE2 build requirements for programs that use preg_*.