xser php5 framework v0.11 测试版 新增的功能 -- 带完美缓存功能的控制器

本文介绍XserPHP5框架中的视图缓存功能,包括缓存策略设置、控制器缓存启用方法、缓存文件生成及更新机制等。通过简单的配置,即可实现强大的缓存功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

xser php5 framework v0.11 测试版 新增的功能

对于视图缓存控制的处理,轻松设置就能实现功能强大的缓存功能.
颗粒度细分到action,对不同的udi资源[命名空间::控制器/action@模块] 能自定义缓存文件路径信息设置

1. config/html-cache-rules.php 

// 缓存策略设置文件 遵循udi_string格式

return array(

	//=> welcome.html , welcome.html.asc
	'default::application/index@default' => 'default/welcome.html' , 

	'default::application/show@default' => 'default/application/show/{name}-{book_id}.html' ,

);

其中 花括号包含的是 可变量,他们由前端$_GET数组中的值来替换.缓存文件对应到 cache/_app/ 这个目录
比如: 

index.php?e=show&name=xx&book_id=112 对应于 cache/_app/default/application/show/xx-112.html

2. 控制器设置,要启用缓存功能,不用担心要写很多辅助代码,只需重写以下方法
	
	protected function _before_execute($action_method){
		$this->enable_cache = true ; // 将这行加入其中即可
	}

例如: application 控制器为默认控制器,
在 config/boot.php中进行了设置: 'default_controller'  => 'application',

class application_controller extends xser_controller {
	
	function actionIndex(){		
		$this->_view['current_uri'] = 'index.php?q=application&e=index' ;
	}
	function actionShow(){
		$this->_view['name'] = $_GET['name'] ; 
		$this->_view['book_id'] = $_GET['book_id'] ; 
		$this->_view['current_uri'] = 'index.php?q=application&e=show' ;		
	}
	
	protected function _before_execute($action_method){
		$this->enable_cache = true ;
	}
}


default::application/index@default 对应的视图文件如下: view/default/application/index.rhtml

<?php $this->_block('contents'); ?>
<h3><?php echo $current_uri ;?></h3>
<?php $this->_endblock(); ?>

<?php $this->_element('test'); ?>


default::application/show@default 对应的视图文件如下: view/default/application/show.rhtml

<?php $this->_block('contents'); ?>
<h3><?php echo $name . ' -- ' . $book_id;?></h3>
<?php $this->_endblock(); ?>

<?php $this->_element('test'); ?>

default::application@default 对应的元素 test的内容如下: view/default/_elements/test.rhtml
<h2>This is a element file2 !</h2>


index.php?e=show&name=xx&book_id=112 生成的缓存文件如下: cache/_app/default/application/show/xx-112.html
<h3>xx -- 112</h3>

<h2>This is a element file2 !</h2>

index.php 生成的缓存文件如下: cache/_app/default/welcome.html
<h3>index.php?q=application&e=index</h3>

<h2>This is a element file2 !</h2>


3. 缓存更新的策略: 大家应该知道缓存文件的更新很多框架并没有具体实现,像smarty虽然提供了,但是对于局部更新
似乎并不简单,这里色色基本实现了缓存自动更新的一种简单方式...

/**
 * 缓存更新的条件:
 * 1. 模板文件发生了改变: 里面引用的模板文件发生变化
 * 		[布局模板文件,视图模板文件,元素模板文件]被更新
 * 		
 * 2. 内容发生了更新
 * 		[修改对应的数据缓存属性文件的时间戳]
 * 
 * 每个缓存对应着两个文件: 数据缓存文件[xx.html],数据缓存属性文件[xx.html.asc]
 * 
 * 缓存文件名模板: ns/mod/q/e/{name}.html => /admin/sys/user/show/lily.html
 */
class xser_html_cache 

缓存具体都由这个类来处理,提供了三个公共方法

public function get_cache_content($udi_string,$cache_tplname_vars)
public function cache_had_expired($udi_string,$cache_tplname_vars)
public function put_cache_content($udi_string,$cache_tplname_vars,$cache_prop,$cache_content)

此类在框架中是一个单态形式的,使用前必须定义缓存策略设置文件config/html-cache-rules.php 

这 三个方法 除了 cache_had_expired 这个提供给用户使用外,其它2个均由框架自身使用.
cache_had_expired 方法用于应对第二个缓存更新的条件: 内容发生了更新

比如 咱在后台更新了 index.php?e=show&name=xx&book_id=112 它对应的数据内容,简单调用此方法即可,例如:

在 上文中提到的	application_controller

	protected function actionq(){
		// 数据更新操作
		
		// 设置缓存过期
		xser::singleton('xser_html_cache')
			->cache_had_expired('default::application/show@default',array(
				'name' => 'xx' , 
				'book_id' => '112' , 
			));
	}


4. 对控制器的缓存功能的扩展,比如定义 控制器中 某些action才享有缓存功能,可以如下设置
	
	protected function _before_execute($action_method){
		$enable_cache_actions = array('index','show');
		if (in_array($action_method,$enable_cache_actions))
			$this->enable_cache = true ;
	}

5. 所有这一切都是在xser_controller这个控制器的基类中实现的,代码并未加多少,整个类的代码才136行,包含空行和注释
	
	protected $enable_cache = false ; //新增变量
	
	public function execute($action_name,xser_udi_object $udi){
		
		$action_method = "action{$action_name}";
		
		if ($this->method_exists($action_method)){
			
			$this->udi = $udi ;
			
			
			// 调用 _before_execute() 方法
            $this->_before_execute($action_method);
                        
			// 缓存存在,直接取出缓存
			if ($this->enable_cache){
				$cache_content = $this->get_cache_content();
				if ($cache_content != false ){
					return $cache_content ;
				}
//				xser::dump($cache_content,'why?');
				unset($cache_content);
				xser::replaceIni('__html_cache_tplname_vars#'.$udi->to_string(),$_GET);
			}
            
            // 执行 action 方法
            $ret = $this->{$action_method}();
            // 调用 _after_execute() 方法
            $this->_after_execute($ret);
            
            if ($this->is_render()){
            	// 加载视图组件,进行渲染操作
            	xser::loadlibrary($this->_view_engine,'xser');
            	$view_class = "xser_{$this->_view_engine}" ;
            	$view_render = new $view_class($this->udi);
            	$view_render->assign($this->_view);
            	//渲染之前执行 
            	$this->_before_render($view_render);
            	
            	// 启用缓存,但缓存不存在,在视图组件中生成缓存
            	return $view_render->execute($this->enable_cache);
            }
		}else {
			$notice = sprintf('Action "%s" not defined in "%s".',
            	$action_name,$udi['mapping_info']['controller_file'].'#'.get_class($this));
            echo $notice ;
	        Xser::log_provider()->exception($notice);  
//	        throw new Exception($notice);       
        }
			
		return null;
	}
	
	// 缓存扩展
	protected function get_cache_content(){
		xser::loadlibrary('html_cache','xser');
		return xser::singleton('xser_html_cache')->get_cache_content(
			$this->udi->to_string(),$_GET ) ;
	}
	
6. 视图引擎组件也相应的做了些改变 class xser_view

	// 新增变量
	protected $_enable_cache = false ; //启用缓存
	protected $udi_string = null ;
	
	protected function reinit(xser_udi_object $udi){
		$this->udi_mapping_info = $udi->mapping_info() ;
		$this->udi_string = $udi->to_string();
		$this->_vars = array(
			'base_uri' => xser::ini('base_uri'),
		); 
	}
	
	public function execute($enable_cache=false){
		$this->_enable_cache = $enable_cache ;
		$this->display();
	}
	
	function fetch()
    {
        $this->_before_render();
        
        $filename = Xser::ini('application_dir') ."/{$this->udi_mapping_info['view_action_file']}";
		if (file_exists($filename))
        {
            $view_parse = new xser_view_parse($this->_vars);
            $output = $view_parse->reset_ref_tpls()->parse($this->udi_mapping_info['view_action_file']);
            
            if ($this->_enable_cache){ // 新增代码
            	//引用的模板列表属性设置
            	$ref_tpls_prop = $view_parse->get_ref_tpls();
            	if (!empty($ref_tpls_prop)){
            		if (!class_exists('xser_html_cache'))
            			xser::loadlibrary('html_cache','xser');
            		$cache_tplname_vars = xser::ini("__html_cache_tplname_vars#{$this->udi_string}",$_GET);
            		xser::cleanIni("__html_cache_tplname_vars#{$this->udi_string}");
            		xser::singleton('xser_html_cache')
            			->put_cache_content($this->udi_string,$cache_tplname_vars,$ref_tpls_prop,$output);		
            	}
            }
        }
        else
        {
        	$notice = "view file not exist: [{$this->udi_mapping_info['view_action_file']}]" ;
        	echo $notice ;
        	Xser::log_provider()->exception($notice);
        	return ;
//        	throw new Exception($notice);
            $output = '';
        }

        $this->_after_render($output);
        return $output;
    }
    
7. class xser_view_parse  的变化

	protected $_ref_tpls = array() ; 
	
	public function get_ref_tpls(){ // 获取引用的模板文件
		return $this->_ref_tpls ;
	}
	/**
	 * @return xser_view_parse
	 */
	public function reset_ref_tpls(){ 
		$this->_ref_tpls = array();
		return $this ;
	}
	
	/**
     * 载入视图文件
     */
    protected function _include($___tpl, array $___vars = null)
    {
    	$file = Xser::ini('application_dir') . "/{$___tpl}" ; 
    	if (!file_exists($file)){    		
    		$notice = "view file1 not exist: [{$___tpl}]" ;
    		Xser::log_provider()->exception($notice);
    		echo $notice ; return ;
//    		throw new Exception($notice);
    	}
    	$this->_ref_tpls[$___tpl] = filemtime($file) ;
    	
        extract($this->_vars);
        if (is_array($___vars)) extract($___vars);
        include $file;
    }

 

资源下载链接为: https://pan.quark.cn/s/67c535f75d4c 在机器人技术中,轨迹规划是实现机器人从一个位置平稳高效移动到另一个位置的核心环节。本资源提供了一套基于 MATLAB 的机器人轨迹规划程序,涵盖了关节空间和笛卡尔空间两种规划方式。MATLAB 是一种强大的数值计算与可视化工具,凭借其灵活易用的特点,常被用于机器人控制算法的开发与仿真。 关节空间轨迹规划主要关注机器人各关节角度的变化,生成从初始配置到目标配置的连续路径。其关键知识点包括: 关节变量:指机器人各关节的旋转角度或伸缩长度。 运动学逆解:通过数学方法从末端执行器的目标位置反推关节变量。 路径平滑:确保关节变量轨迹连续且无抖动,常用方法有 S 型曲线拟合、多项式插值等。 速度和加速度限制:考虑关节的实际物理限制,确保轨迹在允许的动态范围内。 碰撞避免:在规划过程中避免关节与其他物体发生碰撞。 笛卡尔空间轨迹规划直接处理机器人末端执行器在工作空间中的位置和姿态变化,涉及以下内容: 工作空间:机器人可到达的所有三维空间点的集合。 路径规划:在工作空间中找到一条从起点到终点的无碰撞路径。 障碍物表示:采用二维或三维网格、Voronoi 图、Octree 等数据结构表示工作空间中的障碍物。 轨迹生成:通过样条曲线、直线插值等方法生成平滑路径。 实时更新:在规划过程中实时检测并避开新出现的障碍物。 在 MATLAB 中实现上述规划方法,可以借助其内置函数和工具箱: 优化工具箱:用于解决运动学逆解和路径规划中的优化问题。 Simulink:可视化建模环境,适合构建和仿真复杂的控制系统。 ODE 求解器:如 ode45,用于求解机器人动力学方程和轨迹执行过程中的运动学问题。 在实际应用中,通常会结合关节空间和笛卡尔空间的规划方法。先在关节空间生成平滑轨迹,再通过运动学正解将关节轨迹转换为笛卡
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值