摘要:在写序列化与反序列化时,我们先来看看产生一个可存储的值的表示描述返回字符串,此字符串包含了表示的字节流,可以存储于任何地方。想要将已序列化的字符串变回的值,可使用。当序列化对象时,将试图在序列动作之前调用该对象的成员函数。
在写序列化serialize与反序列化unserialize()时,我们先来看看:
serialize — 产生一个可存储的值的表示
描述
string serialize ( mixed $value )
serialize() 返回字符串,此字符串包含了表示 value 的字节流,可以存储于任何地方。
这有利于存储或传递 PHP 的值,同时不丢失其类型和结构。
想要将已序列化的字符串变回 PHP 的值,可使用 unserialize()。serialize() 可处理除了 resource 之外的任何类型。甚至可以 serialize() 那些包含了指向其自身引用的数组。你正 serialize() 的数组/对象中的引用也将被存储。
当序列化对象时,PHP 将试图在序列动作之前调用该对象的成员函数 __sleep()。这样就允许对象在被序列化之前做任何清除操作。类似的,当使用 unserialize() 恢复对象时, 将调用 __wakeup() 成员函数。
个人实际项目中的理解
序列化serialize()就是可以将多个字段的值如 name、vaule、sex、money等存储在数据库表中一个字段里如extend_params,而不用另外开辟那么多字段,使用的时候就要先反序列化extend_params
上代码
下面的代码是我在帘易购项目中计价算法中用到的(ECShop)
/**
* 添加定制商品到购物车
*/
public function add_customizationOp() {
if (floatval($_POST["width"]) <= 0 || floatval($_POST["height"]) <= 0 || floatval($_POST["c_height"]) <= 0) {
echo "请选择正确的尺寸";
exit;
}
$goods = Model()->table("goods,goods_common")->join("left")->on("goods.goods_commonid = goods_common.goods_commonid")->where(array("goods_common.goods_commonid" => array("in", $_POST["goods"])))->select();
if (empty($goods)) {
echo "请选择好合适的款式面料";
exit;
}
$class = $this->_get_class_list(1573);
$gc_array = array();
foreach ($class as $val) {
$gc_array[$val["gc_id"]] = $val["gc_name"];
}
foreach ($goods as $key => $val) {
if ($val["gc_id"] == 1574) {
$ratio = unserialize($val["ratio"]);
break;
}
}
if (empty($ratio) || empty($goods)) {
echo "请选择好合适的款式面料";
exit;
}
$extend_params["width"] = floatval($_POST["width"]);
$extend_params["height"] = floatval($_POST["height"]);
$extend_params["c_height"] = floatval($_POST["c_height"]);
$extend_params["hl"] = floatval($_POST["hl"]);
$extend_params["settle"] = " 计价类型:特别定制";
if (isset($_POST["pay_message"]) && !empty($_POST["pay_message"])) {
$extend_params["pay_message"] = trim($_POST["pay_message"]);
}
$insert_array = array();
$extend_params["total_price"] = 0;
$count = count($goods);
$i = 1;
$sum = 0;
$item_id = time() . rand(1000, 9999);
foreach ($goods as $val) {
if ($val["gc_id"] == 1574 || (isset($ratio[$val["gc_id"]]) && !empty($ratio[$val["gc_id"]]) && intval($ratio[$val["gc_id"]]) > 0)) {
if ($val["goods_storage"] - $_POST["quantity"] < 0) {
echo $val["goods_name"] . "库存不足";
exit;
} else {
$param["goods_num"] = $_POST["quantity"];
}
if ($val["gc_id"] == 1574) {
$param["goods_price"] = $val["goods_price"] * $extend_params["width"];
}elseif($val["gc_id"] == 1589||$val["gc_id"] == 1590){
$param["goods_price"] = $val["goods_price"] * floatval($ratio[$val["gc_id"]]) / 100;
} else {
$extend_params["mianliao"] = $gc_array[$val["gc_id"]];
$param["goods_price"] = $val["goods_price"] * $extend_params["width"] * floatval($ratio[$val["gc_id"]]) / 100;
}
if ($extend_params["height"] - 0.6 > 0) {
$param["goods_price"] = $param["goods_price"] * $extend_params["height"] / 0.45;
}
$sum += $param["goods_price"];
if ($i == $count) {
$extend_params["num"] = $count;
$extend_params["sum"] = sprintf("%.2f", $sum);
}
$param["goods_price"] = sprintf("%.2f", $param["goods_price"]);
$param["buyer_id"] = $this->member_info["member_id"];
$param["store_id"] = $this->member_info["bd_store_id"];
$param["goods_id"] = $val["goods_id"];
$param["goods_name"] = $val["goods_name"];
$param["type"] = 2;
$param["customization_id"] = $item_id;
$param["goods_image"] = $val["goods_image"];
$param["store_name"] = $val["store_name"];
$param["extend_params"] = serialize($extend_params); //重点
$insert_array[] = $param;
unset($extend_params["mianliao"]);
$i++;
}
}
//日志
$da["f_id"]=$count;
$da["f_name"]=json_encode($ratio);
$da["f_ip"]="11";
$da["t_id"]=$i;
$da["t_name"]="111";
$da["t_msg"]=json_encode($goods);
$da["add_time"]=time();
Model()->table("chat_log")->insert($da);
$res = Model()->table("cart")->insertAll($insert_array);
if ($res) {
echo 1;
exit;
} else {
echo "添加失败";
exit;
}
}
关键
$param["extend_params"] = serialize($extend_params); //重点
序列化效果
a:5:{s:5:"width";s:1:"2";s:6:"height";s:1:"0";s:11:"pay_message";s:6:"书房";s:11:"goods_price";s:5:"28.00";s:6:"settle";s:22:" 计价类型:定制";}
看到这里就知道serialize()作用性的了
那下面就来看看 是怎么用到unserialize()
/**
* 购物车列表
*/
public function cart_listOp() {
$model_cart = Model("cart");
$condition = array("buyer_id" => $this->member_info["member_id"]);
$cart_list = $model_cart->listCart("db", $condition);
$sum = 0; //商品总价
$num = 0; //商品数量
$all_click = 3; //是否全选
if (isset($_GET["height"])) {
Tpl::output("height", intval($_GET["height"]));
} else {
Tpl::output("height", 0);
}
foreach ($cart_list as $key => $value) {
if (!empty($value["extend_params"])) {
$extend_params = unserialize($value["extend_params"]); //重点
$value["extend_params1"] = "";
$value["extend_params2"] = "";
if (isset($extend_params["settle"])) {
$value["extend_params1"] .= $extend_params["settle"];
}
if (isset($extend_params["width"]) && floatval($extend_params["width"]) > 0) {
$value["extend_params1"] .= " 宽度:" . floatval($extend_params["width"]) . "米";
}
if (isset($extend_params["height"]) && floatval($extend_params["height"]) > 0) {
$value["extend_params1"] .= " 高度:" . floatval($extend_params["height"]) . "米";
}
if (isset($extend_params["c_height"]) && floatval($extend_params["c_height"]) > 0) {
$value["extend_params1"] .= " 窗高:" . floatval($extend_params["c_height"]) . "米";
}
if (isset($extend_params["hl"])) {
if ($extend_params["hl"] == 1) {
$value["extend_params2"] .= " 魔术贴:正面";
} else if ($extend_params["hl"] == 2) {
$value["extend_params2"] .= " 魔术贴:反面";
} else if ($extend_params["hl"] == 3) {
if (!isset($extend_params["mianliao"])) {
$value["extend_params2"] .= "无魔术贴";
}
}
//定制商品
$cart_list[$key]["num"] = $extend_params["num"];
$cart_list[$key]["sum"] = $extend_params["sum"];
if (isset($extend_params["mianliao"])) {
$value["extend_params2"] .= " " . $extend_params["mianliao"];
}
}
if (isset($extend_params["interfacing"])) {
if ($extend_params["interfacing"] == 1) {
$value["extend_params2"] .= " 衬布:遮光衬布";
} else if ($extend_params["interfacing"] == 2) {
$value["extend_params2"] .= " 衬布:不遮光衬布";
} else if ($extend_params["interfacing"] == 0) {
$value["extend_params2"] .= " 衬布:无衬布";
}
}
$cart_list[$key]["cunbucloth"] = $extend_params["cunbucloth"];
$cart_list[$key]["cunbumon"] = $extend_params["cunbumon"];
$cart_list[$key]["pay_message"] = $extend_params["pay_message"];
$cart_list[$key]["extend_params1"] = $value["extend_params1"];
$cart_list[$key]["extend_params2"] = $value["extend_params2"];
$cart_list[$key]["goods_sum"] = ncPriceFormat($extend_params["sum"] * $value["goods_num"]);
if($extend_params["sum"]){
$cart_list[$key]["goods_sum"] = ncPriceFormat($extend_params["sum"] * $value["goods_num"]);
}else{
$cart_list[$key]["goods_sum"] = ncPriceFormat($value["goods_price"] * $value["goods_num"]);
}
}
$cart_list[$key]["goods_image_url"] = cthumb($value["goods_image"], $value["store_id"]);
$cart_list[$key]["goods_price"] = $value["goods_price"];
$cart_list[$key]["quantity"] = $value["goods_num"]; //单笔订单购买的产品数量
$cart[] = $cart_list[$key];
if ($value["click"] == 1) {
$sum += $cart_list[$key]["goods_sum"];
$num += $cart_list[$key]["goods_num"];
} else {
$all_click = 2;
}
}
// dump($cart);
// exit(-1);
Tpl::output("cart", $cart);
Tpl::output("all_click", $all_click);
Tpl::output("num", $num);
Tpl::output("sum", ncPriceFormat($sum));
Tpl::showpage("cart");
}
重点
$extend_params = unserialize($value["extend_params"]); //重点
下面你就可以直接用$extend_params 来定位到你需要的数据了
总结
项目做不要怕Bug,要敢于面对它并把它真正的解决,当我做这个项目的时候,我并不是很清楚地知道序列化和反序列化的真正用法,我是先序列化了,然后要用的时候没有序列化,而直接去 $value["extend_params"]["sum"]这样去找,所以它是找不到数据的,后来经过反复试错,我懂得了得反序列化它,然后就可以直接这样用$extend_params["sum"],故接触得多,懂得也就多啦,不用怕自己现在很多都不会,重要的是自己肯去接触肯去理解
注:文章来源雨中笑记录实习期遇到的问题与心得,转载请申明原文
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/30841.html
摘要:实现里的安装用法世界上最好的语言世界上最好的语言世界上最好的语言地址 Golang 实现 PHP里的 serialize() 、 unserialize() 安装 go get -u github.com/techoner/gophp 用法 package main import ( fmt github.com/techoner/gophp/serialize )...
摘要:和函数这两个是序列化和反序列化中数据的常用函数。序列化数组输出结果反序列化输出结果当数组值包含如双引号单引号或冒号等字符时,它们被反序列化后,可能会出现问题。序列化反序列化但是编码将增加字符串的长度。序列化数组输出结果反序列化 序列化是将变量转换为可保存或传输的字符串的过程;反序列化就是在适当的时候把这个字符串再转化成原来的变量使用。这两个过程结合起来,可以轻松地存储和传输数据,使程序...
0.前言 本文为笃行日常学习记录,web安全php漏洞系列。 对象的序列化和反序列化作用就不再赘述,php中序列化的结果是一个php自定义的字符串格式,有点类似json. 我们在任何语言中设计对象的序列化和反序列化都需要解决几个问题 把某个对象序列化之后,序列化的结果有自描述的功能(从序列化的结果中知道这个对象的具体类型,知道类型还不够,当然还需要知道这个类型所对应具体的值). 序列化时的权...
摘要:我把分为五个部分,,,,而其中是就是做一些类的介绍与相关的类在各自文章内,在介绍这些类之前,先介绍几个接口数组式访问接口只要实现了这个接口,就可以使得像那样操作。只有内部的类用写的类才可以直接实现接口代码中使用或接口来实现遍历。 我把SPL分为五个部分:Iterator,Classes,Exceptions,Datastructures,Function;而其中classes是就是做一...
摘要:序列化工具类序列化工具的序列化与反序列化使用实现序列化和反序列化反序列化时,必须要有默认构造函数,否则报错使用序列化缓存此类分别包含序列化序列化序列化三种序列化方式。 序列化工具类 序列化即将对象序列化为字节数组,反序列化就是将字节数组恢复成对象。主要的目的是方便传输和存储。 序列化工具类: public class SerializeUtil { private stati...
阅读 1685·2021-09-22 15:43
阅读 2341·2019-08-30 15:54
阅读 1377·2019-08-30 10:51
阅读 2260·2019-08-29 18:35
阅读 579·2019-08-26 11:58
阅读 2679·2019-08-26 11:38
阅读 2664·2019-08-23 18:35
阅读 3963·2019-08-23 18:33