【问题标题】:PHP - Replace JSON with the correct Unicode symbolPHP - 用正确的 Unicode 符号替换 JSON
【发布时间】:2018-05-19 08:39:46
【问题描述】:

好的,所以我有一些 JSON,当解码时,我打印出结果。在解码 JSON 之前,我使用 stripslashes() 删除多余的斜杠。 JSON 包含网站链接,例如 https://www.w3schools.com/php/default.asp 和描述,例如 Hello World, I have u00249999999 dollars

当我打印出 JSON 时,我希望它打印出来 Hello World, I have $9999999 dollars,但它会打印出Hello World, I have u00249999999 dollars

我假设 u0024 没有被解析,因为它没有反斜杠,但问题是网站链接的正斜杠不会通过带斜杠删除,这很好 - 我认为反斜杠使用 stripslashes() 删除 Unicode 符号;

如何让 PHP 自动检测和解析 Unicode 美元符号?我还想将此规则应用于每个 Unicode 符号。

提前致谢!

【问题讨论】:

    标签: php json unicode backslash stripslashes


    【解决方案1】:

    根据PHP documentation on stripslashes (),它

    取消引用带引号的字符串。

    这意味着,它基本上删除了所有用于转义字符(或 Unicode 序列)的反斜杠。删除这些时,您基本上没有机会完全确定 "u0024" 之类的任何序列都是 Unicode 实体,您的用户可能只是输入了它。

    除此之外,在包含转义引号的 JSON 值上使用 stripslashes () 时会遇到一些麻烦。考虑这个例子:

    {
      "key": "\"value\""
    }
    

    当使用stripslashes () 时,这将变得无效,因为它将如下所示:

    {
      "key": ""value""
    }
    

    这是不可解析的,因为它不是有效的 JSON 对象。当您不使用stripslashes () 时,所有转义序列都将由 JSON 解析器转换,并且在将(解码的)JSON 对象输出到客户端之前,PHP 将自动解码(或“转换”)您的数据可能包含的 Unicode 序列.

    结论:我建议在处理 JSON 实体时不要使用stripslashes (),因为它可能会破坏事物(如前面的示例中所见,但也出现在您的问题中)。

    【讨论】:

    • 这成功了!我不确定它是否会起作用 - 因为我只是使用 stripslashes() 来删除由 JSON 编码器自动放置在那里的斜杠 - 我没有意识到结果对象可以被解析,即使当我使用 print_r( ) 打印数据。非常感谢!这真的很有帮助 - 抱歉这么晚才回复 - 我现在有考试。
    【解决方案2】:

    您的假设是正确的:u0024 没有被解析,因为它没有反斜杠。您可以使用正则表达式在转换后添加反斜杠。

    您的内部似乎有 UTF-8 编码的字符串,PHP 正确输出它们,但您的浏览器无法自动检测编码(它决定使用 ISO 8859-1 或其他编码)。

    最好的方法是通过发送相应的 HTTP 标头告诉浏览器正在使用 UTF-8:

    header("content-type: text/html; charset=UTF-8"); 
    

    然后,您可以将其余代码保持原样,而不必对实体进行 html 编码或创建其他混乱。

    如果需要,您还可以使用<meta> 标签在生成的 HTML 中额外声明编码:

    <meta http-equiv=Content-Type content="text/html; charset=UTF-8"> for HTML <=4.01
    <meta charset="UTF-8">
    

    对于 HTML5 HTTP 标头优先于&lt;meta&gt; 标记,但如果将 HTML 保存为 HD 然后在本地读取,则后者可能很有用。

    【讨论】:

    • 抱歉这么晚才回复。我只是看了你的建议,但我的问题已经解决了。顺便说一句,我确实在文档顶部设置了内容类型。感谢您的回复!祝你有美好的一天!
    【解决方案3】:

    您必须了解的主要问题是,为什么需要去除斜线? 而且,如果确实需要去除斜线,如何管理编码?使用 html_entity_decode 将 unicode 符号 before 转换为斜杠而不是之后可能是个好主意。

    无论如何,您可以尝试使用此解决方法解决问题:

    $string = "Hello World, I have u00249999999 dollars";
    $string = preg_replace( "/u([0-9A-F]{0,4})/", "&#x$1;", $string ); // recover "u" + 4 alnums
    $string = html_entity_decode( $string, ENT_COMPAT, 'UTF-8' ); // convert to utf-8
    

    【讨论】:

    • @MrLister 你说得对,我写代码的速度很快,只是为了指出解决问题的可能方法,即使我不同意这种解决方案。但是让我指出,我的代码中唯一的问题是必须转换为反斜杠的斜杠:$string = preg_replace( "/(u\d{4})/", "\\$1", $string ); 显然将\\ 翻倍以取消转义,然后它将与mb_convert_encoding 一起用于表示为 \u+ 的任何字符4digits 写在我的代码的注释中。我已经更正了我的回复,现在它比其他的更中肯。
    • 感谢您的回复 - 我尝试了您的建议,但它不起作用,因为它会将所有 Unicode 替换为美元符号。我真正想做的是用正确的相应 Unicode 符号替换所有 Unicode。不过还是谢谢!
    • @MrLister 永远是对的(除非他写了我的昵称)。无论如何,这里是最终解决方案:$string = "Hello World, I have u00249999999 dollars"; $string = preg_replace( "/u([0-9A-F]{0,4})/", "&amp;#x$1;", $string ); $string = html_entity_decode( $string, ENT_COMPAT, 'UTF-8' );。我更新了答案。
    • @Kalamun 好的。我删除了我的反对票(以及我拼写错误的 cmets)。但我仍然认为更好的答案是首先不要从源材料中删除那些反斜杠。
    • @MrLister 我同意,我删除了反斜杠,它起作用了!
    猜你喜欢
    • 2012-09-19
    • 2018-12-16
    • 2020-11-13
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多