joomla源代码探析续(二十五)JRequest对象的变量获取过程
2011-07-03 14:09
281 查看
Joomla 1.5 RC3版本的SEF存在不少问题,前段时间架站的时候曾经仔细看过这部分,昨天做apache转向的时候,突然发现又都忘记了,再回忆一次,记录下来。/index.php 中$mainframe->route(); 这一函数中实现了从URI中获取相关参数并填充到JRequest中,我们来看看这个函数的实现过程。这个函数的代码清单如下:
可以看到,首先克隆了一个JURI,然后$router->parse($uri),实现了uri的解析,返回的数组结果填充到了JRequest中。先简略看一下 JURI::getInstance() ,代码在enviroment/uri.php中,这里略过了。代码大体的实际就是兼容了apache与IIS,组成完成的URL路径,传递给JURI的构造器,最终生成JURI对象作为返回结果。接着我们来看看$result = $router->parse($uri) 实现了什么,以下是JRouterSite的parse函数的代码清单:
这段代码实际就是去掉了路径中的 index.php以及在SEF开启的状态下的后缀,并调用父类JRouter的parse函数。JRouter的parse函数代码清单如下:
我们来看看关键的两个函数,因为不会同时发生,我们只来看看 $this->_parseSefRoute($uri)函数。以下是JRouterSite的_parseSefRoute方法代码清单:
这段代码比较长,不详细分析了,实际上首先做了菜单项的比较,然后接着调用$uri->getQuery(true)返回query中的所有名称/值对,接着在合适的条件下调用相应组件下的router.php中对应路径解析函数,比如对于content,就是com_content/router.php的ContentParseRoute函数,最终整个函数生成了包含option,view,layout等在内的散列数组并返回。返回的数据经过merge后,返回给JRequest::set($result, 'get', false )至此全部的参数数值就写入到JRequest中了,注意这里只是 'get'方式传递的参数,不包括post方式提交的数据。
function route() { // get the full request URI $uri = clone(JURI::getInstance()); $router =& $this->getRouter(); $result = $router->parse($uri); JRequest::set($result, 'get', false ); }
可以看到,首先克隆了一个JURI,然后$router->parse($uri),实现了uri的解析,返回的数组结果填充到了JRequest中。先简略看一下 JURI::getInstance() ,代码在enviroment/uri.php中,这里略过了。代码大体的实际就是兼容了apache与IIS,组成完成的URL路径,传递给JURI的构造器,最终生成JURI对象作为返回结果。接着我们来看看$result = $router->parse($uri) 实现了什么,以下是JRouterSite的parse函数的代码清单:
function parse(&$uri) { $vars = array(); // Get the path $path = $uri->getPath(); //Remove the suffix if($this->_mode == JROUTER_MODE_SEF) { // Get the application $app =& JFactory::getApplication(); if($app->getCfg('sef_suffix') && !(substr($path, -9) == 'index.php' || substr($path, -1) == '/')) { if($suffix = pathinfo($path, PATHINFO_EXTENSION)) { $path = str_replace('.'.$suffix, ', $path); $vars['format'] = $suffix; } } } //Remove basepath $path = substr_replace($path, ', 0, strlen(JURI::base(true))); //Remove prefix $path = str_replace('index.php', ', $path); //Set the route $uri->setPath(trim($path , '/')); $vars += parent::parse($uri); return $vars; }
这段代码实际就是去掉了路径中的 index.php以及在SEF开启的状态下的后缀,并调用父类JRouter的parse函数。JRouter的parse函数代码清单如下:
unction parse(&$uri) { $vars = array(); // Process the parsed variables based on custom defined rules $vars = $this->_processParseRules($uri); // Parse RAW URL if($this->_mode == JROUTER_MODE_RAW) { $vars += $this->_parseRawRoute($uri); } // Parse SEF URL if($this->_mode == JROUTER_MODE_SEF) { $vars += $vars + $this->_parseSefRoute($uri); } return array_merge($this->getVars(), $vars); }
我们来看看关键的两个函数,因为不会同时发生,我们只来看看 $this->_parseSefRoute($uri)函数。以下是JRouterSite的_parseSefRoute方法代码清单:
function _parseSefRoute(&$uri) { $vars = array(); $menu =& JSite::getMenu(true); $route = $uri->getPath(); //Handle an empty URL (special case) if(empty($route)) { $item = $menu->getDefault(); //Set the information in the request $vars = $item->query; //Get the itemid $vars['Itemid'] = $item->id; // Set the active menu item $menu->setActive($vars['Itemid']); return $vars; } //Get the variables from the uri $vars = $uri->getQuery(true); /* * Parse the application route */ if(substr($route, 0, 9) == 'component') { $segments = explode('/', $route); $route = str_replace('component/'.$segments[1], ', $route); $vars['option'] = 'com_'.$segments[1]; $vars['Itemid'] = null; } else { //Need to reverse the array (highest sublevels first) $items = array_reverse($menu->getMenu()); foreach ($items as $item) { $lenght = strlen($item->route); //get the lenght of the route if($lenght > 0 && strpos($route.'/', $item->route.'/') === 0 && $item->type != 'menulink') { $route = substr($route, $lenght); $vars['Itemid'] = $item->id; $vars['option'] = $item->component; break; } } } // Set the active menu item if ( isset($vars['Itemid']) ) { $menu->setActive( $vars['Itemid'] ); } //Set the variables $this->setVars($vars); /* * Parse the component route */ if(!empty($route)) { $segments = explode('/', $route); array_shift($segments); // Handle component route $component = preg_replace('/[^A-Z0-9_\.-]/i', ', $this->_vars['option']); // Use the component routing handler if it exists $path = JPATH_BASE.DS.'components'.DS.$component.DS.'router.php'; if (file_exists($path) && count($segments)) { //decode the route segments $segments = $this->_decodeSegments($segments); require_once $path; $function = substr($component, 4).'ParseRoute'; $vars = $function($segments); $this->setVars($vars); } } else { //Set active menu item if($item =& $menu->getActive()) { $vars = $item->query; } } return $vars; }
这段代码比较长,不详细分析了,实际上首先做了菜单项的比较,然后接着调用$uri->getQuery(true)返回query中的所有名称/值对,接着在合适的条件下调用相应组件下的router.php中对应路径解析函数,比如对于content,就是com_content/router.php的ContentParseRoute函数,最终整个函数生成了包含option,view,layout等在内的散列数组并返回。返回的数据经过merge后,返回给JRequest::set($result, 'get', false )至此全部的参数数值就写入到JRequest中了,注意这里只是 'get'方式传递的参数,不包括post方式提交的数据。
相关文章推荐
- Hadoop map reduce 过程获取环境变量
- mysql 存储过程中 limit之后使用分页变量,传入分页参数. 类似于微博游标分批次获取信息;问号参数类似于c#的string.format;问号占位符
- 获取存储过程的返回值,用于其他变量中
- (转载)Hadoop map reduce 过程获取环境变量
- jsp页面通过 request对象直接获取 struts2 Action的变量的值。
- 数据库存储过程中定义一个变量,通过sql语句在数据表中获取这个变量值的方法。
- hadoop map reduce 过程获取环境变量
- [C语言]除非该数组为全局变量,否则只能在定义数组时获取数组长度,在传递过程中只是传递指针不能再次获取长度
- mfc中父对话框变量获取子对话框控件的变量
- MySQL存储过程中declare和set定义变量的区别
- PHP快速入门教程:服务器和浏览器变量获取示例
- SpringMVC与Freemarker整合获取request对象
- 使用Request对象的Browser获取客户端浏览器的基本信息
- thinkphp3.x中变量的获取和过滤方法详解
- 获取SqlServer存储过程定义的三种方法
- php URL各部分获取方法(全局变量)
- 存储过程中sql语句按变量进行判断执行相应的查询条件
- Java中获取request对象的几种方法
- https和http 调用过程中请求头 referrer 获取不到的问题
- oracle和sqlserver在过程sql中通过select对变量进行赋值的区别及实例