php基础-变量解析与字符转义

因项目原因,碰巧遇到了一些关于php中字符转义的问题;鉴于此,本次分享我们主要来一起学习下php语言中与变量解析、字符转义有关的基础;在此基础上,分析一个很有意思的字符串案例,最后分享一款超实用的Linux小工具:xxd;

我们知道,在php中,如果想定义一个字符串变量的话,可以使用一个单引号'',也可以使用一个双引号"",即:

$var = 'abc'; 或 $var = "abc";

这两者一般而言,效果上没有太多区别,最本质的区别就是:双引号的字符串中如果包含变量,则在执行时变量会被解析,脑补文档见下;

直接上代码,示例如下:

a.php,输出为 $a

$a = "hello";

echo '$a';

b.php,输出为hello

$a = "hello";

echo "$a";

分享到这里,你也许想说,这么小儿科的语法东西,官网上都有,有必要演示吗? 其实本次分享的重点倒不是这个,主要想借此铺垫,然后一起来透析一下字符串在计算机中的二进制本质;

ok,分享到这里,我们来做个小测试,请大家分析一下以下程序会输出什么?

$var = "\x01\x02\x03\x04\x05\x06\x07\x08";

echo $var;

"\x01\x02\x03\x04\x05\x06\x07\x08"这个串,还有人说…

OK,我们来在控制台运行下该程序,我们发现肉眼没看到有任何输出;

奇怪,这里明明是给变量$var显式的赋值了呀?

那我们再用var_dump函数替换echo 关键字,即:

$var = "\x01\x02\x03\x04\x05\x06\x07\x08";

var_dump($var);

再次运行后,发现其实变量的确是有值,而且是长度为8的一个字符串,但是就是看不到具体的显示:

[root@jordy t]#

[root@jordy t]# php var.php

string(8) "

到这里,大家也许隐约感觉到,以上几种猜测可能都错了。

那到底给$var变量赋的这个字符串值的本质是什么?接下来,让我们以另外一个方式试着来探究它的本质;也许大家都猜到了,那就是将该变量的值写入的一个文件里面,代码见:

$var = "\x01\x02\x03\x04\x05\x06\x07\x08";

file_put_contents("/tmp/hex_data",$var);

exit("运行完毕\n");

[root@jordy t]# php save_hex.php

运行完毕

查看被写的数据文件及大小:

[root@jordy t]# du -b /tmp/hex_data

8 /tmp/hex_data

与之前结果吻合,占8个字节(byte)

用vim 打开该文件,看到:

^A^B^C^D^E^F^G^H

看着到挺像一些控制性字符,那到底是什么,让我么还是回到最初的官方文档来分析:

$var = "\x01\x02\x03\x04\x05\x06\x07\x08";

结合文档,我们知道,\x01代表一个用十六进制表示的字符,那转换为十进制的话,它代表十进制的1,而整个$var变量就表示十进制的1到十进制的8对应的ASCII码值所表示的字符,然后我们对照ASCII码表来查询一下,到底值为十进制1到8的ASCII码是什么字符:

这下一目了然了,1到8对应的字符清晰地见上述码表中;

在ASCII码中,1-31的字符都属于不可打印字符的范畴,所以我们虽然能看到该字符串所占的字节长度,但是却未能在控制台看到字符串的“样子”;

刚刚,我们把字符串写到了 /tmp/hex_data 文件中了。接下来,我们用xxd这个工具来透析一下该文件的二进制内容:

[root@jordy t]# xxd /tmp/hex_data

0000000: 0102 0304 0506 0708 ........

ok,我们清楚的看到,该文件里面存储了8个字符,并且是不可打印的字符,其对应的ASCII值用十六进制表示,分别为01 02 03 04 05 06 07 08

分享到这里,我想大家也应该明白了这个串的本质,同时也许感受到了计算机二进制世界的有趣之处吧;

作为引申,我们再来追加两个示例:

1.如果以同样的十六进制表示ASCII码值的方式,想输出字符串"abc",那应该如何写?

查看字a,b,c 对应的ASCII码,分别是97,98,99。转换为十六进制后,分别表示是61,62,63,则代码如下:

$var = "\x61\x62\x63";

echo $var."\n";

运行结果:

[root@jordy var]# php abc.php

abc

2.那如果以同样的方式想输出字符串“12345678”呢?对照ASCII码表,这几个字符对应的ASCII码分别为49,50,51,52,53,54,55,56,转为十六进制分别为31,32,33,34,35,36,37,38

对应代码见:

$var = "\x31\x32\x33\x34\x35\x36\x37\x38";

echo $var."\n";

运行结果:

[root@jordy var]# php num_str.php

最后,给大家隆重推荐下linux下的xxd 命令工具,该工具主要的功能就是可以以十六进制形式来查看一个文件内容的本质;工具虽小,但简单好用,功能丰富,是开发人员不可或缺的利器,具体文档见下(man xxd),感兴趣的话大家可深入研用:

本次分享关键词总结:ASCII码、十六进制、php字符串转义、xxd工具;

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181229G0PUWC00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券