PHP 字符串相关常识
0x00 前言
第一次遇见字符串这个概念是在学 C 语言的时候,那时候觉得字符串也没有什么难的,不就是一个以 \0 结尾的 char 数组而已咯。后来在学习 PHP 的过程中也同样保持这个观念,不过在字符串还是纯英文的时候还是没什么问题的,但后面遇到要处理中文的时候就事故频发,然后搜索结果里的字符集、字符编码、多字节字符串、二进制安全各种概念搞得一头雾水,虽然最后的搜索结果都附有了解决方案但我还是觉得对于相关的知识需要理解和总结。
0x01 字符集
字符集(全称是编码字符集)是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。字符集都可以用「一张或多张二维表」表示,比如:ASCII 是很常见的一个字符集,一提起它我们应该都能想到下面这张图。我们可以看见每一个字符都对应有一个二进制编码。

因为ASCII 字符集上的编码和字符编码是一样的,然后很多刚学习的人就把字符集和字符编码给弄混淆了。但是实际上字符集和字符编码是不同的概念。
0x02 字符编码
由于历史原因,在早期字符集其实和字符编码是同义的,因为字符集的编码就是对应字符实际储存的值,直到 Unicode 的出现,因为 Unicode 有好几种不同的字符编码,比如:UTF-8、UFF-16、UTF-32。然后字符编码的概念就出来了,字符编码是字符集和实际存储数值之间的转换关系,也就是说字符编码是定义在字符集上的映射规则。然后我就开始有点头晕了/(ㄒoㄒ)/~~,字符编码 UTF-8 和字符集 Unicode 到底是什么关系?
实际上我们可以说UTF-8 是 Unicode 的一种实现方式。云服务器Window Server 2012R系统安装MySQL的详细教程
我们可以查到在 Unicode 码表中,「国」字对应的十六进制编码是 0x56FD 但是如果我们新建一个文本文件,输入一个「国」字并用 UTF-8 的字符编码储存,然后以十六进制的方式查看该文件,我们会发现储存的并不是 0x56FD 而是 0xE59BBD。因为字符集的编码通过某种规则转换为了实际存储的数据,这里的某种规则即是字符编码。下面一图可以看出字符集和字符编码的不同。

既然字符集已经有编码了(而且很多字符集的字符编码和字符集上的编码一样),那为何要多此一举搞个字符编码出来?因为如果直接采用字符集上的编码,那么像 Unicode 之类的字符集,它的每个字符都需要三个字节储存,而对于一些常见的字符(比如:英文字母)来说用三个字节储存无疑是很浪费空间的。而通过 UTF-8 字符编码便可以将常见的字符采用较少的字节编码,而不常用的字符就采用较多的字节编码,达到节约储存空间的目的。
0x03 多字节字符串
PHP 在处理非英文的字符串时,部分字符串相关的函数可能会经常出现问题,因为 PHP 中处理字符串的函数默认假设所有字符都是 8 位字符,占用一个字节。而中文至少要用两个或三个字节储存(使用 UTF-8 编码),所以经常会出错。比如 strlen 函数在测试中文字符串时得到的是字节长度而不字符长度,所以我们应该利用 mbstring 拓展 提供的多字节字符串函数进行处理。
0x04 二进制安全
在浏览字符串处理函数的过程中我们常常会看到一个词「二进制安全」,听着感觉很高大上的样子然后网上对它的解释如下:
二进制安全是一个主要用来处理字符串操作的编程术语。二进制安全功能本质上是把输入当作一个没有任何特殊的原生流,其在操作上应包含一个字符所能有的256种可能的值(假设为8为字符)。
听着有点似懂非懂的样子,但和 C 语言的字符串作对比之后就比较明白了。
C 字符串中的字符必须符合某种编码(比如 ASCII),并且除了字符串的末尾之外,字符串里面不能包含空字符,否则最先被程序读入的空字符将被误认为是字符串结尾 ——这些限制使得 C 字符串只能保存文本数据,而不能保存像图片、音频、视频、压缩文件这样的二进制数据。
也就是说在二进制安全的函数操作里 \0 并不会看做字符串的结尾,字符串中所有的数据都没有特殊的含义。所以 PHP 的 strlen 函数能获取包含空字符的字符串长度,而 C 语言却不行。当然 PHP 里也有非二进制安全的函数,所以在使用某些函数前还是要注意函数是否是二进制安全的。如下例:
<?php
$str1 = "good";
$str2 = "good\0bad";
var_dump(strcoll($str1, $str2));
// 非二进制安全,输出 0
var_dump(strcmp($str1, $str2));
// 二进制安全,输出 -4
写这篇文章的时候真的觉得很难写( ⊙ o ⊙ )啊!感觉自己还是说的不清不楚的样子,还没有网上的资料讲得好。但进行一下总结起码能够加强记忆吧/(ㄒoㄒ)/~~。有错的地方希望有人能够提出来(但我觉得应该都不会有人来看我的博客的233,更不会有评论)。0x05 总结
0x06 参考资料
文章转自:https://www.0php.net/posts/PHP-字符串相关常识.html
PHP 字符串相关常识的更多相关文章
- 常用linux 命令 -字符串相关
参考网络文章,个人工作总结 题记:一般对字符串的操作有以下几种:求长度,截取字符串,拼接字符串,找字符串中某个字符的索引 1 expr 命令 1.1 定义 man 手册 Print the value ...
- 【Todo】字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树
另开一文分析字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树. 先来一个汇总, 算法: 本文中提到的字符串匹配算法有:KMP, BM, Horspool, Sunday, BF, ...
- python中跟字符串相关的一些操作
公司让用python自动生成代码,以前没看过python.所以匆匆的看了两天python就连猜带蒙就上马开干了..因此好多操作可能看的时候看懂了,用的时候知道有这么个东西,具体用法就忘记了..用到了就 ...
- IP相关常识
IP相关常识 一. IP地址概念 IP地址是一个32位的二进制数,它由网络ID和主机ID两部份组成,用来在网络中唯一的标识的一台计算机.网络ID用来标识计算机所处的网段:主机ID用来标识计算机在网段 ...
- ES6字符串相关扩展
变量的解构赋值 // 数组的解构赋值 let [a,b,c] = [1,2,3]; //1,2,3 let [a,b,c] = [,123,]; //undefined 123 undefined l ...
- Java数据结构和算法总结-字符串相关高频面试题算法
前言:周末闲来无事,看了看字符串相关算法的讲解视频,收货颇丰,跟着视频讲解简单做了一下笔记,方便以后翻阅复习同时也很乐意分享给大家.什么字符串在算法中有多重要之类的大路边上的客套话就不多说了,直接上笔 ...
- PHP基础系列(一) PHP字符串相关的函数分类整理
PHP提供了非常丰富的自带函数,有人说PHP是一个大的函数库,在某种程度上我是非常认同这种观点的,这个也是PHP非常容易上手的原因之一.在使用PHP编程的时候,需要实现某一功能的时候,如果说php自带 ...
- python字符串、字符串处理函数及字符串相关操作
python字符串.字符串处理函数及字符串相关操作 字符串介绍 python字符串表示 Python除处理数字外还可以处理字符串,字符串用单撇号或双撇号包裹: >>> 'spam e ...
- java常用类详细介绍及总结:字符串相关类、日期时间API、比较器接口、System、Math、BigInteger与BigDecimal
一.字符串相关的类 1.String及常用方法 1.1 String的特性 String:字符串,使用一对""引起来表示. String声明为final的,不可被继承 String ...
随机推荐
- 配置java开发环境,存在多个版本JDK时,怎样让所需版本生效
我本地有个1.7.0的java版本,后来我新装了一个13的版本,但是命令行查java版本的时候,生效的还是1.7.0的版本,经过资料查询以及自身亲测,现将过程记录如下: 1.电脑右键选择--属性--高 ...
- reactstrap,scrollbar组件
react-script 编译,部署,sass,less,test,helmet等 https://github.com/facebookincubator/create-react-app/blob ...
- 运维日常之机房浪潮服务器硬盘红灯亮起,服务器一直响,raid磁盘红色。。。故障解决方法
按Ctrl+H进入到WebBIOS内,看见的错误如下所示: 错误是PDMissing,只不过维护的IBM服务器错误的磁盘不是第一块,而是第三块而已,不过坏哪块硬盘没有影响,重要的是错误的原因.这种错误 ...
- [转帖]LSB
LSB 简介 冯 锐2006 年 8 月 07 日发布 https://www.ibm.com/developerworks/cn/linux/l-lsb-intr/ 学习一下 之前 不知道LSB_R ...
- Maven - 配置setting.xml
1.配置本地库路径 <localRepository>C:/fyliu/mvn/repo</localRepository> 2.配置中央仓库 <mirror> & ...
- LayUI 多选框动态加载、启用、禁用、赋值、取值等js实现
例如多选框如下: <div class="layui-form"> <select xm-select="city"> </sel ...
- [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)
[BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...
- hibernate-HQL连接查询 转载sincoolvip
和SQL查询一样,HQL也支持各种各样的连接查询,如内连接.外连接 连接类型 HQL语法内连接 inner join 或者join迫切内连接 inner join fetch 或join fetch左 ...
- uoj218_火车管理
题意 \(n\)个位置,每个位置一个栈,三种操作,询问区间栈顶的和,区间入栈某个数,单点出栈某个数. 分析 用一个线段树来维护栈顶的和,区间(单点)更新和区间询问. 用一个主席树来维护每个位置最新一次 ...
- Jpa/Hibernate 字节码增强:字段延迟加载
JPA提供了@Basic注解,实现延迟加载字段的功能,如下: @Basic(fetch = FetchType.LAZY) @Column(name = "REMARK_CONTENT&qu ...