joomla源代码探析续(二十五)JRequest对象的变量获取过程

Joomla 1.5 RC3版本的SEF存在不少问题,前段时间架站的时候曾经仔细看过这部分,昨天做apache转向的时候,突然发现又都忘记了,再回忆一次,记录下来。

/index.php 中$mainframe->route(); 这一函数中实现了从URI中获取相关参数并填充到JRequest中,我们来看看这个函数的实现过程。

这个函数的代码清单如下:

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方式提交的数据。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果您想使用自己的代码建立Joomla网站,可以按照以下步骤进行操作: 1. 创建Joomla安装环境:将Joomla安装文件上传到您的Web服务器,并按照安装指南进行安装。确保您的服务器环境满足Joomla的最低要求。 2. 创建自定义模板:在Joomla安装目录的/templates文件夹中创建一个新的文件夹,用于存放您的自定义模板文件。在该文件夹中创建一个index.php文件,作为您的模板的入口文件。 3. 编写模板代码:使用HTML、CSS和PHP等技术编写模板代码。您可以根据自己的需求和设计来创建网站的布局、样式和功能。在index.php文件中,您可以使用Joomla提供的模板标记和函数来获取内容并将其渲染到网页中。 4. 创建模块和组件:如果您需要自定义模块或组件,可以在Joomla安装目录的/modules和/components文件夹中创建相应的文件夹,并在其中编写您的代码。根据Joomla的开发文档和API参考,您可以创建自己的模块和组件来扩展Joomla的功能。 5. 安装和启用模板、模块和组件:登录Joomla后台管理界面,选择“扩展”选项卡,然后选择“模板管理”、“模块管理”或“组件管理”,分别安装和启用您创建的模板、模块和组件。 6. 添加内容和配置网站:使用Joomla的后台管理界面,您可以添加网站内容、创建菜单和配置网站设置。根据您的自定义代码和需求,使用Joomla提供的功能来管理和展示内容。 7. 测试和优化:在网站开发完成后,进行测试并进行必要的调整和优化。确保您的网站在不同浏览器和设备上都能正常显示和运行。 这些是使用自己的代码建立Joomla网站的基本步骤。请注意,使用自定义代码需要一定的编程知识和经验。在开发过程中,您可以参考Joomla的开发文档和社区资源,以获取更多关于Joomla开发的指导和帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值