<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>潘锦的空间 &#187; MVC</title>
	<atom:link href="https://www.phppan.com/tag/mvc/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.phppan.com</link>
	<description>SaaS SaaS架构 团队管理 技术管理 技术架构 PHP 内核 扩展 项目管理</description>
	<lastBuildDate>Sat, 04 Apr 2026 01:19:58 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.9.40</generator>
	<item>
		<title>Yii 框架的视图层实现</title>
		<link>https://www.phppan.com/2013/02/yiiframework-view/</link>
		<comments>https://www.phppan.com/2013/02/yiiframework-view/#comments</comments>
		<pubDate>Sun, 17 Feb 2013 14:37:29 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[Yii框架]]></category>
		<category><![CDATA[企业应用架构]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=1793</guid>
		<description><![CDATA[如果你想看看 Yii 框架的视图实现过程，请继续向下；如果你想看看胖子的碎碎念，请直接拉到文章最后；如果你只是 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>如果你想看看 Yii 框架的视图实现过程，请继续向下；如果你想看看胖子的碎碎念，请直接拉到文章最后；如果你只是路过，那也路过留名吧^_^。</p>
<p>Martin Flower 在《企业应用架构模式》中提到 MVC  模式的关键点在于两个分离：从模型中分离视图和从视图中分离控制器。视图的表现在很大程度上决定了此模式的使用，以及框架对 MVC 模式的各个层级的分离水平。 Yii  框架是一个基于 MVC 模式的框架，它在视图这块做了很多的工作，很清晰的实现了视图的功能。</p>
<p>Yii 框架的视图是一个包含了主要的用户交互元素的 PHP 脚本。每个视图有一个名字，当渲染( render  )时，名字会被用于识别视图脚本文件。视图的名称与其视图脚本名称是一样的。例如:视图 edit 的名称出自一个名为 edit.php  的脚本文件。要渲染时，需通过传递视图的名称调用 CController::render()。这个方法将在 “protected/views/控制器 ID”  目录下寻找对应的视图文件，其寻找方法为 getViewFile。这里的 protected/views 只是默认的存储位置，我们可以通过  Yii::app()-&gt;setViewPath 方法改变此路径。</p>
<p>在视图脚本内部,我们可以通过 $this  来访问控制器实例。同时，我们也可以在视图里以“$this-&gt;属性名”的方式获取控制器的任何属性，这种调用方式是通过实现__get魔法方法实现的。</p>
<p>一次较为完整的视图渲染过程在 CController 类的 render 函数中体现得淋漓尽致。当控制器中从模型（model）中拿到数据后，一般会执行  render() 方法创建视图，其大概过程如下：</p>
<ol>
<li>执行预留的 beforeRender 钩子。</li>
<li>查找渲染局部内容 $output，实际上这里是一个部分视图渲染的过程，它包括获取视图文件路径，渲染视图文件，处理输出三个部分。在渲染的过程中，通过  PHP 中的 extract() 方法把数组中将变量导入到当前的符号表，直接 require 视图文件，从而合并数据和表现。</li>
<li>如果存在布局，则将得到的内容放入以 content 为下标的的数组传递给父类的 renderFile() 方法中，重复执行渲染视图的过程。在布局中执行  <strong><!--?php echo $content; ?--></strong>，输出局部内容$output，实现了局部和布局视图的合并。为了实现多级布局，在布局中还可以通过控制器的视图装饰方法加载。</li>
<li>执行预留的 afterRender 钩子。</li>
</ol>
<p>在渲染视图的时候，如果参数中有传递对应的值，会执行 processOutput() 方法，此方法一般在渲染视图结束时才会调用，它实现了三个过程：</p>
<ol>
<li>注册客户端脚本，具体由 ClientScript 组件管理。</li>
<li>如果存在，则执行动态内容输出。</li>
<li>页面内容 base64_encode 加密，如果存在 zlib 扩展，则会先压缩。</li>
</ol>
<p>在 CController 类中对视图的渲染除了上面的render方法外，还有其它多种方法：</p>
<ul>
<li>render方法： 和布局一起渲染 render($view,$data=null,$return=false)</li>
<li>renderPartial方法： 仅渲染视图内容，或者是渲染部分页面内容。它与 render() 方法的不同是它不会渲染布局，并且在 render()  方法中也会调用此方法。 renderPartial($view,$data=null,$return=false,$processOutput=false)</li>
<li>renderText方法：渲染静态内容和布局。renderText($text,$return=false)</li>
<li>renderDynamic方法：通过回调函数渲染动态内容，通常我们会在模板文件中中调用此方法。renderDynamic($callback)-&gt;renderDynamicInternal($callback,$params)</li>
<li>renderClip方法：渲染显示 CClipWidget  生成的内容，此处需要指定名字。renderClip($name,$params=array(),$return=false)</li>
</ul>
<p>对于不同的页面中共用的内容，虽然可以通过 renderPartial  方法渲染部分页面视图，但是必然存在对于数据部分的重复，因为这些视图都需要调用控制提供的数据，从而产生耦合。因此 Yii 框架  提供了另一个独立的视图部件，官方称之为 Widget （小物件？小挂件？）。</p>
<p>小物件是 CWidget  或其子类的实例。它是一个主要用于表现数据的组件。小物件通常内嵌于一个视图来产生一些复杂而独立的用户界面。也算是一种界面的独立和松耦合的设计。如我们做WEB应用时常用的列表，翻页，日历等。这些  Widget 增加了界面的复用度，减少了代码量。</p>
<p>与前面视图部分不同的是，它没有布局文件支持，并且 Widget 视图中的 $this 指向 Widget  实例而不是控制器实例，这里实现了与控制器的分离。如果要实现一个自定义的 Widget ，我们仅需要继承 CWidget 并覆盖其 init() 和 run()  方法,可以定义一个新的 Widget 。</p>
<p>我们在视图中通过 $this-&gt;widget（） 或 $this-&gt;beginWidget() 和 $this-&gt;endWidget()  调用 Widget，两者的区别在于第二个方法可以在显示的过程中添加 html 内容。添加内容的位置在 init() 方法和 run()  方法输出的内容之间。</p>
<p>除了布局、Widget 外， Yii 框架实现系统级的视图，用来显示 Yii 的错误和日志信息。</p>
<p>系统视图的命名遵从了一些规则。比如像“errorXXX”这样的名称就是用于渲染展示错误号 XXX 的 CHttpException 的视图。在  framework/views 下, Yii 提供了一系列默认的系统视图. 我们可以通过在 protected/views/system  下创建同名视图文件进行自定义。系统默认的 exception 视图非常赞，结合 Yii 本身的 traces  机制，当抛出异常或出错时就会很详细的定位出问题的代码所在。</p>
<p>以上只是胖子阅读 Yii  框架源码的笔记。结合《企业应用架构模式》这本书的内容，如页面控制器、前端控制器、活动记录等，胖子发现对框架的实现有更深入的理解。一方面印证了书上的理论，一方面为实现过程的原理找到了出处。不晓得  Yii 框架的作者是否对此书也有精读，或者是经验的积累？</p>
<p>参考资料： http://www.yiiframework.com/doc/guide/1.1/en/basics.view</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2013/02/yiiframework-view/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
