【问题标题】:Having en-dash at the end of the string doesn't allow json_encode在字符串末尾有破折号不允许 json_encode
【发布时间】:2016-10-14 13:24:48
【问题描述】:

我正在尝试使用从字符串中提取 n 个字符 substr($originalText,0,250);

第 n 个字符是一个破折号。所以当我在记事本中查看它时,我得到最后一个字符 â€。在我的编辑器 Brackets 中,我什至无法打开它的日志文件,因为它只支持 UTF-8 编码。

我也无法在这个字符串上运行 json_encode。

但是,当我使用substr($originalText,0,251) 时,它工作得很好。我可以打开日志文件,它会显示一个破折号而不是â€。 json_encode 也可以正常工作。

我可以使用mb_convert_encoding($mystring, "UTF-8", "Windows-1252") 来规避这个问题,但是谁能告诉我为什么最后有这些字符会导致错误? 此外,在执行此操作时,我的日志文件显示 †在括号中,这也令人困惑。

我的问题是为什么在字符串末尾有破折号,与在其他任何地方(后面跟着其他字符)不同。

希望我的问题很清楚,如果不是,我可以尝试进一步解释。

谢谢。

【问题讨论】:

  • substr() 不是用于处理多字节字符集字符串的最佳函数,请改为查看 mb_substr()

标签: php json utf-8 mb-convert-encoding


【解决方案1】:

Pid's answer 解释了为什么会发生这种情况,这个答案只是看看你能做些什么......

使用 mb_substr()

multibyte string 模块正是为这种情况而设计的,它提供了许多正确处理多字节字符的字符串函数。我建议您查看那里,因为在您的应用程序的其他地方可能还需要其他的。

如果您收到未找到功能的错误,您可能需要安装或启用此模块。相关说明取决于平台,超出此问题的范围。

您想要为问题中的情况使用的函数称为mb_substr(),其调用方式与您使用substr() 相同,但具有其他可选参数。

【讨论】:

  • 谢谢。使用 mb_substr() 比 mb_convert_encoding() 效果更好。我现在不必在前端重新编码。
【解决方案2】:

UTF-8 使用所谓的代理,将代码页扩展到 ASCII 之外以容纳更多字符。

单个 UTF-8 字符可以编码为一个、两个、三个或四个字节,具体取决于字符。

你在一个多字节字符的中间剪掉了字符串:

[<-character->]
[byte-0|byte-1]
       ^
      You cut the string right here in the middle!


[<-----character---->]
[byte-0|byte-1|byte-2]
       ^      ^
      Or anywhere here if it's 3 bytes long.

所以解码器有第一个字节但无法读取整个字符,因为字符串过早结束。

这会导致您所看到的所有效果。

这个问题的解决方法是here in Dezza's answer

【讨论】:

  • 我认为可能是这样,因为将限制从 250 更改为 249 只会打印 â。谢谢你解释得很好。
  • 我会接受这个答案,因为它解释了出了什么问题。
  • 是的,我试图解释这个问题。解决方案是多字节版本mb_substr(),如另一个答案所示。我一直认为理解问题比盲目应用解决方案更重要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多