PHP 中 Serialize 和 JSON 的区别和在 WordPress 中如何使用

2023-04-13 14:03:14 浏览数 (1)

​在 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 函数。

代码语言:javascript复制
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 是已经序列化的字符串,它还会对其再进行一次序列化操作。下面的例子比较全面解释其用法:

代码语言:javascript复制
// 字符串不做任何处理,直接返回。
$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 这两个用来检测当前字符串是不是序列化字符串的函数。

代码语言:javascript复制
is_serialized( $data );

is_serialized_string( $data );

简单说:is_serialized 用法更广泛一点,无论数组,对象,字符串被序列化之后的字符串,它判断为 true,而 is_serialized_string 只有字符串被序列化之后,才判断为 true。下面的例子也非常全面的区分两者的区别:

代码语言:javascript复制
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,并且进行一些完整性检查。

代码语言:javascript复制
wp_json_encode( $data, $options = 0, $depth = 512 )

简单说下 WordPress 引进这个函数的原因:

首先不同 PHP 版本 json_encode 函数支持不同的参数。PHP 5.3 之前只支持 一个参数 data,PHP 5.3 引进了  options 参数,PHP 5.5 又引进了 

在 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

代码语言:javascript复制
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 数据。

代码语言:javascript复制
wp_send_json( $response, $status_code = null )

他首先输出 application/json 的 Content-Type 头,如果 status_code 不为空,则输出  status_code 的状态码。

然后调用 wp_json_encode 对数据进行编码。

wpjam_send_json

代码语言:javascript复制
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 两个函数:

代码语言:javascript复制
wp_send_json_success( $data = null, $status_code = null )
代码语言:javascript复制
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 结果,这个函数没有参数,直接使用:

代码语言:javascript复制
wp_is_json_request()

它通过判断 _SERVER['HTTP_ACCEPT'] 中含有 application/json,或者  _SERVER'CONTENT_TYPE' 等于 application/json。

wp_is_jsonp_request

判断当前请求是不是 JSONP 请求,或者返回 JSONP 结果,这个函数没有参数,直接使用:

代码语言:javascript复制
wp_is_jsonp_request()

它首先判断 $_GET['_jsonp'] ,是否存在,然后通过函数 wp_check_jsonp_callback 判断它的值是否合法。

wp_check_jsonp_callback

判断 JSONP callback 是不是一个一个合法的 JavaScript callback 函数:

代码语言:javascript复制
wp_check_jsonp_callback( $callback )

合法的 JavaScript callback 函数只能数字加字符,以及英文点号。

0 人点赞