昨天在调试代码时,在同一个sever上有两个版本的代码,刚开始在一个新版本做开发,由于需要调试旧版本的问题,因此访问旧版本代码时,发现无论访问什 么都是空白页,php环境变量设置的display_errors=1,error_reporting=E_ALL,按道理不应该是空白页,最有可能的 是入口程序的某一部分使用了@抑制了fatal error,刚开始以为是权限验证,后来发现似乎还没进入controller就死掉了,只好一步一步的跟踪框架的加载程序,最终发现是框架内部对 session封装的类里调用:
@session_start()Maven生成项目站点

 导致的,看了一下调用栈,发现session_start()时,如果有对象保存在session中,会自动调用这个对象的__wakeup将这 个对象反序列化,同理,在session赋值后,如果是直接将对象保存在session中也会自动调用这个对象的__sleep方法将这个对象序列化。而 框架定义了自己的spl_autoload,因此在旧版本里寻找新版本的对象定义时,找不到对应的类文件,因此会导致一个fatal error,从而变成空白。

我的CHM格式PHP手册没有对这个隐含的序列化和反序列化说明,以下是PHP官网对serilize()函数中提到的:

如果你是用session,并且调用session_register()注册对象,这些对象会在每个PHP页面的运行结束后自动序列化,也会在其他页面自动反序列化。这基本上意味着这些对象一旦成为session的一部分,他就能在你的各个页面中使用。

即使你再其他页面不使用一些类定义,也强烈推荐你在所有页面include全部像这样进行过session注册对象的类定义文件。如果你不这么做的话,如果一个对象在一个看不到它的类定义的情况下反序列化时,他就变成一个不包含任何函数的stdClass,也就是说这个对象基本是一个没有意义的对象了。


只有注册用户登录后才能发表评论。
网站导航:

posts - 139, comments - 0, trackbacks - 0, articles - 0

Copyright © PHP博客