http://file.whzxc.cn/126.png 如图,获取微信用户信息中的昵称,这个点,php json 解析不了,复制到百度 百度都直接跳到首页了 使用 mb_convert_encoding(,'utf-8','utf-8') 也不行 谁知道怎么过滤么
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 2
垃圾 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
sobigfish 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 1
应该是里面包含了 control character
https://zh.wikipedia.org/zh-hans/%E6%8E%A7%E5%88%B6%E5%AD%97%E7%AC%A6 |
17
sobigfish 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
sobigfish 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 5
先上一个能复现的代码:
``` <?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 编码加密,然后输出的时候直接解密输出。
|