Single quoted
The simplest way to specify a string is to enclose it in single
quotes (the character '
).
To specify a literal single quote, escape it with a backslash
(\
). To specify a literal backslash, double it
(\\
). All other instances of backslash will be treated
as a literal backslash: this means that the other escape sequences you
might be used to, such as \r
or \n
,
will be output literally as specified rather than having any special
meaning.
Note:
Unlike the double-quoted
and heredoc syntaxes,
variables and escape sequences
for special characters will not be expanded when they
occur in single quoted strings.
Heredoc
A third way to delimit strings is the heredoc syntax:
<<<
. After this operator, an identifier is
provided, then a newline. The string itself follows, and then
the same identifier again to close the quotation.
The closing identifier may be indented by space or tab, in which case
the indentation will be stripped from all lines in the doc string.
Prior to PHP 7.3.0, the closing identifier must
begin in the first column of the line.
Also, the closing identifier must follow the same naming rules as any
other label in PHP: it must contain only alphanumeric characters and
underscores, and must start with a non-digit character or underscore.
Example #1 Basic Heredoc example as of PHP 7.3.0
<?php
// no indentation
echo <<<END
a
b
c
\n
END;
// 4 spaces of indentation
echo <<<END
a
b
c
END;
Output of the above example in PHP 7.3:
If the closing identifier is indented further than any lines of the body, then a ParseError will be thrown:
Example #2 Closing identifier must not be indented further than any lines of the body
<?php
echo <<<END
a
b
c
END;
Output of the above example in PHP 7.3:
PHP Parse error: Invalid body indentation level (expecting an indentation level of at least 3) in example.php on line 4
If the closing identifier is indented, tabs can be used as well, however,
tabs and spaces must not be intermixed regarding
the indentation of the closing identifier and the indentation of the body
(up to the closing identifier). In any of these cases, a ParseError will be thrown.
These whitespace constraints have been included because mixing tabs and
spaces for indentation is harmful to legibility.
Example #3 Different indentation for body (spaces) closing identifier
<?php
// All the following code do not work.
// different indentation for body (spaces) ending marker (tabs)
{
echo <<<END
a
END;
}
// mixing spaces and tabs in body
{
echo <<<END
a
END;
}
// mixing spaces and tabs in ending marker
{
echo <<<END
a
END;
}
Output of the above example in PHP 7.3:
PHP Parse error: Invalid indentation - tabs and spaces cannot be mixed in example.php line 8
The closing identifier for the body string is not required to be
followed by a semicolon or newline. For example, the following code
is allowed as of PHP 7.3.0:
Example #4 Continuing an expression after a closing identifier
<?php
$values = [<<<END
a
b
c
END, 'd e f'];
var_dump($values);
Output of the above example in PHP 7.3:
array(2) {
[0] =>
string(11) "a
b
c"
[1] =>
string(5) "d e f"
}
Warning
If the closing identifier was found at the start of a line, then
regardless of whether it was a part of another word, it may be considered
as the closing identifier and causes a ParseError.
Example #5 Closing identifier in body of the string tends to cause ParseError
<?php
$values = [<<<END
a
b
END ING
END, 'd e f'];
Output of the above example in PHP 7.3:
PHP Parse error: syntax error, unexpected identifier "ING", expecting "]" in example.php on line 6
To avoid this problem, it is safe to follow the simple rule:
do not choose as a closing identifier if it appears in the body
of the text.
Warning
Prior to PHP 7.3.0, it is very important to note that the line with the
closing identifier must contain no other characters, except a semicolon
(;
).
That means especially that the identifier
may not be indented, and there may not be any spaces
or tabs before or after the semicolon. It's also important to realize that
the first character before the closing identifier must be a newline as
defined by the local operating system. This is \n
on
UNIX systems, including macOS. The closing delimiter must also be
followed by a newline.
If this rule is broken and the closing identifier is not "clean", it will
not be considered a closing identifier, and PHP will continue looking for
one. If a proper closing identifier is not found before the end of the
current file, a parse error will result at the last line.
Example #6 Invalid example, prior to PHP 7.3.0
<?php
class foo {
public $bar = <<<EOT
bar
EOT;
}
// Identifier must not be indented
?>
Example #7 Valid example, even prior to PHP 7.3.0
<?php
class foo {
public $bar = <<<EOT
bar
EOT;
}
?>
Heredocs containing variables can not be used for initializing class properties.
Heredoc text behaves just like a double-quoted string, without
the double quotes. This means that quotes in a heredoc do not need to be
escaped, but the escape codes listed above can still be used. Variables are
expanded, but the same care must be taken when expressing complex variables
inside a heredoc as with strings.
Example #8 Heredoc string quoting example
<?php
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;
/* More complex example, with variables. */
class foo
{
var $foo;
var $bar;
function __construct()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'MyName';
echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;
?>
The above example will output:
My name is "MyName". I am printing some Foo.
Now, I am printing some Bar2.
This should print a capital 'A': A
It is also possible to use the Heredoc syntax to pass data to function
arguments:
Example #9 Heredoc in arguments example
<?php
var_dump(array(<<<EOD
foobar!
EOD
));
?>
It's possible to initialize static variables and class
properties/constants using the Heredoc syntax:
Example #10 Using Heredoc to initialize static values
<?php
// Static variables
function foo()
{
static $bar = <<<LABEL
Nothing in here...
LABEL;
}
// Class properties/constants
class foo
{
const BAR = <<<FOOBAR
Constant example
FOOBAR;
public $baz = <<<FOOBAR
Property example
FOOBAR;
}
?>
The opening Heredoc identifier may optionally be
enclosed in double quotes:
Example #11 Using double quotes in Heredoc
<?php
echo <<<"FOOBAR"
Hello World!
FOOBAR;
?>
Nowdoc
Nowdocs are to single-quoted strings what heredocs are to double-quoted
strings. A nowdoc is specified similarly to a heredoc, but no
parsing is done inside a nowdoc. The construct is ideal for
embedding PHP code or other large blocks of text without the need for
escaping. It shares some features in common with the SGML
<![CDATA[ ]]>
construct, in that it declares a
block of text which is not for parsing.
A nowdoc is identified with the same <<<
sequence used for heredocs, but the identifier which follows is enclosed in
single quotes, e.g. <<<'EOT'
. All the rules for
heredoc identifiers also apply to nowdoc identifiers, especially those
regarding the appearance of the closing identifier.
Example #12 Nowdoc string quoting example
<?php
echo <<<'EOD'
Example of string spanning multiple lines
using nowdoc syntax. Backslashes are always treated literally,
e.g. \\ and \'.
EOD;
The above example will output:
Example of string spanning multiple lines
using nowdoc syntax. Backslashes are always treated literally,
e.g. \\ and \'.
Example #13 Nowdoc string quoting example with variables
<?php
class foo
{
public $foo;
public $bar;
function __construct()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'MyName';
echo <<<'EOT'
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41
EOT;
?>
The above example will output:
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41
Example #14 Static data example
<?php
class foo {
public $bar = <<<'EOT'
bar
EOT;
}
?>
Variable parsing
When a string is specified in double quotes or with heredoc,
variables are parsed within it.
There are two types of syntax: a
simple one and a
complex one.
The simple syntax is the most common and convenient. It provides a way to
embed a variable, an array value, or an object
property in a string with a minimum of effort.
The complex syntax can be recognised by the
curly braces surrounding the expression.
Simple syntax
If a dollar sign ($
) is encountered, the parser will
greedily take as many tokens as possible to form a valid variable name.
Enclose the variable name in curly braces to explicitly specify the end of
the name.
Similarly, an array index or an object property
can be parsed. With array indices, the closing square bracket
(]
) marks the end of the index. The same rules apply to
object properties as to simple variables.
Example #15 Simple syntax example
<?php
$juices = array("apple", "orange", "koolaid1" => "purple");
echo "He drank some $juices[0] juice.".PHP_EOL;
echo "He drank some $juices[1] juice.".PHP_EOL;
echo "He drank some $juices[koolaid1] juice.".PHP_EOL;
class people {
public $john = "John Smith";
public $jane = "Jane Smith";
public $robert = "Robert Paulsen";
public $smith = "Smith";
}
$people = new people();
echo "$people->john drank some $juices[0] juice.".PHP_EOL;
echo "$people->john then said hello to $people->jane.".PHP_EOL;
echo "$people->john's wife greeted $people->robert.".PHP_EOL;
echo "$people->robert greeted the two $people->smiths."; // Won't work
?>
The above example will output:
He drank some apple juice.
He drank some orange juice.
He drank some purple juice.
John Smith drank some apple juice.
John Smith then said hello to Jane Smith.
John Smith's wife greeted Robert Paulsen.
Robert Paulsen greeted the two .
As of PHP 7.1.0 also negative numeric indices are
supported.
Example #16 Negative numeric indices
<?php
$string = 'string';
echo "The character at index -2 is $string[-2].", PHP_EOL;
$string[-3] = 'o';
echo "Changing the character at index -3 to o gives $string.", PHP_EOL;
?>
The above example will output:
The character at index -2 is n.
Changing the character at index -3 to o gives strong.
For anything more complex, you should use the complex syntax.
Complex (curly) syntax
This isn't called complex because the syntax is complex, but because it
allows for the use of complex expressions.
Any scalar variable, array element or object property with a
string representation can be included via this syntax.
The expression is written the same way as it would appear outside the
string, and then wrapped in {
and
}
. Since {
can not be escaped, this
syntax will only be recognised when the $
immediately
follows the {
. Use {\$
to get a
literal {$
. Some examples to make it clear:
It is also possible to access class properties using variables
within strings using this syntax.
Note:
The value accessed from functions, method calls, static class variables,
and class constants inside
{$}
will be interpreted as the name
of a variable in the scope in which the string is defined. Using
single curly braces ({}
) will not work for
accessing the return values of functions or methods or the
values of class constants or static class variables.
String access and modification by character
Characters within strings may be accessed and modified by
specifying the zero-based offset of the desired character after the
string using square array brackets, as in
$str[42]. Think of a string as an
array of characters for this purpose. The functions
substr() and substr_replace()
can be used when you want to extract or replace more than 1 character.
Note:
As of PHP 7.1.0, negative string offsets are also supported. These specify
the offset from the end of the string.
Formerly, negative offsets emitted E_NOTICE
for reading
(yielding an empty string) and E_WARNING
for writing
(leaving the string untouched).
Note:
Prior to PHP 8.0.0, strings could also be accessed using braces, as in
$str{42}, for the same purpose.
This curly brace syntax was deprecated as of PHP 7.4.0 and no longer supported as of PHP 8.0.0.
Warning
Writing to an out of range offset pads the string with spaces.
Non-integer types are converted to integer.
Illegal offset type emits E_WARNING
.
Only the first character of an assigned string is used.
As of PHP 7.1.0, assigning an empty string throws a fatal error. Formerly,
it assigned a NULL byte.
Warning
Internally, PHP strings are byte arrays. As a result, accessing or
modifying a string using array brackets is not multi-byte safe, and
should only be done with strings that are in a single-byte encoding such
as ISO-8859-1.
Note:
As of PHP 7.1.0, applying the empty index operator on an empty string throws a fatal
error. Formerly, the empty string was silently converted to an array.
Example #17 Some string examples
<?php
// Get the first character of a string
$str = 'This is a test.';
$first = $str[0];
// Get the third character of a string
$third = $str[2];
// Get the last character of a string.
$str = 'This is still a test.';
$last = $str[strlen($str)-1];
// Modify the last character of a string
$str = 'Look at the sea';
$str[strlen($str)-1] = 'e';
?>
String offsets have to either be integers or integer-like strings,
otherwise a warning will be thrown.
Example #18 Example of Illegal String Offsets
<?php
$str = 'abc';
var_dump($str['1']);
var_dump(isset($str['1']));
var_dump($str['1.0']);
var_dump(isset($str['1.0']));
var_dump($str['x']);
var_dump(isset($str['x']));
var_dump($str['1x']);
var_dump(isset($str['1x']));
?>
The above example will output:
string(1) "b"
bool(true)
Warning: Illegal string offset '1.0' in /tmp/t.php on line 7
string(1) "b"
bool(false)
Warning: Illegal string offset 'x' in /tmp/t.php on line 9
string(1) "a"
bool(false)
string(1) "b"
bool(false)
Note:
Accessing variables of other types (not including arrays or objects
implementing the appropriate interfaces) using []
or
{}
silently returns null
.
Note:
Characters within string literals can be accessed
using []
or {}
.
Note:
Accessing characters within string literals using the
{}
syntax has been deprecated in PHP 7.4.
This has been removed in PHP 8.0.