字符串是一组字符,每个字符相当于一个字节。也就是说,因为PHP只能支持256个字符集,所以不支持Unicode。
注意:在32位版本中,字符串最多可以为2GB(最多2147483647字节)。
字符串可以用四种方式表示:
1、单引号
2、双引号
3、heredoc 语法结构
4、nowdoc 语法结构
定义字符串的最简单方法是用单引号(字符')括起来。
要表示单引号本身,请在前面加上反斜线()进行转义。使用两个反斜线(\)表示反斜线本身。使用其他方法的反斜杠将被视为反斜杠本身。也就是说,如果您想使用其他转义序列(如 或 ),这并不意味着特殊,而是指两个字符本身。
注意:与双引号或透明文档语法结构不同,单引号字符串中的变量或特殊字符转义序列不会被替换。
<?php echo 'this is a simple string'; // 可以录入多行 echo 'You can also have embedded newlines in strings this way as it is okay to do'; // 输出: Arnold once said: "I'll be back" echo 'Arnold once said: "I'll be back"'; // 输出: You deleted C:*.*? echo 'You deleted C:\*.*?'; // 输出: You deleted C:*.*? echo 'You deleted C:*.*?'; // 输出: This will not expand: a newline echo 'This will not expand: a newline'; // 输出: Variables do not $expand $either echo 'Variables do not $expand $either'; ?>
如果字符串被双引号(“)包围,PHP将解析以下特殊字符:
换行符(LF或ASCII字符集的0x0A(10))
回车(CR或ASCII字符集的0x0D(13))
水平制表符字符(HT或ASCII字符集的0x09(9))
v垂直制表符字符(VT或ASCII字符集的0x0B(11))
e转义(ESC或ASCII字符集的0x1B(27))
f表单提要(ASCII字符集的FF或0x0C(12))
\反斜线
$美元符号
“双引号”
[0-7]{1,3}是一个以八进制表示正则表达式序列的字符,它与静静溢出以容纳在一个字节中相匹配(例如,“400”==“ 00”)
\x[0-9A-Fa-f]{1,2}匹配正则表达式序列,是十六进制字符
u{[0-9A-Fa-f]+}与正则表达式匹配的字符串是Unicode代码点,可以将其作为UTF-8表达式输出字符串
与单引号字符串一样,转义其他字符时会出现反斜杠。
双引号中定义的字符串的最重要功能是解析变量。
表达字符串的第三种方法是使用透明文档语法<<。在运算符之后提供标识符,然后继续换行。下面是字符串string本身,将以前定义的标识符作为结束标记结束。
可以在空格或制表符中缩进结束标识符。在这种情况下,docstring将删除所有缩进。在PHP7.3.0之前的版本中,最后引用的标识符必须位于行的第一列。
标识符也按照PHP规则命名,就像其他标记一样。标识符只能包含字符、数字和下划线,并且必须以字符和下划线开始。
示例1 PHP7.3.0或更高版本的基本透明文档示例:
<?php // 无缩进 echo <<<END a b c END; // 4 空格缩进 echo <<<END a b c END;
在PHP7.3中输出上述例程:
a
b
c
a
b
c
如果结束标识符缩进得比内容中的任何行都多,则抛出部件错误异常。
示例2结束标识符不能缩进文本中的任何行:
<?php echo <<<END a b c END;
在PHP7.3中输出上述例程:
PHP Parse error: Invalid body indentation level (expecting an indentation level of at least 3) in example.php on line 4
选项卡可以缩进结束标识符,但是对于结束标识符和内容缩进,选项卡和空间不能混合使用。在上述任一种情况下,抛出部件错误异常。包含这些空白限制,因为缩进中混合了制表符和空格会很难读。
示例3内容(空白)和结束标识符不同的缩进:
<?php // 以下所有代码都不起作用。 // 正文(空格)和结束标记(制表符),不同的缩进 { echo <<<END a END; } // 在正文中混合空格和制表符 { echo <<<END a END; } // 在结束标记中混合空格和制表符 { echo <<<END a END; }
在PHP7.3中输出上述例程:
PHP Parse error: Invalid indentation - tabs and spaces cannot be mixed in example.php line 8
不需要在内容字符串的结束标识符后面加分号或换行符。例如,以下代码在PHP7.3.0或更高版本中是允许的。
例4关闭标识符后继续表达式:
<?php $values = [<<<END a b c END, 'd e f']; var_dump($values);
在PHP7.3中输出上述例程:
array(2) {
[0] =>
string(11) "a
b
c"
[1] =>
string(5) "d e f"
}
注意:
如果结束标识符位于行的开头,则无论它是否是另一个单词的一部分,它都会被视为结束标识符,并可能导致出现ParseError。
示例5字符串内容的结束标识符可能会导致ParseError:
<?php $values = [<<<END a b END ING END, 'd e f'];
在PHP7.3中输出上述例程:
PHP Parse error: syntax error, unexpected identifier "ING", expecting "]" in example.php on line 6
为了避免这个问题,遵循以下简单的规则是安全的。不要选择出现在正文内容中的单词作为结束标识符。
注意:
在PHP7.3.0之前,具有结束标识符的行包括(;)而需要与环境混合的每条反射光线,进行环境采样。也就是说,标识符不能缩进,也不能在分号前后包含空格或制表符。更重要的是,在结束标识符之前,需要由本机操作系统识别的换行符(如UNIX和macOS系统中的 ),并且换行符必须在结束分隔符之后继续。
如果退出标记不符合此规则,则PHP确定它不是退出标识符,并继续搜索。如果在文件结束前找不到适当的结束标识符,PHP将在最后一行生成解析错误。
示例6PHP7.3.0之前的错误示例:
<?php class foo { public $bar = <<<EOT bar EOT; } // 不能缩进标识符 ?>
PHP7.3.0之前的有效示例:
<?php class foo { public $bar = <<<EOT bar EOT; } ?>
透明文档结构类似于一个由没有双引号的双引号括起来的字符串。也就是说,单引号不会在透明文档结构中转义,但上述转义序列仍然可用。变量将被替换,但请注意复杂变量,如透明文档结构中的字符串。
Heredocs文档结构字符串示例:
<?php $str = <<<EOD Example of string spanning multiple lines using heredoc syntax. EOD; /* 含有变量的更复杂示例 */ 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; ?>
输出上述例程:
My name is "MyName". I am printing some Foo.
Now, I am printing some Bar2.
This should print a capital 'A': A
也可以在函数参数中使用Heredoc结构传递数据。
参数的透明文档结构示例:
<?php var_dump(array(<<<EOD foobar! EOD )); ?>
可以使用透明文档结构初始化静态变量、类属性和常量。
使用实例#10 Heredoc结构初始化静态值:
<?php // 静态变量 function foo() { static $bar = <<<LABEL Nothing in here... LABEL; } // 类的常量、属性 class foo { const BAR = <<<FOOBAR Constant example FOOBAR; public $baz = <<<FOOBAR Property example FOOBAR; } ?>
标识符也可以在透明文档结构中用双引号声明。
实例#11在透明文档结构中使用双引号:
<?php echo <<<"FOOBAR" Hello World! FOOBAR; ?>
与透明文档结构类似于双引号字符串一样,Nowdoc结构类似于单引号字符串。nowdoc的结构与透明文档的结构非常相似,但nowdoc不进行解析。此结构非常适合在不转义特殊字符的情况下嵌入PHP代码或其他大文本区块。SGML的<!与CDATA[]>结构一样,nowdoc结构也具有相同的特征。
nowdoc结构也与透明文档结构相同,标记为<<,但以下标识符用单引号括起来(例如:<<<<'EOT'):。Heredoc结构中的所有规则,特别是结束标识符规则也适用于nowdoc结构。
实例#12 Nowdoc结构字符串示例:
<?php echo <<<'EOD' Example of string spanning multiple lines using nowdoc syntax. Backslashes are always treated literally, e.g. \ and '. EOD;
输出上述例程:
Example of string spanning multiple lines
using nowdoc syntax. Backslashes are always treated literally,
e.g. \ and '.
包含实例#13变量引用的Nowdoc字符串示例:
<?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; ?>
输出上述例程:
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
实例#14静态数据示例:
<?php class foo { public $bar = <<<'EOT' bar EOT; } ?>
注意:
在PHP5.3.0中添加了Nowdoc构建。
如果字符串由双引号或透明文档结构定义,则会解析其中的变量。
这里有两个语法规则:简单规则和复杂规则。简单的语法规则是最常见和最有用的,可以用最少的代码在字符串中嵌入变量、数组值或对象属性。
复杂规则语法的特征是用中括号括起来的表达式。
简单语法
当PHP解析器检测到美元符号($)时,它将尽可能多的令牌组合在一起形成有效的变量名称,就像许多其他解析器一样。可以使用中括号分隔变量名称。
<?php $juice = "apple"; echo "He drank some $juice juice.".PHP_EOL; // Invalid. "s" is a valid character for a variable name, but the variable is $juice. echo "He drank some juice made of $juices."; // Valid. Explicitly specify the end of the variable name by enclosing it in braces: echo "He drank some juice made of ${juice}s."; ?>
输出上述例程:
He drank some apple juice.
He drank some juice made of .
He drank some juice made of apples.
同样,还可以解析数组索引或对象属性。数组索引使用方括号()表示索引的末尾,对象属性遵循与上述变量相同的规则。
实例#15简单语法示例:
<?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 ?>
输出上述例程:
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 .
PHP7.1.0或更高版本还支持负数值索引。
实例#16负索引:
<?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 character at index -2 is n.
Changing the character at index -3 to o gives strong.
如果您想表达更复杂的结构,请使用复杂的语法。
复杂(中括号)语法
复杂的语法是命名的,因为它可以使用复杂的表达式,而不是因为它的语法复杂。
具有字符串表示的标量变量、数组单元格或对象属性可以使用此语法。表达式以与字符串外部相同的方式编写,并用括号{和}括起来。由于{无法转义,因此只有在{旁边时才会识别$。您可以使用{$来表示{$。以下示例更为恰当:
<?php // 显示所有错误 error_reporting(E_ALL); $great = 'fantastic'; // 无效,输出: This is { fantastic} echo "This is { $great}"; // 有效,输出: This is fantastic echo "This is {$great}"; // 有效 echo "This square is {$square->width}00 centimeters broad."; // 有效,只有通过花括号语法才能正确解析带引号的键名 echo "This works: {$arr['key']}"; // 有效 echo "This works: {$arr[4][3]}"; // 这是错误的表达式,因为就象 $foo[bar] 的格式在字符串以外也是错的一样。 // 换句话说,只有在 PHP 能找到常量 foo 的前提下才会正常工作;这里会产生一个 // E_NOTICE (undefined constant) 级别的错误。 echo "This is wrong: {$arr[foo][3]}"; // 有效,当在字符串中使用多重数组时,一定要用括号将它括起来 echo "This works: {$arr['foo'][3]}"; // 有效 echo "This works: " . $arr['foo'][3]; echo "This works too: {$obj->values[3]->name}"; echo "This is the value of the var named $name: {${$name}}"; echo "This is the value of the var named by the return value of getName(): {${getName()}}"; echo "This is the value of the var named by the return value of $object->getName(): {${$object->getName()}}"; // 无效,输出: This is the return value of getName(): {getName()} echo "This is the return value of getName(): {getName()}"; // 无效, 输出: C:folder{fantastic}.txt echo "C:folder{$great}.txt" // 有效, 输出: C:folderfantastic.txt echo "C:\folder\{$great}.txt" ?>
也可以使用此语法从字符串中的变量调用类属性。
<?php class foo { var $bar = 'I am bar.'; } $foo = new foo(); $bar = 'bar'; $baz = array('foo', 'bar', 'baz', 'quux'); echo "{$foo->$bar} "; echo "{$foo->{$baz[1]}} "; ?>
输出以上例程:
I am bar.
I am bar.
注意:
函数、方法、静态类变量和类常量可以使用{$}作为定义字符串的命名空间的变量名访问这些值。如果单独使用括号({}),则无法处理来自函数或方法的返回值,或类常量和类静态变量的值。
<?php // 显示所有错误 error_reporting(E_ALL); class beers { const softdrink = 'rootbeer'; public static $ale = 'ipa'; } $rootbeer = 'A & W'; $ipa = 'Alexander Keith's'; // 有效,输出: I'd like an A & W echo "I'd like an {${beers::softdrink}} "; // 也有效,输出: I'd like an Alexander Keith's echo "I'd like an {${beers::$ale}} "; ?>