PHP 定义字符串
什么是字符串?
"字符串"就是一串字符。
PHP声明字符串,及注意事项
1. 在PHP中一个字符,比如 'a' 和多个字符,比如 "this is a demo" 都是字符串(java里面单个字符叫char类型,多个字符组成的叫string类型)
2. 声明一个字符串,必须使用 '单引号' 或 "双引号" 引起来
3. PHP里面字符串没有长度限制,""可以是空字符," "可以是空格,
只要服务器内存允许,可以无限长(C语言中对字符串有很明确的长度要求,char str[10] 这个字符只能是10个)
4. 在单引号中可以使用双引号,在双引号中也可以使用单引号
5. 在单引号定义的字符串中,不能再使用单引号。在双引号定义的字符中,不能再使用双引号(就像在多行注释里面,不能在嵌套多行注释)
6. 可以使用转义字符 \ ,转义字符后面的,就要转义的字符
PHP定义字符串有三种方式
双引号
单引号
定界符
一、"双引号"声明字符串
用双引号定义的字符串
$str = "hello world"; echo $str; // hello world
双引号定义的字符串里面,再出现双引号,PHP报语法解析错误
$str = "hello ,"world""; echo $str; // Parse error: syntax error, unexpected 'world' (T_STRING) in…… /** * Parse error: syntax error, unexpected 'world' (T_STRING) * syntax 语法的意思 * */
这个错误的原因很简单
1). 我们用双引号做字符串的定界符(边界符)
2). "hello ,"这个字符串就已经结束了,所以后面的world""就出错了
用"双引号"声明字符串的时候,字符串内部不能再出现"双引号",因为"双引号"被当成字符串的边界来对待,
所以字符串内出现双引号,就引起了解释上的歧义,导致了语法错误
双引号定义的字符串内,如果就想出现双引号,有什么办法呢?
可以用转义字符 \,转义双引号之后再执行(转义字符是键盘"回车键"上面的那个"斜线")
转义字符
从字面上分析,转义是改变他本来的意思
转义字符可以将没有意义的字符变成有意义的,也可以将有意义的字符变成没有意义的字符。
比如,双引号和单引号就是有意义的,可以声明字符串用,是一个定界符的作用,但是想让引号变成没有意义,直接用转义字符
\" 就失去了引号声明字符串的作用,而变成了一个普通的字符,把原来的意义给转没了
所以转义字符可以,让双引号嵌套双引号,单引号嵌套单引号
// \" 双引号前加一个反斜线,来转义双引号 $str = "hello ,\"world\""; echo $str; // hello ,"world"
反斜线当做转义字符来理解,如果想输出 \ 反斜线本身,怎么办呢?
可以把转义字符本身给转义了,用两个反斜线 \\ ,来表示一个反斜线 \
$str = "hello \\world"; echo $str; // hello \world
转义字符,还可以将没有意义的字符,转义成有意义的字符
比如字母n,t,r没有意义,但是字母前加上转义符后 \n,\r,\t
字符串 this\ris\nPHP\tstring ,在'单引号'定义的字符串里面,是原样输出的
$str = 'this\n\ris\nPHP\tstring'; echo $str; // this\n\ris\nPHP\tstring
如果是双引号定义的字符串,再看一下
$str = "this\n\ris\nPHP\tstring"; echo $str; // this is PHP string
没看出什么效果,只是多空格,因为HTML对多个空格、多个回车当做一个空格使用,所以看不出什么效果。
但是,右键查看源代码
\n 换行
\r 回车
\t tab键
所以\n,\r,\t这些符号都有意义,当然还有一些其它的符号
下面做了一个的罗列:
Sequence | Meaning |
---|---|
单引号 | |
\' | 单引号 |
\\ | 反斜杠 |
双引号 | |
\" | 双引号 |
\n | 换行 |
\r | 回车 |
\r\n | 在window系统下换行、回车,要用\r\n两个,在linux下只用\n就可以了,都是换到下一行去 |
\t | 水平制表 tab键 |
\v | 垂直制表 tab键 |
\f | 换页 |
\$ | 美元Dollar符号 |
\[0-7]{1,3} | 此正则表达式序列,匹配一个用八进制符号表示的字符 |
\x[0-9A-Fa-f]{1,2} | 此正则表达式序列,匹配一个十六进制符号表示的字符 |
\n\r 转义的意义
$str = "hello\n\rworld"; echo $str; // hello world
有一个空格,没看出转义的意义
\n\r\n\r\n\r 重复写三次,页面还是一个空格的效果,所以 \n\r 和空格关系不大
$str = "hello\n\r\n\r\n\rworld"; echo $str; // hello world
\n\r 转义体现在哪呢?
按道理说应该是换行、回车,为什么没看出效果呢,点击右键查看源代码
hello之后空了两行后才有world
所以连续三次 \n\r ,连续三次换行回车
在字符串中嵌套变量
在js语言中,在字符串里面使用一个变量,需要用链接符去链接变量,PHP里面也有字符串链接符号(链接运算符),这里暂时不用链接符号,直接在双引号定义的字符串里面用变量。
双引号字符串里面的变量可以解析出来
$var = '\\world'; $str = "hellow $var"; echo $str; // hellow \world
单引号字符串不能解析变量
$var = '\\world'; $str = 'hellow $var'; echo $str; // hellow $var
如果变量$var前面没有空格,变量还可以解析出来
$var = '\\world'; $str = "hellow$var"; // $var与'hellow'没有空格,贴在一起 echo $str; // hellow\world
这次$var变量在中间,前后都没有空格,这次就解析不出来了
$var = 'world'; $str = "hellow$varaaa"; // 变量$var前后都没有空格 echo $str; // Notice: Undefined variable: varaaa in……
变量和字符串混在一起了,没有截断点隔开,PHP就认为$varaaa是一个变量名,
Notice不是太严重的错误(不是致命的错误,只是注意),只是提示这个$varaaa变量没有定义
怎样才能解析出$var这个变量?
用合法的变量名之外的符号,合法的变量名有字母、数字、下户线
合法变量名不能用在这做间隔,可以用特殊字符把变量$var隔开
空格,算是一个特殊字符 "hello$var aaa"
逗号,算是一个特殊字符 "hello$var,aaa"
井号,算是一个特殊字符 "hello$var#aaa"
括号,也算是一个特殊字符 "hello$var)aaa"
注意,中括号不算是一个特殊字符 "hello$var[]aaa" ,因为PHP数组中,中括号属于合法变量名中数组的下标,中括号会被解析
用特殊字符把变量$var隔开,字符串中$var变量被解析出来
$var = 'world'; $str = "hello$var,aaa"; echo $str; // helloworld,aaa
但是有的程序里面不需要空格,还要把$var变量解析出来怎么办?
这个时候使用花括号,PHP程序会认为{$var}是一个变量,就可以解析出来
$var = 'world'; $str = "hello{$var}aaa"; // 使用花括号{} echo $str; // helloworldaaa
花括号的位置在"hello${var}aaa"这里也可以,但通常是用上面{$var}的方式
双引号里面在解释字符串的时候,遇到花括号就把里面单独当成一个区域去分析,不会连在一起了
$var = 'world'; $str = "hello${var}aaa"; echo $str; // helloworldaaa
单引号定义的字符串里面是不能解析变量的,所以用不用大括号都没有效果的。
$var = 'world'; $str = 'hello${var}aaa'; echo $str; // hello${var}aaa
所以单引号字符串里面不能解析变量,也不认这种花括号
一般在双引号字符串里面嵌套变量,尽量使用花括号{}
$int = 10; $str = "this \$int = {$int} \\is s demo"; echo $str; // this $int = 10 \is s demo
\$var 变量前面加一个反斜线,也不能解析变量了
$var = '\\world'; $str = "hello \$var"; // $符号被给转义成了普通字符串"$" echo $str; // hello $var
把$符号的意义给转了,就没有变量的含义了
二、'单引号'声明字符串
$str = 'hello'; echo $str; // hello
在'单引号'里面再出现'单引号',就会出现了语法错误(就像在多行注释里面,不能再嵌套一个多行注释)
$str = 'hello 'world''; echo $str; // Parse error: syntax error, unexpected 'world' (T_STRING) in……
问题和双引号的一样,
PHP认为'hello '是一个完整的字符串,后面的world'',PHP语法就无法识别了,会提示解析错误
用'单引号'定义字符串,想在字符串内出现'单引号',还是用转义来表示
$str = 'hello \'world\''; echo $str; // hello 'world'
既然转义字符能在单引号里面,可以转义单引号。说明转义字符在单引号里面还是可以用的,还可以把转义字符本身也给转义了(转义自己)。
直接一个反斜杠,什么作用都没有
$str = 'hello \world'; echo $str; // hello \world
两个反斜杠,虽然效果上没有变化,但是让转义字符本身,失去了转义的意义
$str = 'hello \\world'; echo $str; // hello \world
单引号和双引号的区别
1. 字符串中嵌套变量,在双引号中可以解析变量,而在单引号中不能解析变量
2. 在双引号中,可以使用转义字符\r,\n,\t,
单引号里面虽然不支持\r,\n,\t 等这些转义字符,但是转义字符在单引号里面,只能转义单引号自己 \' ,还能转义转义字符本身 \\
$age = 29; $str1 = 'hello \n\r \t $age'; $str2 = "hello \n\r \t $age"; echo $str1, '<br/>'; // hello \n\r \t $age echo $str2; // hello 29
右键看源码,看的更清晰,字符串$str2,29前空出那块空格是tab的作用
在双引号里\n \r \t都被当成了,换行符,回车符,制表符来处理了,而单引号就直接给显示出来了
单引号:系统不做复杂的转义,只转义\',\\,其他的一律原样输出
双引号:转义的比较多,\", \\, \r, \n, \r, \$……等
常见的面试题
1、单引号 和 双引号定义字符串有什么不同
2、单引号 和 双引号定义字符串,那个速度更快些?
双引号功能强大,单引号功能简单,但是功能越强,消耗的系统资源越多,功能简单的效率越高。
所以平时开发的时候,能用单引号的地方就尽量用单引号,大量的字符串通常使用单引号。
如果就几个字符串效率差不了多少,但是代码里面有几百条、几千条字符串时,都没注意这个细节,那么整个脚本的速度就会比注意细节的慢很多。
变量解析的区别
单引号不对字符串内的,$变量名进行解析
而双引号,会试着把$理解成变量名来解析
单引号,双引号的选择原则:
什么时候去选择单引号或是双引号呢?
大段文本、新闻标题,自我介绍等这样一大段话,用单引号解析快
有的时候,需要在一段字符串中夹杂变量,一般用双引号
比如拼接sql语句
$name = $_POST['name']; $sql = "select * from tbname where name = $name";
单引号在java里面声明字符,用的单一的字符,双引号是声明字符串用的。PHP不分字符和字符串,统统都是字符串
还有在js里面单引号和双引号声明字符串,是完全一样的没有任何区别的。PHP单引号和双引号也都可以生成字符串,但生成的字符串是有区别的。
三、定界符号声明字符串
PHP的字符串没有长度限制,
当需要写一段文本,甚至是多行,里面有很多单引号,有很多双引号,转义的时候非常麻烦
声明字符串还有第三种方法叫定界符号
定界符号有heredoc和nowdoc两种方式
heredoc方式语法:
<<<标识符
中间写大段文本
标识符;
注意:
1.标识符的名称和变量名的要求一样,不能以数字开头
2.heredoc的结束符,一定是独占一行,
而且前面不能有其它字符,包括空格
3.heredoc方式对文本的处理,和双引号一样,\r,\n,\t,$变量等能解析出来
/** * heredoc语法: * <<<hello 先写三个小于号,再写一个自己命名的字符串(叫标记符)比如hello(这个hello后面连空格都不能有,直接回车) * 中间是大量多行字符串…… * hello; 在结尾写hello结束,直接回车也不能有空格 * */ $name = '——尼古拉特斯拉'; $str = <<<hello 宇宙是一个完整的有机体,它包含着数目庞大的组成部分,\r\n 它们非常相似,但振动的频率并不相同,\r\n 每一个部分都是彼此平行的世界,当我们与他的频率发生共振,\r\n 就等于打开了通往这个世界的大门,我们可以任意穿越整个宇宙。\r\n \t\t\t\t\t\t\t\t\t\t\t\t$name hello; echo $str;
heredoc方式打印code,里面的<pre>标签被解析生效了
$str = <<<cont <pre> // 要打印this里面的foo,要生成的对象去访问。 var foo = '123'; function print(){ //var this = Object.create(print.prototype) this.foo = '234'; console.log(foo); } var obj = new print(); // 123 console.log(obj.foo); // 234' </pre> cont; echo $str;
nowdoc方式
heredoc对大段文本内的\n、\r、\t、变量的解析很方便,但是如果不想解析这些,
到了PHP5.3后新增了nowdoc方式,跟单引号一样,不解析\n、\r、\t、$变量等
nowdoc写法和heredoc写法一样,
nowdoc在标识符两边用单引号包起来,这样大段的文本解析,就和单引号一样的效果了,不取转义\n,\r,\t,变量等等
$name = '——尼古拉特斯拉'; $str = <<<'title' 宇宙是一个完整的有机体,它包含着数目庞大的组成部分,\r\n 它们非常相似,但振动的频率并不相同,\r\n 每一个部分都是彼此平行的世界,当我们与他的频率发生共振,\r\n 就等于打开了通往这个世界的大门,我们可以任意穿越整个宇宙。\r\n \t\t\t\t\t\t\t\t\t\t\t\t$name title; echo $str;