PHP全局缓存上栽的坑及其他【反面教材系列】
五一以来工作状态不好,就没更新iOS系列。暂时也没iOS项目,先边学边做PHP。这篇就当个随笔吧。
不太记得当年跑起来第一个ASP.NET 2.0的程序花了我多少时间了。。。只记得相当痛苦。那还是在05年初,VS2005还没发布的时候。
相比之下,PHP的上手简单得可以用“令人发指”来形容。
总结了一下有几个原因:
- 多少会用Google和stackoverflow了
- 有ASP.NET的web开发经验作为参考
- PHP代码的结构相比ASP.NET简单干净了很多
- PHP语言本身设计的目的相对专一:web
于是完全没看教程,倚仗Google一路高歌猛进。
但今天终于发现这种学习方式的一大弊端:光凭ASP.NET的惯性思维,在遇到PHP和ASP.NET的差异时会踩雷。
说一下今天的踩雷经过:
需求为将文件形式的代码,改为从数据库里读取代码字符串,然后通过eval方法动态加载执行(关于eval的使用方法可以参见这篇:http://www.cnblogs.com/galaxyyao/archive/2013/04/25/3043104.html)
进展很顺利。新建一个ClassInitializer类,在类里数据,读取,eval,over。唯一带来一些麻烦的是调试,只能靠输出来判断是不是正确执行了。
写完后我测试了一下,发现每次request,ClassInitializer类都会重新从数据库读取。嗯,应该是我没有检测是否初始化过的问题。不行,这样会有Performance问题吧。
于是添加了一个静态变量来检测是否加载过:
private static $hasInitialized = false;
然后在初始化结束后改为true。嗯?还是不行?大概是我没有变成单例模式吧。
于是搜索关键字php singleton,改写ClassInitializer。嗯?还是不行?是因为在类里的原因吧?
于是提出来,做成全局变量。依然不行。
于是继续搜索,发现一个让我ORZ的结论:PHP“没有”在request之间的共享变量的方法。。。
好吧,那么我改用缓存总可以了吧?因为原本需求就是避免文件形式,所以文件形式的缓存pass。
ASP.NET里一般是用Application或Session,似乎PHP也有$_SESSION,那么我们再试下?
依然失败。似乎stackoverflow上还有回复说可以用memcache或APC?查了一下都是插件,不符合需求,pass。
最终发现stackoverflow的回复:
The life span of PHP (and its variables) over a request:
- Request is sent to server, whether by user, ajax, curl through PHP or what-have-you
- Relevant PHP script is executed, whether as a module on your web server, a CGI worker process, or other options
- Script is executed, response to the request (if any) is created and sent
- (optional) script continues to execute some other job until eventual termination, at which time all its variables die with it.
以及
In short, no, such a thing is not available natively in PHP. To understand why, you have to understand that PHP has its entire environment built for each request, and it is subsequently torn down at the end of the request. PHP does give you $_SESSION to store per session variables, but after digging into the docs you will see that that variable is built during each request also. PHP (or mod php to be more specific) is fundamentally different from other "application servers". Basically, it is not an application server. It is a per request script runner.
Now, don't get me wrong, PHP lets you do application level data store, but you will have to go to a database, or to disk to get it.
回顾了一下,这个问题如果我有看过一些基础PHP教程的话应该就能绕过,也不会花这么大半天的时候最后还是采用最初方案了。
还是找个时间通读一遍PHP的经典教材吧。
语法细节可以在需要的时候当场查,但架构和原理需要专门系统性地学习,这是今天的教训。