PHP中单引号字符串和双引号字符串有什么区别?

926

我有点困惑为什么在PHP代码中有的字符串放在单引号中,有的放在双引号中。

我只知道在.NET或C语言中,如果用单引号括起来,那就是一个字符,而不是一个字符串。

7个回答

1228

PHP字符串不仅可以使用两种方式指定,而是可以使用四种方式。

  1. 单引号字符串几乎完全按原样显示。变量和大多数转义序列将不被解释。但有一个例外,为了显示字面上的单引号,可以使用反斜杠\'进行转义,并且要显示反斜杠,可以用另一个反斜杠\\进行转义(所以,即使单引号字符串也会被解析)。
  2. 双引号字符串将显示一系列转义序列(包括一些正则表达式),并且字符串中的变量将被求值。重要的是,可以使用花括号来隔离您想要求值的变量名称。例如,假设您有一个名为$type的变量,您想要echo "The $types are"。那么它将寻找变量$types。为了避免这种情况,可以使用echo "The {$type}s are"。请参见字符串解析以了解如何使用数组变量等。
  3. Heredoc字符串语法与双引号字符串类似。它以<<<开始。在此运算符之后提供标识符,然后是换行符。接下来是字符串本身,然后是相同的标识符以关闭引号。在这种语法中,不需要转义引号。
  4. Nowdoc(自PHP 5.3.0起)字符串语法基本上与单引号字符串相似。区别在于即使单引号或反斜杠也不必转义。nowdoc使用与heredocs相同的<<<序列进行标识,但是其后跟随的标识符用单引号括起来,例如<<<'EOT'在nowdoc中不进行解析

注意:单引号字符串中的单引号和双引号字符串中的双引号必须进行转义:

$string = 'He said "What\'s up?"';
$string = "He said \"What's up?\"";

速度:
没有任何区别。
请阅读一篇可信的文章,来自PHP核心开发人员之一。在测试方面,我们不应该轻信它们。必须理解编写可信测试,尤其是解释其结果需要大量知识和经验。这意味着大多数测试都是错误的。例如,在如下代码中:

for($i=0;$i<100000;$i++) {
    'string';
}

引号包含的字符串只会被解析一次,与整个脚本一起转换成操作码。然后该操作码将被执行一百万次。因此,它测量的不是解析时间,而这仅仅是冰山一角。对于像这样的微型基准测试,几乎不可能创建一个可靠的测试,因为某些干扰性副作用会破坏测试结果。


33
对于花括号技巧加一。以前并不知道。可惜它不遵循与shell脚本相同的惯例,即${变量名} - devios1
7
我只在需要用到\n时才使用双引号,在我的PHP代码中,其他任何内容都用单引号。 - Jo Smo
似乎'heredoc'是从bash移植到PHP的,或者不是吗?无论如何,这是一个很好的答案,所以加一分。谢谢。 - sjsam
6
在 PHP 文档评论中有一个有趣的注释:http://php.net/manual/en/language.types.string.php#120160 -“双引号字符串”因为要解析所有的 \n 反斜杠和 $ 美元符号来进行变量扩展,所以看起来很慢,但事实证明它们是 PHP 中最快的字符串连接方法——没有其他方法能超过它!单引号仅在你的字符串完全是文字(没有需要解析或连接的内容)时才更快,但差距非常小,不重要。 - dregad
3
注意:现在双引号 " 速度变慢的情况已经几乎不存在了。目前,更新已经让大多数情况下双引号的处理速度跟其他字符一样快了。 - SherylHohman
显示剩余6条评论

250

在双引号中的内容会被计算,但是单引号中的不会:

$s = "dollars";
echo 'This costs a lot of $s.'; // This costs a lot of $s.
echo "This costs a lot of $s."; // This costs a lot of dollars.

1
转义的单引号和转义的反斜杠即使在单引号字符串中也会被展开。 - Peter Ajtai
52
很多刚接触 PHP 的开发者容易犯一个错误:$mailbody = 'I want a line break:\nDone.'; 会保留 \n ,而 $mailbody = "I want a line break:\nDone."; 则会解析出换行符。请注意区分使用单引号和双引号。 - Avatar
2
我的建议仅适用于面试或恶意软件开发。只需比较两个表达式的var_dump():$testWithAsciiAndUtf8Characters = "\x48\x41\x4c\114\117 \u{0147}\u{012B}\u{0144}\u{014D}!";$simpleTest = '\x48\x41\x4c\114\117 \u{0147}\u{012B}\u{0144}\u{014D}!';$testWithAsciiAndUtf8Characters中的字符序列被转换为具有实际字母的字符串。 - Rostyslav Pylypenko

74

' 单引号

指定字符串最简单的方法是用单引号将其括起来。单引号内的所有内容都被视为纯字符串。

示例:

echo 'Start with a simple string';
echo 'Variables $var and escape sequences \n do not get interpolated';
echo 'You only need to escape the quote \' and a backslash itself\\';

" 双引号

双引号字符串可以插入变量和各种转义序列。请注意:使用花括号 {} 来包含复杂变量或者在变量后面的字符是一个合法变量名字符时。

示例:

echo "Start with a simple string";
echo "String's apostrophe";
echo "Escape sequences get interpolated\n";
echo "Variables $var get interpolated as well {$name}_sake";

在PHP中,单引号和双引号有性能优势吗?

没有。

为了提高性能,PHP会一次解析整个代码,然后将结果的字节码存储在opcode缓存中。这种方法除了任何引用字符串外,还会消除整个解析过程。


1
单引号字符串中唯一的例外是,你可以使用 \' 转义单引号以在字符串内部使用它(或者使用 \\' 显示反斜杠)。请注意,传统的转义序列,如 \n 不会被解析为换行符。PHP 字符串文档 - SherylHohman
我在所有答案中都看到:您可以在双引号内使用变量名称来打印变量的值,但是您正在说,变量名称还应该被括在花括号中,以避免使用连接点。因此,如果"$my_var"和"{$my_var}"都输出$my_var的值,那么大括号有什么用?谢谢! - Bahman.A
1
@Bahman.A 我知道这已经过去了几年,你可能已经知道答案了,但以防其他人在未来寻找同样的东西:花括号分支主要是为了代码的可读性而在双引号中使用变量时添加的。当快速扫描以理解它是一个变量而不是字符串文字时非常有用。 - William Patton
@Bahman.A 我认为你使用"{$one}"而不是"$one"的原因不是阅读性,而是确切的变量查找。{ }也允许数组和对象查找。用于连接字符串的点运算符仍然需要用于函数查找。 - Justin
它还允许您编写 {$foo}bar,因为 $foobar 会被解释为 {$foobar} - alexia

44

单引号字符串中的变量不会被解释。而双引号字符串会解释其中的变量。

此外,双引号字符串可以包含省略反斜杠的单引号,而单引号字符串可以包含未转义的双引号。


10
单引号字符串在内存使用上更加高效。在PHP中处理字符串的最快方式是使用单引号,并使用“.”操作符连接字符串和变量。 - RibaldEddie
嗯,如果我错了,请纠正我,但是PHP的基础语言是C,对吧?那么为什么PHP和C中的字符串引号不同呢? - rob waminal
2
@rob waminal:PHP 可以在 C 中实现,但它是一种不同的语言。PHP 语言规定了这些语义。 - Borealid
@Ribald - 现在文档语法不是更快吗?单引号字符串会解析转义的单引号和反斜杠。 - Peter Ajtai
@Peter,你可能是正确的,我从未真正深入研究过它。PHP文档声称其速度很快,我决定相信这些文档。 :) - RibaldEddie
1
@RibaldEddie 现在这可是新鲜事啊。有什么证据吗? - Your Common Sense

37

在PHP中,'my name'"my name"都是字符串。你可以在PHP手册中了解更多相关信息。

你需要知道的是:

$a = 'name';
$b = "my $a"; == 'my name'
$c = 'my $a'; != 'my name'
在PHP中,人们使用单引号来定义一个常量字符串,比如 'a''我的名字''abc xyz',而使用双引号来定义一个包含标识符的字符串,例如 "a $b $c $d"

13

这两种封闭字符都是字符串。一种引号方便地用于封闭另一种引号。"'"'"'。这两种引号的最大区别在于,双引号中包含的标识符引用会被替换,但单引号中不会。


4

有些人可能会觉得我离题了,但是这里还是要说一下:

你不需要因为字符串内容而在以下选项中做出选择:
echo "It's \"game\" time."; 或者 echo 'It\'s "game" time.';

如果你熟悉英文引号的使用及正确的撇号字符,那么你可以使用双引号或单引号,因为它们都不再重要:
echo "It’s “game” time.";echo 'It’s “game” time.';

当然,如果需要添加变量的话也可以。只要记住,当在双引号内时它们才会被计算!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接