
http://file.whzxc.cn/126.png 如图,获取微信用户信息中的昵称,这个点,php json 解析不了,复制到百度 百度都直接跳到首页了 使用 mb_convert_encoding(,'utf-8','utf-') 也不行 谁知道怎么过滤么
1 imnpc 2018-10-17 09:52:29 +08:00 // 过滤掉 emoji 表情 function filterEmoji($str) { $str = preg_replace_callback( '/./u', function (array $match) { return strlen($match[0]) >= 4 ? '' : $match[0]; }, $str); return $str; } |
2 reus 2018-10-17 10:09:46 +08:00 垃圾 PHP PHP 是世界上最垃圾的流行语言 |
4 lcy630409 OP @imnpc 不是 emoji 表情呢,那个符号我复制到 v2 保存也不见了,真 tm 蛋痛,用户设置的各类用户名真心无语 |
6 jowan 2018-10-17 10:16:17 +08:00 数据库设置 utf8mb4 编码,普通的 utf8 只能保存部分 emoji 表情 |
7 jowan 2018-10-17 10:17:30 +08:00 表也要设置一下 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; |
8 lcy630409 OP @jowan 不是保存的问题,从微信那边获取过来之后,json_decode 都返回 null,jsonlasterr 为 3,放在解析 json 里 提示这个,开始发现 手动处理了这个用户,然后发现有一小部分用户都有这个问题,就只能找解决办法了 |
10 wei745359223 2018-10-17 10:26:46 +08:00 把 JSON 字符串发出来 |
11 lcy630409 OP @wei745359223 那个点贴不出来,刚在主题中试过了,保存后 v2 显示不出来,粘贴到百度,回车,然后又跳到百度首页了..... |
12 koast 2018-10-17 10:32:40 +08:00 via Android 不能贴一下字符编码吗 |
13 dobelee 2018-10-17 10:43:51 +08:00 你确实之前编码是 utf-8 ? |
14 lcy630409 OP 感谢大家的讨论,找到办法了,问师兄得出了办法了 在 json_decode 之前 preg_replace('/[\x00-\x1F\x80-\x9F]/u', '', trim($a)); 就可以了 此贴终结,再次感谢各位热心回答,谢谢 |
15 run2 2018-10-17 10:45:39 +08:00 呃,没有直接测微信的 $jstring= '{"nickname":"喜喜(●ˇˇ●)","sex":2}'; var_dump(mb_convert_encoding($jstring,'utf-8')); var_dump(json_decode(mb_convert_encoding($jstring,'utf-8'))); var_dump(json_last_error_msg()); 但没毛病啊,你 php 版本? Output for 5.6.38 - 7.3.0rc3 string(48) "{"nickname":"喜喜(●ˇˇ●)","sex":2}" object(stdClass)#1 (2) { ["nickname"]=> string(25) "喜喜(●ˇˇ●)" ["sex"]=> int(2) } string(8) "No error" |
16 wei745359223 2018-10-17 10:46:38 +08:00 应该是里面包含了 control character https://zh.wikipedia.org/zh-hans/%E6%8E%A7%E5%88%B6%E5%AD%97%E7%AC%A6 |
17 run2 2018-10-17 10:52:25 +08:00 3 JSON_ERROR_CTRL_CHAR |
18 lcy630409 OP @sobigfish 不是你这里面的字符呢,你可以看一下上面的图,在 json 校验下 那个点会被解析成||这个啥符号,粘贴到 notepad++中显示 DC4,估计是啥特殊的表情吧 |
19 yc8332 2018-10-17 13:54:19 +08:00 人家能发出来你就应该能保存。。没毛病,只是可能你的程序不能支持。。。比如把它转成 unicode 保存,显示的时候再恢复 |
20 sgq1128 2018-10-17 14:01:08 +08:00 这是个非法的 json 啊 |
21 run2 2018-10-17 14:01:31 +08:00 @lcy630409 #18 16 楼 wei745359223 给你说了,jsonlasterr 3 就是 JSON_ERROR_CTRL_CHAR,这个就是指控制字符,但微信可能并没有传(只是你后期自己测试复制了换行字符类的) 你可以直接试试微信传过来的,直接 json_decode(mb_convert_encoding())看可以不 |
22 cyspy 2018-10-17 16:02:54 +08:00 看起来是某种分隔符(小节符号)。无论如何,理论上 JSON 里只能出现 ASCII Escape,其他的都算非法 JSON |
23 raysonlu 2018-10-17 16:49:17 +08:00 微信给用户改昵称的时候不把用户的控制符去掉的么? |
24 zxq2233 2018-10-17 18:38:40 +08:00 via Android 为什么不用 JAVA |
26 topzyh 2018-10-17 22:57:34 +08:00 我遇到过,用 utf8mb4 就行了,如果你用了 TP 之类的框架,框架里也要设置 |
27 jhdxr 2018-10-17 23:35:55 +08:00 先上一个能复现的代码: ``` <?php $str = '"'.chr(11).'"'; var_dump(json_decode($str), json_last_error(), json_last_error_msg()); ``` 但这个并不是 php 的实现问题,实际上如果你在 js 中(我只在 firefox56 中进行了测试) ``` JSON.parse('"\x0b"'); ``` 实际上你也会得到类似的出错信息:SyntaxError: JSON.parse: bad control character in string literal at line 1 column 2 of the JSON data 原因是什么呢?如果你查看 json 的定义( http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf ),其中对于 string 做了明确的定义: A string is a sequence of Unicode code points wrapped with quotation marks (U+0022). All code points may be placed within the quotation marks except for the code points that must be escaped: quotation mark (U+0022), reverse solidus (U+005C), and the control characters U+0000 to U+001F. 注意其中非常明确指出了控制符(\x00-\x1f )需要被转义,否则这就是一个非法的 json。所以在这种情况下只能说微信不负责任的给了一个非法的 json,@lcy630409 在 14 楼的代码就可以算是一个解决方案(直接过滤掉无效字符) @reus 不了解真相的开喷,只能说明你自己是。。。 @raysonlu 早期微信的确没有过滤控制字符。然后通过这些字符(比如\u202e )在一些时候(比如撤回消息)时会出现一些神奇的效果。当然现在已经在改名时过滤了。但之前改的那些依然有效。 |
28 mumu 2018-10-18 15:32:43 +08:00 我都 base64 编码加密,然后输出的时候直接解密输出。 |