PHP字符串你不知道的事

  • PHP常见的定义字符串的方式有那些?

    1、单引号

    在单引号中,任何特殊字符都会按原样输出【除\、\‘将会被转义输出】,不是什么都不解析的,这是很多人的误解

    echo 'this is a  var!'.PHP_EOL; //this is a  var!
    echo '6666$var666\n \t \b \\ \' \$';    //6666$var666\n \t \b \ ' \$
    
    

    2、双引号

    遇到$将会解析该变量,双引号中会转义反斜杠的转义字符;

    从理论上来讲单引号因为不需要解析$符号修饰的变量会快点

    3、heredoc(语法糖)

    $name = 'lis2';
    $str = <<<"EOF"
    $name\n
    真帅
    substr("aaaa",0,1);
    if($name=='lis'){
    echo 'true';
    }else {
    echo 'false';
    }
    EOF;
    echo $str; //里面的函数和判断都不会解析,变量会解析,相当于用双引号把内容括起来
    

    4、nowdoc(语法糖)

    $name = 'lis2';
    $str = <<<"EOF"
    $name\n
    真帅
    substr("aaaa",0,1);
    if($name=='lis'){
    echo 'true';
    }else {
    echo 'false';
    }
    EOF;
    echo $str;//相当于用单引号把内容括起来
    
  • 字符串和其他类型的转换

    echo null.PHP_EOL; //空字符串
    echo false.PHP_EOL; //空字符串
    echo true.PHP_EOL; //1
    echo 222; //222
    echo 333.0; //333
    
  • 字符串的获取

    $str = 'hello the beautiful world';
    echo $str[6] . "\n"; //t
    echo $str{6} . "\n"; //t
    echo $str[-1]; //d 最后一个,数组是不能通过-1这种方法获取
    
  • 变量的底层原理

    每一个php变量都会由变量类型value值引用计数次数和`是否是引用变量的zval结构体组成

    struct _zval_struct {
    	union {
    		long lval;
    		double dval;
    		struct {
    			char *val;
    			int len;
    		} str;
    		HashTable *ht;
    		zend_object_value obj;
    	} value;					//变量value值
    	zend_uint refcount__gc;   //引用计数内存中使用次数,为0删除该变量
    	zend_uchar type;		   //变量类型
    	zend_uchar is_ref__gc;    //区分是否是引用变量,是引用为1,否则为0
    };
    //PHP7
    

    好文推荐:

    PHP变量的内部引用

  • 字符串的最大长度

​ 自PHP 7.0.0起,对64位版本中的字符串长度没有特殊限制。在32位版本和较早版本中,字符串最大可以为2GB(最大2147483647字节)

  • 为什么说PHP不支持Unicode编码?

    官方文档原文:一个字符串 string 就是由一系列的字符组成,其中每个字符等同于一个字节。这意味着 PHP 只能支持 256 的字符集,因此不支持 Unicode

    PHP 中的 string 的实现方式是一个由字节组成的数组再加上一个整数指明缓冲区长度。也就是byte[]数组组成的

    $str = "李四";
    echo strlen($str);//6
    

    上面的代码如果是在utf-8编码格式下得出的结果,首先“李四”有两个字符“李”、“四”组成的,utf-8编码就是相当于一个表,全世界的每个符号(字符)都有一个值,经查的字符“李”对应的编码是E69D8E(一个数值,16进制的形式,十进制是15113614),“四”对应的编码是E59B9B,我们知道一个byte表示的单位是0-255,PHP如果想表示李这个字符,在utf-8编码格式下就要表示出15113614这个数就可以了,两个byte的最大长度的2^16 =65536,2^24 =16777216,所以三个byte可以表示“李”这个字符,同理字符“四”也是占用了三个byte,strlen是单字节函数,也就是计算的是占用字节byte数组的长度,划分的粒度是字节,所以也就是6了,同理如果是在gbk编码格式下得到的结果会是4。

    如果想要正常的计算,需要使用mbstring扩展,multi-byte(多字节)的缩写

    $str = '李四';
    echo mb_strlen($str);
    

    这个时候在看官方文档原文就可以这样理解:字符串要是0-255之间的字符我们可以看做每个字符一个字节,unicode超过了这个,所以不支持。

    字符串类型的此特性解释了为什么 PHP 中没有单独的“byte”类型 - 已经用字符串来代替了。返回非文本值的函数 - 例如从网络套接字读取的任意数据 - 仍会返回字符串。

    由于 PHP 并不特别指明字符串的编码,那字符串到底是怎样编码的呢?例如字符串 "á" 到底是等于 "\xE1"(ISO-8859-1),"\xC3\xA1"(UTF-8,C form),"\x61\xCC\x81"(UTF-8,D form)还是任何其它可能的表达呢?答案是字符串会被按照该脚本文件相同的编码方式来编码。因此如果一个脚本的编码是 ISO-8859-1,则其中的字符串也会被编码为 ISO-8859-1,以此类推。不过这并不适用于激活了 Zend Multibyte 时;此时脚本可以是以任何方式编码的(明确指定或被自动检测)然后被转换为某种内部编码,然后字符串将被用此方式编码。注意脚本的编码有一些约束(如果激活了 Zend Multibyte 则是其内部编码)- 这意味着此编码应该是 ASCII 的兼容超集,例如 UTF-8 或 ISO-8859-1。不过要注意,依赖状态的编码其中相同的字节值可以用于首字母和非首字母而转换状态,这可能会造成问题。

  • 字符串的二进制安全是什么意思?

    C语言中的字符串的结束标志是‘\0’,这个是时候是二进制不安全的,PHP字符串中包含‘\0’的时候不会认为是字符串结束

    更好的解释见:
    php的二进制安全

posted @ 2020-12-16 16:33  小刘的早餐店  阅读(115)  评论(0编辑  收藏  举报