PHP 中 Serialize 和 JSON 的区别和在 WordPress 中如何使用
在 PHP 中,Serialize 和 JSON 是 PHP 和 WordPress 开发中的数据处理的常用方法,那么它们有什么区别呢?在 WordPress 中又如何使用呢?
Serialize 和 JSON 区别
1. 使用 Serialize 进行编码后,大小大概是使用 JSON 编码的1.5倍,这是因为 Serialize 后字符串包含了子串的长度,并且有更加详细的类型区分,而 JSON 只有四种类型,并且是以简单的符号表示。这也造成了 Serialize 要比 JSON 速度更快,一般快 20-30%。
2. JSON 是基于Unicode格式,所以要在 UTF-8 环境下进行操作,如果中文不想转换成 unicode,需要使用额外的参数: json_encode($array, JSON_UNESCAPED_UNICODE)
3. JSON 无法存储对象的原始的 class,解码的时候,只能解码成 stdClass 的实例。另外在 JSON 中也无法使用 __sleep()
和 __wakeup()
魔术方法。
4. 默认情况下,对象的公共属性才能被 JSON 编码,当然在 PHP 5.4 之后,可以通过类实现 JsonSerializable 接口来改变该行为。
5. 当然 JSON 更通用,它是跨平台的通用格式,在接口中,现在基本都是用 JSON 了。
WordPress 序列化处理相关函数大全
序列化处理是 WordPress 的强项,比如在使用 update_option
的时候,可以把字符串,数组,或者对象直接存进去,WordPress 会自定化进行序列化处理,需要用到的时候,只需要使用 get_option
函数取出数据即可,原本是数组,取出来还是数组,原来是对象,取出来依然是对象,非常方便。
WordPress 是怎么做到的呢?这个就是 WordPress 自己定义了几个序列化处理的相关函数把序列化处理过程做的更简单:
maybe_unserialize 和 maybe_serialize 函数
首先 WordPress 扩展了 PHP 原生的 unserialize
和 serialize
函数,定义了 maybe_unserialize
和 maybe_serialize
函数。
maybe_unserialize( $original );
maybe_serialize( $data );
maybe_unserialize
是 WordPress 的反序列化函数,官方的解释是:Unserialize value only if it was serialized. 意思是它会首先会检测一下当前的字符串是不是序列化之后的字符串,是的话,它才使用 PHP 的 unserialize
函数进行反序列化,如果不是,则直接返回。
maybe_serialize
是 WordPress 的序列化函数,如果是普通字符串,则直接返回,如果 $data 是对象或者数组,则是用 PHP serialize
函数对齐进行序列化。特别需要注意的是,如果 $data 是已经序列化的字符串,它还会对其再进行一次序列化操作。下面的例子比较全面解释其用法:
// 字符串不做任何处理,直接返回。
$data = 'Hello World!';
echo maybe_serialize( $data );
// Hello World!
// 整形,浮点型,和布尔型数据也是不做处理,直接返回。
$data = 55;
echo maybe_serialize( $data );
// 55
$data = 4.560
echo maybe_serialize( $data );
// 4.560
$data = true;
$data = maybe_serialize( $data );
// $data = true;
$data = null;
$data = maybe_serialize( $data );
// $data = null
// 对象和数组会被转换成序列化数据
$data = array( 1 => 'Hello World!', 'foo' => 'bar' );
echo maybe_serialize( $data );
// a:2:{i:1;s:12:"Hello World!";s:3:"foo";s:3:"bar";}
// 已经序列化的字符串,会被再次序列化
$data = 'a:2:{i:1;s:12:"Hello World!";s:3:"foo";s:3:"bar";}';
echo maybe_serialize( $data );
// s:50:"a:2:{i:1;s:12:"Hello World!";s:3:"foo";s:3:"bar";}";
is_serialized 和 is_serialized_string 函数
WordPress 提供了 is_serialized
和 is_serialized_string
这两个用来检测当前字符串是不是序列化字符串的函数。
is_serialized( $data );
is_serialized_string( $data );
简单说:is_serialized
用法更广泛一点,无论数组,对象,字符串被序列化之后的字符串,它判断为 true,而 is_serialized_string
只有字符串被序列化之后,才判断为 true。下面的例子也非常全面的区分两者的区别:
var_dump( is_serialized( serialize(NULL) ) ); // true
var_dump( is_serialized_string( serialize(NULL) ) ); // false
var_dump( is_serialized( serialize(array(1,2,3)) ) ); // true
var_dump( is_serialized_string( serialize(array(1,2,3)) ) ); // false
var_dump( is_serialized( serialize("hello") ) ); // true
var_dump( is_serialized_string( serialize("hello") ) ); // true
WordPress JSON 处理相关函数大全
JSON 处理是 WordPress 开发中的经常需要处理的一项工作,为此,WordPress 定义了一堆 JSON 处理的函数,今天做一下统一的介绍。
wp_json_encode
编码成 JSON,并且进行一些完整性检查。
wp_json_encode( $data, $options = 0, $depth = 512 )
简单说下 WordPress 引进这个函数的原因:
首先不同 PHP 版本 json_encode
函数支持不同的参数。PHP 5.3 之前只支持 一个参数 $data
,PHP 5.3 引进了 $options
参数,PHP 5.5 又引进了 $depth
参数。所以 WordPress 适配不同版本的 PHP,wp_json_encode
都支持三个参数,兼容不同版本的 PHP。
在 json_encode
之前,wp_json_encode
使用函数 _wp_json_prepare_data
对数据进行清理,如果 boolean
,integer
,double
,string
,NULL
这些类型,直接返回,如果数组,继续使用 _wp_json_prepare_data
函数对数组中的每个元素进行清理,如果是对象,如果该对象的 class 实现了 JsonSerializable
接口,则返回 $data = $data->jsonSerialize()
,否则,继续使用 _wp_json_prepare_data
对对象中的每个属性进行清理。
然后使用 json_encode
进行编码,如果不成功,则使用 _wp_json_sanity_check
对数据进行完整性处理,最后再使用 json_encode
进行编码。_wp_json_sanity_check
主要使用函数 _wp_json_convert_string
对数据进行深度 UTF-8 检测和转换。
所以建议使用 wp_json_encode
对变量进行 JSON 编码,它的可靠性更高。
wpjam_json_encode
wp_json_encode( $data, $options = JSON_UNESCAPED_UNICODE, $depth = 512 )
PHP5.4 JSON 新增了一个选项:JSON_UNESCAPED_UNICODE
,故名思议:不要编码成 Unicode,让中文更可读。
所以我们写了一个 wpjam_json_encode
函数,相比 wp_json_encode
,就是将 $options
参数默认值设置为 JSON_UNESCAPED_UNICODE
,这样直接使用 wpjam_json_encode($data)
,中文就不会被编码成 unicode,更可读。
只要你安装 WPJAM Basic 插件,你的 WordPress 就会有这个函数。
wp_send_json
直接发送 JSON 数据。
wp_send_json( $response, $status_code = null )
他首先输出 application/json
的 Content-Type 头,如果 $status_code
不为空,则输出 $status_code
的状态码。
然后调用 wp_json_encode
对数据进行编码。
wpjam_send_json
wpjam_send_json( $response, $status_code = null )
同样为了能够 JSON 编码之后,中文更可读,我们也写了 wpjam_send_json
函数,它和 wp_send_json
几乎一致,只是调用对数据进行编码的函数是 wpjam_json_encode
。
另外如果传入的数据是 WP_Error
的实例,那么 wpjam_send_json
直接输出 errcode 和 errmsg JSON。如果没有设置 errcode
,则 wpjam_send_json
自动加上 errcode=>0
安装 WPJAM Basic 插件,你的 WordPress 就会有这个函数。
wp_send_json_success 和 wp_send_json_error
WordPress 还提供 wp_send_json_success
和 wp_send_json_error
两个函数:
wp_send_json_success( $data = null, $status_code = null )
wp_send_json_error( $data = null, $status_code = null )
wp_send_json_success
先输出 success 为 true,然后把数据 $data 放到 data 里面输出。wp_send_json_error
则会判断 $data 是否为 WP_Error 实例,如果是,则输出 code 和 message 的数组。我们实现的 wpjam_send_json
已经能够自动化处理这些错误了。
wp_is_json_request
判断当前请求是不是 JSON 请求,或者返回 JSON 结果,这个函数没有参数,直接使用:
wp_is_json_request()
它通过判断 $_SERVER['HTTP_ACCEPT']
中含有 application/json
,或者 $_SERVER['CONTENT_TYPE']
等于 application/json
。
wp_is_jsonp_request
判断当前请求是不是 JSONP 请求,或者返回 JSONP 结果,这个函数没有参数,直接使用:
wp_is_jsonp_request()
它首先判断 $_GET['_jsonp']
,是否存在,然后通过函数 wp_check_jsonp_callback
判断它的值是否合法。
wp_check_jsonp_callback
判断 JSONP callback 是不是一个一个合法的 JavaScript callback 函数:
wp_check_jsonp_callback( $callback )
合法的 JavaScript callback 函数只能数字加字符,以及英文点号。