mb_encode_numericentity()中$convmap的更好解释

8
这个参数名为convmap,用于mb_encode_numericentity方法。在php手册中对此参数的描述对我来说含糊不清。是否有人能给出更好的解释,或者如果应该足够我理解的话,是否能将其简化?这个参数中使用的数组元素的含义是什么?manpage中的示例1为:
<?php
$convmap = array (
 int start_code1, int end_code1, int offset1, int mask1,
 int start_code2, int end_code2, int offset2, int mask2,
 ........
 int start_codeN, int end_codeN, int offsetN, int maskN );
// Specify Unicode value for start_codeN and end_codeN
// Add offsetN to value and take bit-wise 'AND' with maskN, then
// it converts value to numeric string reference.
?>

这很有帮助,但是我看到许多使用示例,例如array(0x80, 0xffff, 0, 0xffff);,这让我感到困惑。这是否意味着偏移量将为0,掩码将为0xffff,如果是这样的话,偏移量是否表示要开始转换的字符串中的字符数,而在这种情况下mask是什么意思?


1
乍一看,网页上的示例1示例2似乎展示了相同的格式(但是分成了单行或多行)。这意味着,在您的示例中,“偏移量”将是“0”,“掩码”将是“0xffff”。这些示例中的$convmap表明,您可以包括任意数量的“行”(四个值的“集合”)。 - summea
1
@summea 感谢你,summea。在这个上下文中,“mask”具体是什么意思?我已经更新了我的问题。 - Nick Rolando
convmap中使用offsetmask值可能有更具体的原因,但我希望下面的答案能稍微帮到你! - summea
1个回答

10

看着兔子洞, 似乎mb_encode_numericentity文档中的评论是准确的,尽管有些晦涩。

convmap 的四个主要部分似乎是:

start_code: 映射从此字符代码开始的项目。
end_code: 映射影响到此字符代码之前的项目。
offset: 为此字符代码添加特定偏移量(正或负)
mask: 用于掩码操作的值(字符代码按位与掩码值)

字符编码可以通过字符表进行可视化,例如 this Codepage Layout example,适用于 ISO-8859-1 编码。在这个编码表中,我们可以看到 convmap 只会影响从 0x80 开始的字符编码项(对于这种特定编码似乎为空白)直到该编码的最后一个字符 0xff(似乎是 ÿ)。ISO-8859-1 是 PHP 文档 Example #2 中使用的编码)
为了更好地理解convmap偏移量(offset)掩码(mask)功能,以下是一些示例,展示了偏移量和掩码如何影响字符编码(在下面的示例中,我们的字符编码具有定义值162

简单示例:

<?php    
$original_str = "¢";
$convmap = array(0x00, 0xff, 0, 0xff);
$converted_str = mb_encode_numericentity($original_str, $convmap, "UTF-8");
echo "original:  $original_str\n";
echo "converted: $converted_str\n";
?>

Result:

original:  ¢
converted: &#162;

偏移量示例:

<?php
$original_str = "¢";
$convmap = array(0x00, 0xff, 1, 0xff);
$converted_str = mb_encode_numericentity($original_str, $convmap, "UTF-8");
echo "original:  $original_str\n";
echo "converted: $converted_str\n";
?>

Result:

original:  ¢
converted: &#163;

注意:

offset 看起来可以更精细地控制当前要转换的项目的 start_codeend_code 部分。例如,您可能有某些特定的原因需要为您的 convmap 中的某些字符代码行添加偏移量,但是您可能需要忽略另一行中的该偏移量。


口罩示例:

<?php
// Mask Example 1
$original_str = "¢";
$convmap = array(0x00, 0xff, 0, 0xf0);
$converted_str = mb_encode_numericentity($original_str, $convmap, "UTF-8");
echo "original:  $original_str\n";
echo "converted: $converted_str\n\n";

// Mask Example 2
$convmap = array(0x00, 0xff, 0, 0x0f);
$converted_str = mb_encode_numericentity($original_str, $convmap, "UTF-8");
echo "original:  $original_str\n";
echo "converted: $converted_str\n\n";

// Mask Example 3
$convmap = array(0x00, 0xff, 0, 0x00);
$converted_str = mb_encode_numericentity($original_str, $convmap, "UTF-8");
echo "original:  $original_str\n";
echo "converted: $converted_str\n";
?>

Result:

original:  ¢
converted: &#160;

original:  ¢
converted: &#2;

original:  ¢
converted: &#0;

注意:

本回答不打算详细介绍掩码,但掩码可以帮助保留或删除给定值的某些位。

掩码示例1

因此,在第一个掩码示例中,0xf0中的f表示我们要保留二进制值左侧的值。在这里,f的二进制值为1111,而0的二进制值为0000——两者合在一起变成了11110000的值。

然后,当我们对字符代码(在这种情况下,是162,其二进制值为10100010进行按位AND操作时,按位运算如下:

  11110000
& 10100010
----------
  10100000

当转换回十进制值时,10100000160

因此,我们有效地保留了原始字符编码值的“左侧”比特,并且摆脱了比特的“右侧”。

掩码示例2

在第二个掩码示例中,掩码0x0f (其二进制值为00001111在按位与操作中将具有以下二进制结果:

  00001111
& 10100010
----------
  00000010

将其转换回十进制值后,结果为2

因此,我们有效地保留了原始字符编码值的“右侧”位,并且摆脱了“左侧”位。

掩码示例3

最后,第三个掩码示例展示了在位与操作中使用0x00掩码的情况 (它在二进制中表示为00000000

  00000000
& 10100010
----------
  00000000

这导致结果为0

1
你很棒。非常感谢你 :) - Nick Rolando
@NickRolando 不是我!但我很高兴这有帮助! - summea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接