rickywu
(Ricky Wu Y)
1
现在Yii的生命周期为
[list=1]
[*]通过 CApplication::preinit() 预初始化应用;
[*]设置类的自动装载器和错误处理;
[*]注册核心类组件;
[*]加载应用配置;
[*]通过 CApplication::init() 初始化应用:
[*]触发 onBeginRequest 事件;
[*]处理用户请求:
[*]触发 onEndRequest 事件。
[/list]
在下以为,应予以修改为:
1,创建urlManager组件.
2,解析用户请求;
3,预初始化其它应用;
4,设置类的自动装载器和错误处理;
5,注册核心类组件;
6,加载应用配置,包括模块配置统一加载;
7,通过 CApplication::init() 初始化应用:
8,触发 onBeginRequest 事件;
9,处理用户请求:
10,触发 onEndRequest 事件。
之所以把创建urlManager组件,解析用户请求放在第一位,
是由于,在现在的周期流程之下,在模块中的配置不能一开始就和应用主配置同步。
运行状态下,模块的配置不起作用,不能覆盖主配置。
举个例子,
在主配置config中,设置了组件的属性,如果想在模块中,进行修改,preinit()或者init()中设置Yii::app()->setComponents($componentsConfig),或者Yii::app()->configure($config)都不能奏效。
拿urlManager来说,假如,主配置中设为path格式,模块要独立为get格式,通过以上方法,都不能奏效。
直接Yii::app()->urlManager->urlFormat='get’倒是可以,生成的链接不再是path格式,但点击时却不能有效解析,直接返回了没有参数的默认的控制器动作结果。
如果应用从用户请求开始,就能基于请求的模块加载配置,则问题会简单很多。
感觉现在Yii的执行流程和urlManager对url的控制解析,都需要改进。
基于这个问题,在这里提出粗浅的见解。至于具体方法,上面只是一个不成熟的建议。
表述中有不当,不详尽的地方,还望见谅。
正确与否,也望各位朋友和qiang哥莫怪。
qiang
(Qiang Xue)
2
这是个鸡和蛋的问题:URL的解析决定了使用哪个module;你又希望module能决定URL的解析。
在实践中,一个应用里的URL格式应该是统一的,而不应该让module来决定。module是从属于application的。
如果不同的module决定不同的URL解析方式,可能造成冲突。
rickywu
(Ricky Wu Y)
3
假如原来的urlFormat为get,然后改为path,我希望原来的链接继续有效,但现在是无效的,对SEO可能不太好。
如果把创建urlManager组件,解析用户请求放在第一步,不论是get,还是path,现在也只有这两种,都能首先决定使用哪个module。继而就有可能依靠该module的配置决定接下来页面中链接生成的方式。也能配置其它专属于该module的其它配置。所以,这可以不必是一个鸡和蛋的问题,可以打另外一个比方,不管是皇帝,还是大巨,还是平民,不管是坐车,还是骑马,还是走路,他们都可以从一个城门进入,互不冲突。把创建urlManager组件,解析用户请求放在第一步,并不是由module决定url的解析,仍然由urlManager决定,只不过,这时urlManager必须自己识别urlFormat是get,还是path,而不是仅依靠config中的配置。module是从属于application的,但是在module应用中,module就是主角,module最大,可能需要重写application的配置。Yii::app()->setComponents($componentsConfig),或者 Yii::app()->configure($config),并不能够起这种作用,不论组件是urlManager,还是其它的,为何?是完全从属,还是一定程度的独立,这两者之间应该是可以均衡考虑的。多谢qiang百忙之中,关注到并回答这个问题。希望可以继续得到您的解惑答疑。
qiang
(Qiang Xue)
4
针对你的特定问题"如何让get的url继续有效":你可以考虑使用apache rewrite规则,对老的URL进行301重定向。
我不太理解两个问题:
-
怎么让url manager自己识别urlFormat是get还是path
-
在预先没有任何配置的情况下,如何让url manager正确判断出当前用户请求的是什么module(注意:你希望module可以更改url manager的配置)
rickywu
(Ricky Wu Y)
5
1,直接从url中可以看出区别,再者,path有rules,get没有,可以从这两点判断。
2,当第一个问题解决了之后,就可以知道是什么module。在这里,不是预先没有任何配置,有url manager的配置。先初始化url manager的配置,再解析url,接下来再配置应用的其它部分。分成两步配置,但可以让module专有配置重写主配置。
这是否可行呢?
qiang
(Qiang Xue)
6
我们的设计初衷是尽量降低各种部件之间的耦合度。我们不希望对应用部件的特殊属性进行特殊处理。因为这样做虽然能解决一些实际问题,但它可能带来更多的副作用。
- 缺省情况下,path也可以没有rule。
URL规则是一种整体规则,它应该只由app来决定。就像走路的左右规则一样,不能让大家自己定义。这样做当然会丧失一些灵活性,但它也保证了规则的通用性。
允许module来更改url配置也会碰到其它问题,例如怎么在module外创建module内的URL (如果module不是当前module)。
hreriam
(Likehere2008)
7
关键是把工具用好了,细节上的问题是小事,能做出什么东西来是大事。seo没那么重要的,关键是能为用户提供有效的服务。不要本末倒置。
rickywu
(Ricky Wu Y)
8
1,对于缺省没有rule的path形式,内部应该也能和get形式区别判断。当然,这比不判断要复杂。原先为get的形式,没有经过改写,无论如何都应该是有效的。现在urlFormat设为path,不能够正确解析,这也是直接套用配置中urlFormat带来的问题。
2,降低各种部件之间的耦合度,应该可以带来更灵活的定制性。现在,是牺牲一些灵活性。
如果,先初始化url manager,解析url,面对各种各样重写过的url,的确会有问题。有可能不知道是哪个module的。module各有各的url rules,可能冲突。解决的办法,可以把所有module的url rules在一个地方统一设置,这会增加url manager和各module的耦合度,但程度可以接受。也可以分别在各自内部设置,运行url manager时,读取所有这些配置。当然,设置时都应该避免冲突的可能性。这样也会产生另外一些不好的问题,处理上更复杂,性能上会更差。至于怎么在module外创建module内的URL,也可以在module外根据module专属的rules解决。再说,为什么要在module外创建它的url。创建时,应该都由它自身内部创建,解析才在外面进行。这些緾来绕去的,实现起来,可能不是太好看,降低可读性,也增加了出错的可能性。但对于没有经过重写的get形式的url,即使urlFormat设为path,也应该尽量予以支持。基于各种考量,可以先把各module定义各自内部url parse形式、规则这个问题放到一边。但是,是否可以把一开始加载各自除urlManager外的其它配置进行考虑。比如,clientScript组件,可能在某个module我希望用另外的形式,现在,在module preinit()、init()中提示只读,不能重写配置。我的理解,任何请求,都是面向特定module的,该module自身需求配置的权重就应该最大。这些都是使用过程中的一些感受看法,具体实现上,没有试验。有还没有想到的不妥,还望qiang哥不吝指出。
rickywu
(Ricky Wu Y)
9
面向SEO只是一个方面,也可以出于其它原因的考虑而有这种需要。
请教,奇怪的问题
比如这里面提到的。
rickywu
(Ricky Wu Y)
10
qiang哥,where are you now?
qiang
(Qiang Xue)
11
关于SEO的问题,我已经给出建议,让你修改htaccess来进行301重定向。
关于这个讨论,我们可以一直进行下去,但我觉得不大会有什么实质结果。
撇开各种利弊不谈,实际上,我们基本是不可能对目前的流程做你建议的修改的,因为这样会破坏兼容性。
而且,你的答复里也提到了新建议里的一些问题。我觉得,与其做修改而引入新的问题,还不如考虑怎么利用好现有的解决方案。你觉得呢?
rickywu
(Ricky Wu Y)
12
对于稳定性和兼容性的考虑,是有道理的。qiang哥说得对,同意。对于这个问题,只是源于一些使用过程中的困惑和想法。作为Yii的开发者,qiang哥考虑问题更深入全面,更谨慎。感谢qiang哥悉心参与讨论。也许,没有绝对完美的框架,但Yii是一个非常非常好的框架,用过的人都知道。而且,可以肯定的是,以后会更加的强大。感觉现在社区氛围不是十分红火,是接触了解Yii的人还不是很多,还是大家都很忙?希望有更多的人参与讨论一些话题,更好地促进Yii的发展。再次感谢qiang哥的解惑答疑,备感荣幸。