在过去几年中,框架迅速发展,几乎在Web应用开发中,每个人都会涉及到一个新生框架,Web开发框架会帮助你加快你的应用程序发布,你只需迅速的把你的想法在框架的白板上书写功能代码。随着Web应用的实现具有共同特征,现有的框架方案已经满足这些要求,在今天还有什么理由要从头开始你的下一个Web应用呢?今天的Web开发,除程序自身语言外,一个现代化、灵活的和可扩展的框架,几乎是一个至关重要的编程工具,此外,如果语言与框架两个部份有特别的互补性,结果是将一个非常强大的工具包:Java和Spring, Ruby和Rails, C#和.NET, PHP和Yii。
Yii是创始人薛强的心血结晶,于2008年1月1日开始开发。在此这前,薛强开发和维护PRADO框架多年。这些年的经验和从PRADO项目得到的用户的反馈了解到,用户需要一个更容易、可扩展、更快速的基于PHP5的框架,以满足应用程序开发人员不断增长的需求。Yii正式发布于2008年10月,最初是alpha版本,其与其他基于PHP的框架表现相比令人印象深刻,立即引起非常积极的关注。在2008年12月3日Yii1.0正式发布, 并于2010年3月14日,发布最新版本1.1.2。它有一个不断增长的开发团队,并继续在每天PHP开发人员中得到收益。我们认为,在这本书中包含信息会对你有些帮助,你很快就会明白为什么。
Yii的名称(是一个缩写,发音为 Yee 或 [ji:])代表容易(easy),高效(effcient)和可扩展(extensible)。Yii是用PHP5写的一个高性能,基于组件的Web 开发应用框架。Yii可以更容易的创建和维护大规模的网络应用程序。这也将使应用程序更有效和可扩展。让我们快速了解一下这些特性。
要运行基于Yii的Web应用,你需要它的核心框架和一台支持PHP5.1.0以上的Web服务器,如果使用Yii开发,你需要精通PHP与面向对象编程 (OOP)。你不需要学习什么新的配置和模板语言,建立Yii应用,主要包括编写和维护自己定义的PHP类,其中一些将是继承Yii核心框架组件类。
Yii集成了许多来自其他著名的Web程序框架和应用程序中的伟大的想法,这些你可能会很熟悉并易于操作。
Yii还包含了一个易用的配置约定。这意味着,Yii已经为几乎所有的应用程序编写了合理的默认值,如果你按照约定的规范,你会写更少的代码,花更少的时间来开发应用程序。如果需要Yii允许你在这些约定基础之上进行定制,本章后面及整书,我们将覆盖到这些默认的约定。
Yii是为开发任何规模的Web应用提供的一个高性能的基于组件的Web框架,它鼓励在Web程序中最大化的代码重用,并可加快开发速度。如前所述,如果你坚持使用Yii的内置约定,你可以让您的应用在运行中,几乎不需要任何配置手册。
Yii的另一个目的是帮助你使用DRY开发,DRY(Don't Repeat Yourself)是一种灵活的应用开发。所有Yii应用是使用模型-视图-控制器(MVC)架构,Yii强制这种开发模式,通过提供一个放置你的MVC 代码的位置,这最大限度地减少重复,并有助于代码重用性和可维护性。你编写越少的代码,则需要的时间就越少,应用程序将赢得市场。同样,越容易维护你的应用程序,留在市场的时间就越长。
当然,Yii不仅开发快,他的运行速度也是非常快的,性能是经过优化的。Yii从一开始就已经做到了开发与性能优化,其结果是,他是一个最快的PHP开发框架。Yii的开发团队已经与其他PHP框架进行了对比与测试,Yii运行速度在他们之上。这意味着在Yii上编写应用程序增加额外的开销是微不足道的。
Yii是经过精心设计的,让几乎所有的代码都可扩展和可定制,以满足不同任务需要。事实上,在开发Yii的应用时,很难用不到Yii扩展性,这是一个很主要的行为,可扩展是框架的核心。如果你要将你的代码为作可重用的工具,提供给其他开发者使用,Yii提供了简单制作步骤和遵循准则,以帮助您建立这样的第三方扩展。并允许你将他贡献到Yii扩展列表中。
Yii最引人注目的是什么。易用性、性能优越、可扩展。Yii的功能包会帮助你满足今天在Web应用程序上的那些更高要求。AJAX可用挂件,Web Service包,基于MVC结构的验证,DAO和Active Record数据库层,复杂的缓存,分级的角色访问控制,主题化,国际化(I18N),和本地化(L10N),这仅仅是Yii的冰山一角。现在从1.1版本,核心框架中有一个官方扩展类库叫Zii。这些扩展是由框架的核心团队成员开发与维护。 社区用户也可以编写并贡献扩展,Yii的扩展每天都在增长,有关所有可用的用户贡献的扩展,详见http://www.yiiframework.com/extensions/
如前所述,Yii是一个MVC框架,它提供了一个明确的目录结构,模型,视图,控制器的代码分别放到自己的目录,在我们建立第一个Yii应用之前,我们需要定义一些关键语,并查看Yii的MVC架构是如果实现和执行的。
通常在一个MVC架构中,模型是负责维护状态,因此,它应该封装业务规则,定义数据的状态。在Yii中,一个模型可以是 CModel的一个实例或它的子类。通常一个模型类包括数据的属性,可能还会有不同的标签(有些是为了显示给用户时更友好),并且可以设置一些规则进行验证。模型中的数据可能来自数据库的表或一个表单用户输入域。
Yii实现了两种模型:表单模型(CFormModel类)和Active Record模型(CActiveRecord类)。他们都继承自同一个基类CModel。CFormModel代表的数据模型是从HTML表单中收集的输入,它封装了所有逻辑,如表单的验证和其他业务逻辑,这些是要应用到表单的域上。它能将这些数据存储在内存中,或者在一个Active Record的模型帮助下,存入数据库。
Active Record (AR)是一种设计模式,用面向对象的方式抽象的访问数据。在Yii中,每一个AR对象的实例可以是CActiveRecord类或它的子类,它包装了数据库表或视图中的一行记录,并封装了所有逻辑和访问数据库的细节,如果有大部份的业务逻辑,则必须使用这种模型。数据库表中一行每列字段的值对应AR对象的一个属性。关于AR的更多介绍,后面将详细说明。
通常情况下,视图是在数据模型的基础上渲染用户界面,Yii中一个视图就是一个PHP文件,它包含有关用户界面相关的元素,经常使用HTML,但也可以使用PHP语句。通常在视图中的PHP语句应该是非常简单的条件或循环语句,或者使用Yii的UI组件,比如HTML助手的方法或预先建立好的挂件。更复杂的逻辑应该与视图分离放到适当的模型中(如数据直接处理),或控制器中。
控制器主要是处理一个路由的请求,也负责获得用户的输入,与模型的交互,并指定视图的显示与更新。Yii中一个控制器实例可能是CController类或它的子类。当一个控制器运行时,它会执行一个请求的操作,然后与需要的模型交互,最后渲染到一个视图上。一个操作,最简单的形式就是一个控制器类方法,方法的名字要以action开头。
大多数的MVC实现中,Web请求生命周期通常如下步骤:
Yii 的MVC实现也不例外,在一个Yii应用程序中,从浏览器发送处理的请求,首先会传给一个路由。路由分析请求,并确定下一步的处理。在大多数情况下路由会识别控制器中的特定操作方法。这个操作方法将关注传入的请求数据与模型交互和执行其他需要的业务逻辑,最终,这个操作方法将处理的响应数据发送给他对应的视图类。视图将确认符合预期布局设计的数据,并返回到浏览器显示。
为了更好的理解,让我们看一个虚构的例子。假如我们用Yii建立了自己的一个博客网站,域名是yourblog.com。这个网站与典型的博客网站类似。在首页显示最近发布的文章列表。点击每篇文章的标题,可以显示完整的文章。下面的图片,可以说明Yii是怎样点击标题,发送请求的。
这个图片是跟踪到用户的点击连接:
http://yourblog.com/post/show/id/99
首先,请求发送给路由。路由解析请求URL结构中的关键词决定发送到哪。默认情况下,Yii的URL结构如以下格式:
http://hostname/index.php?r=ControllerID/ActionID
URL中的变量r指的是路由,Yii分析路由这条路由,以确定适当的控制器和操作方法做进一步处理请求。现在,你可能已经注意到,前面提到的URL地址并不遵循这个默认格式。其实这是一个非常简单的事情,通过配置来使用更友好的格式:
http://hostname/ControllerID/ActionID
这个例子我们将继续使用这行简化的格式。该URL中ControllerID指的是控制器的名称。默认情况下第一部份加上单词Controller就是控制器类的名称,例如:如果你的控制器类名是TestController则ControllerID应该是Test。同样ActionID指的是控制器中定义的操作名称。如果要在控制器中定义操作,那么要将单词Action加上操作名称,例如:如果您的操作方法名为actionCreate(),那么 ActionID则是Create。
如果ActionID省略,控制器将采用默认的操作方法,这个方法是actionIndex()。如果ControllerID也省略了,应用程序将使用默认控制器。Yii默认的控制器是SiteController
回到这个例子,路由将分析下面的URL,http://yourblog.com/post/show/id/99,并会取URL路径的第一部份作为 ControllerID,第二部份作为ActionID。这将转化为路由请求到PostController类中的 actionShow()方法。URL最后部份(id/99)是一个键/值的查询参数,将在处理过程中,提供给操作方法。在这个例子中,表示所选的博客文章ID为99。
actionShow()方法处理具体的博客文章请求。在这种情况下,它使用查询字符串变量id,来确定具体的要求,他将要求模型来查询id=99的博客文章。
AR模型类请求数据库返回数据给控制器,控制器进一步准备数据给视图,视图则渲染到一个需要的HTML中,并将响应返回给用户的浏览器。
MVC架构允许我们将模型,控制器与视图分离,这使得开发人员可以很容易改变应用程序,而不影响用户界面(UI),UI设计师也可以自由作出不影响模型的业务逻辑变化。这种分离也可以很容易提供多个相同的模型。例如,你可以在yourblog.com的HTML页面或一个Flash/Flex RIA演示或移动应用程序或Web Service使用相同的模型代码,使用MVC约定的分离功能,将使应用程序更容易扩展和维护。
Yii已经帮你做了很多,并不是简单的分离代码,包括一些命令的约定和建议代码应该放置在同一类目录中。它已经帮助你写好了需要将这些部份关联在一起的代码。这使你可以享受严格的MVC设计带来的好处,而不必花费时间编写自己所需细节代码。让我们看看它都写了些什么。
在多数情况下,我们建立的Web应用程序内部会与数据库关联。如前面的博客发布程序,该程序中博客的文章内容存在数据库的表中。然而,Web应用程序需要的数据,与数据库映射到内存中类定义的属性是对应的。对象关系映射(ORM)库提供的,就是映射数据库表为一个对象的类。
ORM的大部份代码是如何实现数据库表中的字段与对象之间的关系,这是非常繁琐和重复的工作。幸运的是,Yii帮助你们完成了这些繁琐而又乏味的工作,它提供给我们一个ORM层,这就是AR模式。
正如前面提到的,AR是一种设计模型,用面向对象的方式抽象的访问数据。它将表映射到类。行映射到对象,列则映射到对象的数据。换句话说,每一个 Active Reocrd类的实例代表了数据库表中的一行。然而,一个AR类不仅仅是数据库表中字段与类中属性的映射关系,他还需要在这些数据上处理一些业务逻辑。最终这个类定义了所有关于怎样对数据库的读写操作。
依靠约定和合理的默认值,Yii的AR对象将减少开发的时间,不必花费时间在繁琐和重复创建、读取、更新和删除数据的SQL语句上。它也允许开发人员使用面向对象的方式访问更多的数据库数据。为了说明这一点,在博客系统中的示例代码是用AR操作对应的数据库表中的id,id是表的主键,id等于99。首先它会检查主键,然后修改标题并将修改结果保存到数据库:
$post=Post::model()->findByPk(99); $post->title='Some new title'; $post->save();
Active Record完成了我们以前需要编的任何SQL或其他要处理数据库的事情。
Active Reocrd不只做了这些。它还无缝的集成了许多Yii框架的其他方面。有许多表单输入域的HTML助手捆绑在AR类的属性上。这样,Active Record提取表单输入值时直接进入模型。并且它支持自动化数据验证,如果验证失败,Yii视图类会显示验证错误给最终用户。我们将在本书提供的许多具体例子再次介绍AR。
视图和控制器是非常紧密的兄弟。控制器会生成需要显示的可用数据给视图,视图生成页面,并触发事件,发送数据给控制器。
在Yii中,一个视图文件是由所属的控制器类确定是否渲染它。这样,在视图脚本里,我们可以通过简单的方法$this引用到控制器实例。这样的实现,使视图和控制器更加紧密。幸运的是,Yii已经完成了所有的细节,因此,我们可以将精力集中具体应用程序的编码上。
Yii的控制器不仅仅是调用模型和渲染视图。控制器能管理请求前或请求后的操作要求,实现基本的访问控制规则来限制某些操作,管理应用程序范围内的布局和嵌套布局,管理数据的分页和许多幕后的服务。同样,我们要感谢Yii不需要让我们插手这些零乱工作的细节。
Yii还有很多内容,要探索它的奥秘,最好的方法是使用它。现在我们已了解一些基础概念和术语,这里是我们的第一个里程碑。在下一章,我们将通过简单的了解Yii的安装过程和建立一个可运行的应用程序,以更好地说明。
在这一章中,我们介绍了一个高级的Web应用框架Yii。我们还了解了Yii的设计理念。初步讨论这些抽象的内容,你是否失去了一点点信心呢?不要担心,这些例子都是有意义的,但,还是要回顾一下这章具体包括的内容: