php mb_strlen($str,‘utf8’) 会返回比 JavaScript .length 更大的结果吗?

问题描述 投票:0回答:1

我正在开发 Angular 17 反应式表单,将表单数据发送到服务器上的 PHP API 并将其存储在数据库中。 我希望用户能够在表单中输入表情符号,因此我将数据库设置为

utf8mb4_unicode_ci
排序规则,以便可以存储表情符号。

安全对我来说非常重要,所以我在客户端和服务器端对各种事情进行了多次检查。

我所做的检查之一是检查输入的长度。我想知道您是否可以提供帮助,因为客户端和服务器端的长度结果不一致(因为字符串包含表情符号)。

在使用 JavaScript

.length
属性以及名为
minLength
maxLength
的内置角度表单验证器时,我发现它们都以相同的方式计算长度(例如,大多数基本笑脸表情符号的计算方式为长度为 2)。

但是,当我将这些数据(包括表情符号)发送到服务器端时,我使用名为

mb_strlen($subject, 'utf8')
的 PHP 方法,并且值不同(大多数基本笑脸表情符号的长度计算为 1 并且它们占用数据库中有 1 个
varchar
字符)。

我测试了大约 160 个表情符号,看看它们在客户端和服务器端返回什么值,以便尝试找出一种模式(以便我可以以正确的方式检查长度)。

正如您从下面的屏幕截图中看到的,在大多数情况下,

mb_strlen($subject,‘utf8’)
返回的长度值比 JavaScript
.length
更低。有时它返回与 JavaScript
.length
属性相同的值,但在所有这些情况下
mb_strlen($subject,‘utf8’)
从未返回大于 JavaScript
.length
返回的长度。

Length of Emojis in JavaScript and PHP

Length of Emojis in JavaScript and PHP

可以安全地假设

mb_strlen($subject,‘utf8’)
永远不会返回大于 JavaScript
.length
的值吗?对于我尚未测试的其余现有表情符号?

如果没有,您能否对此进行更多解释,并给出一些字符示例,其中

mb_strlen($subject,‘utf8’)
将返回比 JavaScript
.length
更大的值?

谢谢你

javascript php angular utf-8 unicode-string
1个回答
0
投票

Javascript字符串的编码是UTF-16,length属性是字符串中UTF-16字符的数量。每个 UTF-16 字符的长度为2 个字节。在 PHP 中,你可以这样计算长度:

# Assume the input string is encoded with UTF-8
$str2 = mb_convert_encoding($str, 'UTF-16LE', 'UTF-8');
$length = strlen($str2) / 2;

但是

mb_strlen
计算字符串中 Unicode 字符的数量。 Unicode字符的长度是可变的,在当前版本中,长度可以是2或3字节

要以 UTF-16 编码表示 3 字节 Unicode 字符,需要使用 代理对(2 个 UTF-16 字符)。因此,

mb_strlen
返回的长度永远不会大于Javascript中的length属性。

© www.soinside.com 2019 - 2024. All rights reserved.