php序列化与反序列化相关
sshong 发表于2013年3月20日 20:35:37 更新于2013年3月20日 22:09:57
所谓序列化,就是将1个变量转化为二进制或者字符串形式,进行存储或者传输。
反序列化,正好相反。

这里总结下最近用到的PHP里面的序列化、反序列化相关的知识。

1、serialize序列化 unserialize反序列化
php中提供了serialize函数用于将一个变量值序列化为字符串形式,
通过unserialize又可以将这个字符串反序列化为一个具体的变量值。
参考如下代码:
$a = 1;
$sa = serialize($a);

$b = 'asarea';
$sb = serialize($b);

$c = array(0 => 1, 1 => 'asarea', 'k' => true);
$sc = serialize($c);

echo "$sa<br>$sb<br>$sc";
输出结果:
i:1;
s:6:"asarea";
a:3:{i:0;i:1;i:1;s:6:"asarea";s:1:"k";b:1;}
大致可以看出些php序列化的方式,i代表int,s代表string,a代表array。

关于自定义class对象的序列化,参考下面代码:
class Girl {
    public $beautiful;
   
    public function Girl($beautiful) {
        $this->beautiful = $beautiful;
    }
   
    public function echoBeauty() {
        echo 'i\'m' . (!$this->beautiful ? ' not ' : ' ') . 'beautiful';
    }
}
$girl = new Girl(true);
// $girl->echoBeauty();
$sgirl = serialize($girl);
echo "$sgirl<br>";
$cloneGirl = unserialize($sgirl);
$cloneGirl->echoBeauty();
输出结果:
O:4:"Girl":1:{s:9:"beautiful";b:1;}
i'm beautiful
关于对象的反序列化,需要在反序列化处能够找到类的定义。

2、json_encode与json_decode
跟serialize差不多,只不过是转化为json格式字符串。

3、var_export、var_dump、print_r
var_export用于生成一个变量的php代码表示,合法的php代码。
var_dump用于打印输出变量信息,信息全面,格式优美。
print_r用于打印输出变量易于理解的信息,信息简单。
$c = array(0 => 1, 1 => 'asarea', 'k' => true);
var_export($c);
var_dump($c);
print_r($c);
echo "<br><br>------------<br><br>";
//对于上例中的girl
var_export($girl);
var_dump($girl);
print_r($girl);
打印结果:
array ( 0 => 1, 1 => 'asarea', 'k' => true, )
array (size=3)
  0 => int 1
  1 => string 'asarea' (length=6)
  'k' => boolean true
Array ( [0] => 1 [1] => asarea [k] => 1 )

------------

Girl::__set_state(array( 'beautiful' => true, ))
object(Girl)[1]
  public 'beautiful' => boolean true
Girl Object ( [beautiful] => 1 )
4、eval
相信很多人都知道这玩意,很多语言都有的,将一个字符串解析成一段代码并执行。
php也不例外,提供了这个函数。上面介绍的var_export的出来的字符串,就可以用eval执行生成变量值(相当于反序列化)。
参考下面代码:
$c = array(0 => 1, 1 => 'asarea', 'k' => true);
$export = var_export($c, true);
eval("\$copy = $export;");
var_dump($copy);
输出
array (size=3)
  0 => int 1
  1 => string 'asarea' (length=6)
  'k' => boolean true

在使用eval时,需要注意由php的开始、结束标签导致的错误。
参考下面的代码:
<?php
$str = "<?php \$site = 'asarea'; ?>";
eval($str);
echo $site;
?>
这段代码运行会报错,为啥?
很简单,我们可以简单的把上述代码看成
<?php
<?php $site = 'asarea'; ?>
echo $site;
?>
标记嵌套了可不会报错吗。
上例可以简单的改为
<?php
$str = "<?php \$site = 'asarea'; ?>";
eval("?>$str<?php ");
echo $site;
?>
//相当于
<?php
?><?php $site = 'asarea'; ?><?php
echo $site;
?>
说到这个,就要说起php的开始标记<?php与结束标记?>。

5、php代码与html的分离
php通常是嵌入在html中的,php解析器在遇到结束标记后,会将结束标记?>与下一次开始标记<?php 之间的内容(通常是html代码)原样echo输出,参考下列代码:
<?php
$a = 1;
?>
<div id='foot'>copyright asarea.me</div>
<?php
echo $a;
?>
可以看到该段代码的opcode如下:
phptag

也就是说上述html代码等同于
echo "<div id='foot'>copyright asarea.me</div>";

由此,我们可以引申出更高级的php代码嵌入方式
<?php
$isMobile = true;
if($isMobile) {
?>
<div id='mobile_foot'>copyright asarea.me</div>
<?php
}
else {
?>
<div id='foot'>copyright asarea.me</div>
<?php
}
?>
上述代码的opcode为:
phptag2
以上方式,对于写大块的html代码分支时,相当有用,不用再人肉去拼php字符串并echo了。
标签:无分类:PHP阅读:2909
评论
暂无评论
添加评论
您的大名,限长10汉字,20英文(*)
电子信箱(*)
您的网站
正文,限长500汉字,1000英文(*)
验证码(*) 单击刷新验证码
联系我
博客订阅