我正在开发 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
返回的长度。
可以安全地假设
mb_strlen($subject,‘utf8’)
永远不会返回大于 JavaScript .length
的值吗?对于我尚未测试的其余现有表情符号?
如果没有,您能否对此进行更多解释,并给出一些字符示例,其中
mb_strlen($subject,‘utf8’)
将返回比 JavaScript .length
更大的值?
谢谢你
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属性。