PHP 高级面试题 - 如果没有 mb 系列函数,如何切割多字节字符串
需求
如果需要将可能含有中文的字符串进行拆分成数组,我们下面以 utf-8 编码为例。
解决方案一
我习惯的方法可能是:
mb_internal_encoding("UTF-8");
$str = "周梦康";
$array = [];
for ($i=0,$l = mb_strlen($str); $i < $l; $i++) {
array_push($array, mb_substr($str, $i, 1, "utf-8"));
}
var_export($array);
假如我们没装mb扩展怎么办?
解决方案二
今天看到一份代码,别人是这么写的:
function str_split_utf8($str)
{
$split = 1;
$array = array();
for ($i = 0; $i < strlen($str);) {
$value = ord($str[$i]);
if ($value > 127) {
if ($value >= 192 && $value <= 223) {
$split = 2;
} elseif ($value >= 224 && $value <= 239) {
$split = 3;
} elseif ($value >= 240 && $value <= 247) {
$split = 4;
}
} else {
$split = 1;
}
$key = null;
for ($j = 0; $j < $split; $j++, $i++) {
$key .= $str[$i];
}
array_push($array, $key);
}
return $array;
}
代码解读
strlen计算的是字节数,而直接使用$str[x]就沿用了c语言里面char数组和字符串的习惯,表示按字节来读取$str,也就是说每次读取的数据的ascii码值不可能大于255。而php里使用ord来获取ascii码值。
切割规则如下

为什么呢?
Unicode
Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。
UTF-8
UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8 的编码规则很简单,只有二条:
- 对于单字节的符号,字节的第一位设为
0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的(能容纳0~127)。 - 对于
n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。
下表总结了编码规则,字母x表示可用编码的位:

想必看了这个表,大家就能明白了吧。
以上是文章全部内容,有需要学习交流的友人请加入交流群的咱们一起,有问题一起交流,一起进步!前提是你是学技术的。感谢阅读!
PHP 高级面试题 - 如果没有 mb 系列函数,如何切割多字节字符串的更多相关文章
- php高级面试题知识点(转载)
php高级面试题知识点大全 时间:2016-01-26 06:36:22来源:网络 导读:php高级面试题知识点大全,本套面试题内容包括php魔术方法.php单点登录.linux基本命令.前端开发技术 ...
- 多线程面试题系列(3):原子操作 Interlocked系列函数
上一篇中讲到一个多线程报数功能.为了描述方便和代码简洁起见,我们可以只输出最后的报数结果来观察程序是否运行出错.这也非常类似于统计一个网站每天有多少用户登录,每个用户登录用一个线程模拟,线程运行时会将 ...
- Java高级面试题解析(一)
最近,在看一些java高级面试题,我发现我在认真研究一个面试题的时候,我自己的收获是很大的,我们在看看面试题的时候,不仅仅要看这个问题本身,还要看这个问题的衍生问题,一个问题有些时候可能是一个问题群( ...
- js经典试题之w3规范系列
js经典试题之w3规范系列 1:w3c 制定的 javascript 标准事件模型的正确的顺序? 答案:事件捕获->事件处理->事件冒泡 解析:先事件捕获从windows > doc ...
- 2019-11-19-C#-高级面试题
title author date CreateTime categories C# 高级面试题 lindexi 2019-11-19 08:40:50 +0800 2018-11-12 11:18: ...
- 第8章 用户模式下的线程同步(1)_Interlocked系列函数
8.1 原子访问:Interlocked系列函数(Interlock英文为互锁的意思) (1)原子访问的原理 ①原子访问:指的是一线程在访问某个资源的同时,能够保证没有其他线程会在同一时刻访问该资源. ...
- Winsock系列函数 及 Socket通信流程
Socket是一种网络通信机制 Winsock系列函数 1. Socket 创建socket 2. Connect 尝试连接远端Socket 3. Send 在某个Socket 向远端 ...
- 原子操作 Interlocked系列函数
上一篇<多线程第一次亲密接触 CreateThread与_beginthreadex本质区别>中讲到一个多线程报数功能.为了描述方便和代码简洁起见,我们可以只输出最后的报数结果来观察程序是 ...
- (转)原子操作 Interlocked系列函数
上一篇<多线程第一次亲密接触 CreateThread与_beginthreadex本质区别>中讲到一个多线程报数功能.为了描述方便和代码简洁起见,我们可以只输出最后的报数结果来观察程序是 ...
随机推荐
- MySQL删除大表时潜在的问题(drop table,truncate table)
来源于:https://www.cnblogs.com/CtripDBA/p/11465315.html,侵删,纯截图,避免吸引流量之嫌 case1,删除大表时,因为清理自适应hash索引占用的内容导 ...
- TP随机从数据库中获取一条数据
orderRaw('rand()'): /** * 随机获取一条商品信息 * @param [type] $condition * @param [type] $field * @param [typ ...
- python 基础学习笔记(5)--文件操作
**python 的文件操作** - [ ] 使用python来读写文件是非常简单的操作,我们使用open()来打开一个文件,获取到文件的语柄,然后通过文件语柄就可以进行各种各样的操作了. - [ ] ...
- Oracle对时间的相关操作
目录导航: 1. 年操作 2. 月操作 3. 周操作 4. 天操作 5. 时操作 6. 分操作 7. 秒操作 1.年操作 SELECT add_months(SYSDATE, -12) FROM du ...
- WASM 成为 HTML、CSS 与 JS 之后的第 4 门 Web 语言
大家都知道,万维网联盟 W3C 认证的 Web 语言有 HTML.CSS 与 JavaScript,而近日联盟正式宣布 WebAssembly 核心规范(WebAssembly Core Specif ...
- Docker和ASP.NET Core
Docker和ASP.NET Core Docker 正在逐渐成为容器行业的事实标准,受到 Windows 和 Linux 生态系统领域最重要供应商的支持. (Microsoft 是支持 Docker ...
- ETCD:实验特性和APIs
原文地址:Experimental features and APIs 大多数情况下,etcd项目是稳定的,但我们仍在快速发展! 我们相信快速发布理念. 我们希望获得有关仍在开发和稳定中的功能的早期反 ...
- oracle相邻表记录交换(单双两两交换)
在博客园的博问中看到了一个这样的提问:一个表中有id和name两个字段,id是连续非空不重复的,想要交换相邻表记录的name值(单双两两交换). 另外,如果最后的单独行没有对应的下一行匹配记录的话,就 ...
- 记一次Ubuntu19无法安装docker源
按照各大网站以及个人习惯我会使用下面这种方法添加Docker源: root@ubuntu:~# sudo add-apt-repository "deb [arch=amd64] https ...
- windows下cocos2d-x环境搭建
该教程使用的cocos2dx的版本为3.14,3之后的大概都差不多 Python环境搭建: cocos2dx在windows上新建工程需要用到python脚本,安装python-2.7.x,可以上py ...