本节分享下,zf中zend_cache的一个例子。
代码如下:
<?php /** * Zend Cache用法举例 * edit by www. */ require 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Cache'); Zend_Loader::loadClass('Zend_Config'); Zend_Loader::loadClass('Zend_Registry'); $config = new Zend_Config_Ini('configsecr/config.ini'); define('CACHE_DIR',FDROOT.'/'.'tmp/'); /* config.ini [cache] cache.needcache=1 cache.frontend.name=Core cache.frontend.lifetime=7200 cache.frontend.automatic_serialization=1 cache.backend.name=File */ /*选项参考手册*/ /*建立cache对象*/ $frontendOptions = $config->cache->cache->frontend->toArray(); $backendOptions = $config->cache->cache->backend->toArray(); $frontendName = $frontendOptions['name']; unset($frontendOptions['name']); $backendName = $backendOptions['name']; unset($backendOptions['name']); if (empty($backendOptions['cache_dir'])) { $backendOptions['cache_dir'] = CACHE_DIR; } $_cache = Zend_Cache::factory($frontendName, $backendName, $frontendOptions, $backendOptions); Zend_Registry::set('cache', $_cache); /*使用cache*/ $viewRenderer = $_cache->load('viewRenderer'); //试图从缓存加载变量 if (!$viewRenderer instanceof Something)//加载不成功 { $viewRenderer = new Something(); /*some other work*/ $_cache->save($viewRenderer, 'viewRenderer');//保存变量到换存 } /*使用Zend Cache还可以轻松缓存整页;且可将缓存存到数据库或者内存。大家好好研究下哦。*/ ?>
session状态自动更新的实现代码,如下:
<?php //保存当前session id; $my_session_id = $_COOKIE[session_name()]; session_start(); .......//一些操作,比如验证当前用户是否有权限操作session更新 {//此处可以循环以操作多个其他用户的session session_write_close (); session_id($_refresh_user_sessoin_id); //$_refresh_user_sessoin_id 是想要更新的其它用户的session的id; //用 session_id()函数不带参数即可取得当前用户的sessionid,但需要在session-start()之后,否则用$_COOKIE[session_name()]; session_start(); .....//对要操作的session进行操作. }//循环处理结束 session_write_close (); session_id($my_session_id);//还原当前用户的session session_start(); ?>
首先,保存想要刷新的人员的sessionid。
本节分享的php多线程的知识,需要用到php的pcntl_fork函数,此函数依赖操作系统fork的实现,以上内容仅适用于linux/unix系统。
来看下pcntl_fork函数的用法:
<?php $pid = pcntl_fork(); if ($pid == -1) { die('could not fork'); } else if ($pid) { // we are the parent pcntl_wait($status); //Protect against Zombie children } else { // we are the child } ?>
通过pcntl_fork创建一个子进程。
如果返回值是-1的话,那么说明子进程创建失败。
创建成功的进程id会返回给父进程,0返回给子进程。
习惯这样写:
<?php $pid = pcntl_fork(); if($pid == -1){ //创建失败咱就退出呗,没啥好说的 die('could not fork'); } else{ if($pid){ //父进程代码,由于是系统程序,请退出值给出返回值 exit(0); } else{ //在新的进程中执行的程序,正常退出的话,也需要返回值 exit(0); } } ?>
如果父进程希望知道子进程正常退出的话,可以加上前面的pcntl_wait。
下面说说其在实际开发中的作用。
1,后台程序
命令行程序好写,服务程序也好写,笔者觉得这服务程序最难写。
linux想让个命令行程序在后台运行,直接在命令后面加个&就搞定了.但是这样总觉得土.有了pcntl_fork突然发现世界是那么的美好.当主进程成功创建子进程并获得子进程的id以后,自己在临死前还不忘说一句:"我已成功运行,我的id是:xxxx(子进程的id)",完了还给系统返回个0(正常退出)。
前面说的是程序常驻内存的情况,注意内存的释放以及向日志文件打印信息,而不是往屏幕上(一打印信息程序就退出的哟).还有一种情况是:程序被其它脚本调用,其它脚本只关心程序是不是正常运行,如果程序要运行很长时间才能运行完的话,最好不让脚本等待.这样的话pcntl_fork又派上用场了:)
2,延时处理.
有时程序退出时要清理自身产生的东西,比如说要删除自己(当然了linux下面是可以删除正在运行的文件的,只是举个例子),这个时候就可以另起动一个进程,然后自己结束了,把事情交给另一个进程来做.当我们写服务程序时,我们肯定是写日志文件记录程序的运行情况(要不谁知道程序是不是在那睡大觉的:0).程序正常退出时我们可以写一条日志说程序退出了,但是当程序收到linux下伟大的kill -9时,怎么记录自己的退出行为呢?额.....这个和php的进程信号有关好像和这个没多大关系。
情况2,一个完善的程序一般都支持start,stop,restart这样的参数.start好说,stop也好说,既然start和stop都好说了,这个restart就先stop然后再start就可以了啊.额...好像又和pcntl_fork没多大关系,当收到重启的信号总不能还是kill然后再start吧。
温柔些的做法就是当前进程退出,让另外的进程再把它拉起来。
3,不死进程
也就是所谓的双进程。