Go to comments

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对多个空格、多个回车当做一个空格使用,所以看不出什么效果。

但是,右键查看源代码

image.png

\n 换行

\r  回车

\t  tab键

所以\n,\r,\t这些符号都有意义,当然还有一些其它的符号


下面做了一个的罗列:

SequenceMeaning
单引号
\'单引号
\\反斜杠
双引号
\"双引号
\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

image.png

所以连续三次 \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;



Leave a comment 0 Comments.

Leave a Reply

换一张