来源:http://trac.seagullproject.org/wiki/Howto/UriManagement

URI管理

简介

这篇文章指出了如何使用seagull中的前端控制器的功能,以及如何输入和输出相关的URI

新Front Controller功能的目的是使Seagull使用对搜索引擎友好的URL,即:

  • 易于收入书签
  • 和大部分搜索引擎的爬行器(Search Engine spider/crawler的翻译)兼容
  • 可根据需要深入到应用程序的功能
  • 可以被诸如Webalizer流量分析程序跟踪

关于简洁干净的URI的相关资料请参考:

http://www.port80software.com/support/articles/nextgenerationurls

本文的讨论将分成两部分

  • input URIs - 获取由Seagull解析的请求
  • output URIs - 组成嵌入在生成的HTML页面中的超级链接的URI字符串

输入URI

格式

Seagull期望的URL格式是:http://example.com/index.php/user/login/action/list/foo/bar

schemehttp
domainexample.com
front controller scriptname index.php
module name user
class name login
action name list
url params foo=bar

因此下列的URL:

http://localhost/seagull/www/index.php/user/login/action/list/foo/bar/fom/baz/

将会被SGL_HTTP_Request对象解析成:

Array
(
    [frontScriptName] => index.php
    [moduleName] => user
    [managerName] => login
    [action] => list
    [foo] => bar
    [fom] => baz
    [SGLSESSID] => 501d9d8b4452f84421fc214dd3fe7979
)

并存储在一个单件的request中。关于Request对象的更多资料请看这里

也支持下列这些格式的URL:

http://localhost/foo/
http://localhost/foo/bar/
http://localhost/foo/bar/key/value/
http://localhost/foo/bar/action/list/
http://localhost/foo/bar/action/list/key/value/

URI分析策略

SGL_Request对象第一次初始化时,它载入了一个策略数组,这些策略是可配置的,用来解析当前的请求。每一个解析策略尝试对URI进行模式匹配。默认调用了三个解析策略,但是开发者可以通过载入和重新安排策略的顺序来自定义URI的解析方法。下列代码可以实现这个功能:

  require_once dirname(__FILE__) . '/UrlParser/SimpleStrategy.php';
  require_once dirname(__FILE__) . '/UrlParser/AliasStrategy.php';
  require_once dirname(__FILE__) . '/UrlParser/ClassicStrategy.php';
  $aStrats = array(
      new SGL_UrlParser_ClassicStrategy(),
      new SGL_UrlParser_AliasStrategy(),
      new SGL_UrlParser_SefStrategy(),
      );
  $uri = new SGL_URL($_SERVER['PHP_SELF'], true, $aStrats);

默认的策略是:

结果对象$uri被缓存,这样最大限度减少了潜在的不必要耗费资源的解析

SGL_Url和SGL_Request的API

在解析完后,大部分的请求数据保存在SGL_Request对象:

$aQueryData = $uri->getQueryData();
$this->aProps = array_merge($_GET, $_FILES, $aQueryData, $_POST);

这些数据可以通过getters和setters方法取得。

保存在URI对象中的更详细的信息可以通过URI API获取。查看文档以获得更多信息。

设置Cookie路径引起的问题

当你使用SEF URI时并且你有在javascript脚本代码中设置cookies,你必须显式的设定cookie路径,否则当前的URI会被使用(在使用标准URI时不存在这个问题,因为浏览器剥离最后一个/之后的所有东西)。如,

classic URI:http://computer.name/seagull/www/tdbMgr.php?element_id=86&toId=13&treeParent=566 cookie路径应该是http://computer.name/seagull/www/

Seagull URI:http://computer.name/seagull/www/index.php/tdb/element_id/86/toId/13/treeParent/566/ cookie路径应该是 http://computer.name/seagull/www/index.php/tdb/element_id/86/toId/13/treeParent/566/

所以可以像这样设置路径 document.cookie = ‘foo=bar ; path=/’

服务器配置需求

URLs的这种实现方法,你的服务器配置不需要做任何修改。出于同样原因,你并不是一定要运行Apache,使用IIS等其它服务器的系统一样也将运行得很好。

灵活性

这种URL的格式有很大的灵活性:

  • front controller的脚本名称是可配置的;另外,你可以使用Apache的ForceType指令来去掉文件扩展名,即:
<Files article>
  ForceType application/x-httpd-php
</Files>

你使可以用这样的URL:

http://example.com/obidos/user/login/action/list/foo/barhttp://example.com/seagull/user/login/action/list/foo/bar

  • 如果你使用Apache服务器并编译了mod_rewrite模块,front controller的脚本名称可全部去掉,可以这么做:
    • 编辑全局配置文件,seagull/var/<servername>.conf.php,做如下设置: $conf[site][frontScriptName] = false;
    • 拷贝 /branches/0.6-bugfix/etc/htaccess-cleanUrl.dist 到你的seagull/www目录并重命名成rename to “.htaccess”
  • URLs的模块名和管理类名这两个部分是不区分大小写。因此下列的URLs都是可接受的,但是推荐你不论在什么时候尽可能全部使用小写字母;
http://example.com/index.php/UsEr/LoGiN/action/list/foo/bar
http://example.com/index.php/USER/login/action/list/foo/bar
  • 类名中的’Mgr’后缀是可选的, - 因为大多类的模块的管理类都使用它,所以在URL中是多余的,因此,下列的两个都可以接受:
http://example.com/index.php/user/loginMgr/action/list/foo/bar
http://example.com/index.php/user/login/action/list/foo/bar
  • 如果模块或类名同样的,模块或类名可不必全写。换句话,许多模块都有一个默认的与模块名相同(至少在URL中是相同的)的管理类,这样在URLs是多余的,如下列的:
http://example.com/index.php/faq/faq/action/list/foo/bar
http://example.com/index.php/user/user/action/list/foo/bar

因此,建议不要明确地调用默认的管理类,因为它已经包含在模块名中。

  • action参数也是可选的:这样,当它不存在时,将会调用设置在管理类中的默认action。因此,下列的两个URLs是相同的:
http://example.com/index.php/user/login/action/list/foo/bar
http://example.com/index.php/user/login/foo/bar

输出URI

在模板中创建URLs

使用Output对象中的makeUrl()方法,这个方法可以在模板范围内使用。这儿有个例子:

this is a <a href="{makeUrl(#edit#)}/foo/{bar}">link</a>

makeUrl()方法接受3个可选的含义直观参数,按重要性顺序是:action,className,moduleName。如果没有提供任何值,将使用当前值将。换句话说,FAQ管理的模板中,如果你没有指定makeUrl()的参数,将提供当前的值,即:

action = list
managerName = FaqMgr
moduleName = faq

你可以使用这种格式来发送查询字符串参数给脚本。makeUrl()方法也提供了下列的功能性:

  • scheme的类型将会自动检测并保存下来,即,如果你使用https模式,生成的链接将也是https模式
  • 当cookie无效的时,session信息将会自动被添加到URL中

当从头到尾叠代resultsets时,使用以下的格式:

this is a <a href="{makeUrl(#edit#,#user#,#user#,aPagedData[data],#frmUserID|usr_id||frmEmail|email#,key)}">complex link</a>

然而这将导致frmUserID和frmEmail参数被设成如下的值:

  • frmUsrID = aPagedData[data][key][usr_id]
  • frmEmail = aPagedData[data][key][email]

参数如下:

1. action
2. module
3. manager
4. 数组的数组或象征数据收集的对象
5. frmVariableName1|dataFieldName1||frmVariableName2|dataFieldName2
6. 数组的索引

如果你不是遍历一个对象数组,可以你下面这样传递一个对象:

{makeUrl(#profil#,#klienci#,#klienci#,##,#frmUserID|$oNews->usr_usr_id#)}

在模板中输出当前URL

如果你要在页面上生成锚或类似的链接,有可能你想在模板中生成当前URL的链接(Seagull 0.6.1及以上版本可以用getCurrentUrl())。可以这样生成:

<a href="{getCurrentUrl()}">foo</a>

对于评论锚,应该像这样:

<a href="{getCurrentUrl()}#comment{increment(key)}">#{increment(key)}</a>

在模块中生成URI

如果你需要在模块中生成URI,可以用SGL_Output::makeUrl()。参数和上面一样,所以代码应该是这样的:

SGL_Output::makeUrl('profil','klienci','klienci',array(),'frmUserID|'.$oNews->usr_usr_id);

在JavaScript中生成URI

你可以在JavaScript中生成URI, 格式是这样的:

var myUri = makeUrl({'module':'mymodule', 'action':'myaction', 'param2': 'foo bar'});

var myUri = makeUrl({'module':'mymodule', 'manager':'mymanager', 'action':'myaction', 'param2': 'foo bar'});

module and action params are mantadory,你也可以指定一个管理类,其它的参数以’name’:’value’这样的形式添加到URI的尾部。

 
howto/urimanagement.txt · 上一次变更: 2007/07/04 10:57 通过 xinhaozheng
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki