)
后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载Yii 2.0 是相对 1.1 完全重写的一代框架两者在命名空间、对象模型、事件机制、Active Record 与视图渲染等层面存在系统性差异。本文以官方《Upgrading from Version 1.1》俄文版 docs/guide-ru/intro-upgrade-from-v1.md为骨架结合 framework 源码实现逐项梳理 1.1 → 2.0 的主要差异、迁移时的代码改写要点与底层原理帮助你从 1.1 代码平滑过渡到 2.0并识别出那些在 2.0 中已经内建、无需再自行开发的功能。适用前提本仓库当前为 Yii 2.0 系列BaseYii::getVersion()返回2.0.56-dev见 framework/BaseYii.php。文中所有类名、路径与行为均以本仓库源码为准。如果你从未使用过 Yii 1.1可跳过本文直接阅读 开始使用。一、迁移总览为什么 1.1 → 2.0 不是一次普通的升级Yii 在 2.0 中进行了彻底重写complete rewrite因此从 1.1 升级到 2.0 远不止是版本号的变化而是一次系统性的代码迁移。官方文档给出了两个重要提醒本文只覆盖两个版本间的主要差异2.0 实际引入的新特性远多于本文列举的内容强烈建议完整通读整个权威指南因为很多过去需要你自行开发的功能如今已经是框架核心的一部分。迁移的大方向可以概括为类名去 C 前缀并引入命名空间、对象配置统一化、事件与行为机制重做、视图/模型/控制器职责更清晰、数据访问层Query Builder 与 Active Record重构。下面各节逐项展开。二、安装方式与 PHP 版本要求2.1 安装全面拥抱 ComposerYii 2.0 全面采用 ComposerPHP 的事实标准依赖管理器。无论是安装框架核心还是安装扩展都通过 Composer 完成。详细安装步骤见 安装 Yii如果你要创建新扩展或把已有的 1.1 扩展改造为 2.0 兼容扩展见 创建扩展。2.2 PHP 版本要求与语言级差异Yii 1.1 要求 PHP 5.2而 Yii 2.0 要求PHP 5.4 或更高本仓库的 composer.json 中require即体现了对现代 PHP 的依赖。这一提升带来了大量语言层面的变化迁移代码时需要注意命名空间Namespaces2.0 的代码全部基于命名空间组织匿名函数Anonymous functions事件处理器、回调等大量使用闭包短数组语法用[...元素...]替代array(...元素...)短 echo 标签?自 PHP 5.4 起可安全地在视图文件中直接使用SPL 类与接口ArrayAccess、IteratorAggregate等被框架大量实现例如yii\base\Model就实现了IteratorAggregate、ArrayAccess、Arrayable见 framework/base/Model.php后期静态绑定Late Static Bindings, LSB支撑了Widget::widget()、AssetBundle::register()这类静态工厂调用日期时间类DateTime框架与业务代码的时间处理基于 PHP 内置类Trait性状框架内部大量使用 trait 复用代码如Model中的ArrayableTrait、StaticInstanceTraitintl 扩展Yii 2.0 依赖 PHPintl扩展来支撑国际化功能详见后文 I18N 一节。三、命名空间与自动加载最直观的变化几乎每一个框架核心类都进入了命名空间例如yii\web\Request类名上的C 前缀被彻底移除CComponent→ComponentCController→ControllerCModel→Model等。类名与目录结构一一对应yii\web\Request对应的类文件就是框架目录下的web/Request.php本仓库实际路径 framework/web/Request.php。无需显式 include得益于 Yii 的类自动加载器你可以直接使用任意核心类而无需手动require。自动加载机制的核心实现在 framework/BaseYii.php 的autoload()先查classMap对于带命名空间的类则通过getAlias( . str_replace(\\, /, $className) . .php)解析到对应文件并include。例如只要yii别名指向框架目录框架默认注册yii __DIR__见 framework/BaseYii.phpyii\web\Request就能被自动解析为yii/web/Request.php并加载。四、Component 与 Object一对二的拆分1.1 中的CComponent在 2.0 中被拆分为两个类1.12.0职责CComponentyii\base\BaseObject轻量基类通过 getter/setter 提供**属性property**能力不携带事件/行为继承关系yii\base\Component继承BaseObject额外支持事件events与行为behaviors什么时候用BaseObject如果你的类不需要事件和行为特性典型如纯数据结构类建议直接继承BaseObject。Component的完整能力除属性外还支持事件与行为。从源码看Component内部维护_events事件名 → 处理器列表、_eventWildcards通配符事件和_behaviors已附加的行为见 framework/base/Component.php。事件名是大小写敏感的而BaseObject的属性名是大小写不敏感的见 framework/base/BaseObject.php 的文档注释。五、对象配置统一的对象初始化约定BaseObject引入了一套统一的对象配置方式。任何BaseObject的子类若需自定义构造函数都应遵循如下约定最后一个参数必须是配置数组且构造函数末尾调用parent::__construct($config)class MyClass extends \yii\base\BaseObject { public function __construct($param1, $param2, $config []) { // ... 配置应用之前的初始化 parent::__construct($config); } public function init() { parent::init(); // ... 配置应用之后的初始化 } }生命周期从 framework/base/BaseObject.php 的注释可以看出BaseObject的构造过程分三步依次进行① 构造函数被调用② 根据给定的配置数组初始化对象属性③ 调用init()方法。其构造器实现为Yii::configure($this, $config)之后调用$this-init()见 framework/base/BaseObject.php。因此需要依赖配置已应用这一前提的初始化逻辑应放在init()中而不是构造函数里。遵守此约定后就可以用配置数组统一地创建和配置对象$object Yii::createObject([ class MyClass, property1 abc, property2 cde, ], [$param1, $param2]);Yii::createObject()是new操作符的增强版支持按类名、配置数组或可调用对象创建实例并且能借助依赖注入容器自动装配依赖见 framework/BaseYii.php。更多配置细节见 配置。六、事件从 on 方法 到任意事件名 trigger在 Yii 1 中事件通过声明on方法实现例如onBeforeSave事件名被硬编码进方法名。Yii 2 中可以使用任意事件名并通过Component的方法显式触发与绑定// 触发事件 $event new \yii\base\Event; $component-trigger($eventName, $event); // 绑定事件处理器 $component-on($eventName, $handler); // 移除处理器 // $component-off($eventName, $handler);从源码看事件处理器支持四种类型匿名函数、对象方法[$object, handleAdd]、静态类方法[Page, handleAdd]、全局函数handleAdd处理器签名统一为function ($event)可通过$event-data访问附加数据见 framework/base/Component.php。此外 2.0 还支持在配置数组中用on add handler的语法直接附加事件、用as tree [...]的语法附加行为同上源码注释。事件的更多增强特性见 事件。七、路径别名 前缀与自动加载的关联Yii 2.0 将别名alias的使用范围扩大到文件/目录路径与 URL并且强制要求别名以开头以与普通路径和 URL 区分。例如别名yii指向 Yii 的安装目录。别名的底层实现BaseYii内置$aliases [yii __DIR__]setAlias()注册别名自动补前缀、去除末尾/、支持把别名指向另一个别名getAlias()按最长匹配优先、/为边界符的规则把别名翻译为真实路径未注册的根别名会抛出InvalidArgumentException见 framework/BaseYii.php。别名无处不在例如yii\caching\FileCache::cachePath既接受路径别名也接受普通目录路径。别名与类命名空间紧密相关官方建议为每个根命名空间定义一个路径别名这样无需额外配置即可使用 Yii 类自动加载器。因为yii指向框架目录yii\web\Request可被自动加载如果你使用 Zend Framework 等第三方库可定义Zend指向其安装目录之后 Yii 就能自动加载其中的任何类。更多内容见 路径别名。八、视图View$this 语义的根本变化1.1 → 2.0 最大的视图变化视图文件中的特殊变量$this不再指向当前控制器或小部件而是指向一个视图对象类型为yii\web\View代表 MVC 模式中的 View 部分。视图对象的context属性保存其上下文因此在视图中访问控制器或小部件应使用$this-context见 framework/base/View.php 中public $context的定义。渲染部分视图的方式变化原来用$this-renderPartial()2.0 中用$this-render()且render()返回渲染结果而非直接输出因此必须显式 echoecho $this-render(_item, [item $item]);模板引擎除了以 PHP 作为主要模板语言2.0 官方支持 Smarty 与 Twig 两个流行模板引擎不再支持 Prado 模板引擎。使用 Smarty/Twig 需要配置应用组件view的View::$renderers属性——该属性是一个按文件扩展名索引的渲染器数组例如tpl [class yii\smarty\ViewRenderer]、twig [class yii\twig\ViewRenderer]若视图文件没有匹配的渲染器则按普通 PHP 渲染见 framework/base/View.php。详见 模板引擎。九、模型Modelscenarios() 取代 on 方法时代Yii 2.0 以yii\base\Model作为模型基类对应 1.1 的CModel。CFormModel类已被完全移除——需要创建表单模型时直接继承yii\base\Model即可。新增scenarios()方法用于声明支持的场景并标明某属性在哪个场景下需要验证、是否安全等public function scenarios() { return [ backend [email, role], frontend [email, !role], ]; }上例声明了两个场景backend场景下email与role都是安全属性可以被批量赋值massive assignmentfrontend场景下email可批量赋值而role不可前缀!表示不安全。两个属性都需要用验证规则进行校验。rules()方法仍然用于声明验证规则。由于scenarios()的出现不再有unsafe验证器。从源码看scenarios()的默认实现会自动从rules()中推导出场景与活动属性默认场景SCENARIO_DEFAULT常量值为default见 framework/base/Model.php包含所有规则涉及的属性各命名场景则由规则中的on/except选项决定见 framework/base/Model.php。实践建议在大多数情况下如果rules()已经完整描述了所有存在的场景且不需要声明不安全属性就无需覆写scenarios()。rules()中规则的完整结构依据 framework/base/Model.php 的文档注释[ [[username, password], required], // 内置必填验证器 [username, string, min 3, max 12], // 内置 string 验证器 参数 [password, compare, compareAttribute password2, on register], // 仅 register 场景生效 [password, authenticate, on login], // 内联验证器模型方法 [dateRange, DateRangeValidator], // 自定义验证器类 ];关于Model的更多信息见 模型。十、控制器Controller返回结果而非直接输出Yii 2.0 以yii\web\Controller作为控制器基类对应 1.1 的CControlleryii\base\Action是所有动作类的基类。对代码最直接的影响控制器动作应返回要渲染的内容而不是直接 echo 输出public function actionView($id) { $model \app\models\Post::findOne($id); if ($model) { return $this-render(view, [model $model]); } else { throw new \yii\web\NotFoundHttpException; } }路由命名约定控制器与动作的驼峰命名会被转换为小写并用连字符分隔例如控制器类CamelCaseController的控制器 ID 是camel-case。详见 控制器 ID 与动作 ID。更多控制器细节见 控制器。十一、小部件Widget静态方法 begin / end / widgetYii 2.0 以yii\base\Widget作为小部件基类对应 1.1 的CWidget。为了获得更好的 IDE 支持2.0 引入了新的静态方法语法use yii\widgets\Menu; use yii\widgets\ActiveForm; // 注意必须 echo 结果才会显示 echo Menu::widget([items $items]); // 传入数组以初始化对象属性 $form ActiveForm::begin([ options [class form-horizontal], fieldConfig [inputOptions [class input-xlarge]], ]); ... 表单字段 ... ActiveForm::end();底层原理Widget::widget()的实现会开启输出缓冲ob_start()、创建小部件实例并返回其run()的输出begin()/end()通过内部栈self::$stack管理嵌套小部件的生命周期见 framework/base/Widget.php。这一设计让ActiveForm::begin() ... ActiveForm::end()这样的成对调用成为可能。更多信息见 小部件。十二、主题Theming基于路径映射的全新机制Yii 2.0 的主题机制完全重做基于源视图文件路径 → 主题化视图文件路径的映射。例如路径映射[/web/views /web/themes/basic]意味着视图文件/web/views/site/index.php的主题化版本位于/web/themes/basic/site/index.php。关键变化主题现在可以应用于任何视图文件即使该视图是在控制器或小部件上下文之外渲染的不再有CThemeManager组件取而代之theme成为应用组件view的一个可配置属性。从源码看View::$theme属性接受主题对象、配置数组或字符串见 framework/base/View.php且在View::init()中会把配置数组规范化未显式指定class时默认为yii\base\Theme见 framework/base/View.php。详见 主题化。十三、控制台应用Console控制器化的命令体系控制台应用现在像 Web 应用一样按控制器组织。控制台控制器应继承yii\console\Controller对应 1.1 的CConsoleCommand。运行方式使用yii 路由其中路由是控制器路由例如sitemap/index。额外的匿名参数会作为对应动作方法的参数传入而命名参数则按照yii\console\Controller::options()中的声明解析。帮助信息自动生成Yii 2.0 支持从注释块自动生成命令帮助信息。有关控制台命令的完整说明见 控制台命令。十四、I18Nintl 扩展与 i18n 应用组件Yii 2.0移除了内置的日期格式器和数字格式器转而使用 PECL intl PHP 扩展。消息翻译现在通过i18n应用组件完成。该组件管理一组消息源message sources允许你根据消息类别category为源消息使用不同的存储来源。详见 国际化。十五、动作过滤器Action Filters行为化实现动作过滤器现在通过行为behaviors实现。定义新过滤器时继承yii\base\ActionFilter使用过滤器时把它作为行为附加到控制器上。例如使用yii\filters\AccessControl过滤器public function behaviors() { return [ access [ class yii\filters\AccessControl, rules [ [allow true, actions [admin], roles []], ], ], ]; }上例中roles []表示仅允许已认证用户访问admin动作。过滤器基类位于 framework/base/ActionFilter.php内置过滤器如AccessControl、VerbFilter、Cors、RateLimiter等位于 framework/filters。更多信息见 过滤器。十六、资源Assets资源包Asset Bundle取代脚本包Yii 2.0 引入**资源包asset bundle**新概念取代了 1.1 的脚本包script package。资源包是某一目录下资源文件JavaScript、CSS、图片等的集合每个资源包用一个继承yii\web\AssetBundle的类表示通过AssetBundle::register()注册后包内资源即可通过 Web 访问与 1.1 的关键区别注册资源包的页面会自动包含包中声明的 JavaScript 与 CSS 文件引用。从源码看AssetBundle的核心属性包括sourcePath源目录、jsJS 文件列表、cssCSS 文件列表、jsOptions/cssOptions注册选项、publishOptions发布选项等见 framework/web/AssetBundle.phpregister()实际调用视图的registerAssetBundle()完成注册见 framework/web/AssetBundle.php。框架自带的基础资源包示例见 framework/assets如yii\assets\YiiAsset、yii\assets\ActiveFormAsset等。更多信息见 管理资源。十七、辅助类Helpers常用静态工具类Yii 2.0 内置了大量常用的静态辅助类主要包括yii\helpers\Htmlyii\helpers\ArrayHelperyii\helpers\StringHelperyii\helpers\FileHelperyii\helpers\Json这些类的实现位于 framework/helpers。更多信息见 辅助类总览。十八、表单FormsActiveField 字段概念Yii 2.0 引入**字段field**概念用于配合yii\widgets\ActiveForm构建表单。一个字段是包含标签、输入控件、错误消息和/或提示文本的容器用yii\widgets\ActiveField对象表示。使用字段可以更简洁地构建表单?php $form yii\widgets\ActiveForm::begin(); ? ? $form-field($model, username) ? ? $form-field($model, password)-passwordInput() ? div classform-group ? Html::submitButton(Login) ? /div ?php yii\widgets\ActiveForm::end(); ?ActiveField支持链式调用输入方法如-passwordInput()、-textInput()、-dropDownList()等并可配合hint()、error()、label()等细化渲染。相关实现位于 framework/widgets/ActiveField.php 与 framework/widgets/ActiveForm.php。更多信息见 创建表单。十九、查询构建器Query Builder统一为 Query 对象在 1.1 中查询构建分散在多个类中CDbCommand、CDbCriteria、CDbCommandBuilder。Yii 2.0 用yii\db\Query对象表示一次数据库查询并可在后台由yii\db\QueryBuilder转换为 SQL 语句$query new \yii\db\Query(); $query-select(id, name) -from(user) -limit(10); $command $query-createCommand(); $sql $command-sql; $rows $command-queryAll();Query提供select()、from()、where()、andWhere()、orderBy()、limit()/offset()、join()等链式方法createCommand()通过QueryBuilder生成 SQL 并返回yii\db\Command实例。核心实现见 framework/db/Query.php 与 framework/db/QueryBuilder.php。更优做法这些查询构建方法也可以配合 Active Record 使用。更多信息见 查询构建器。二十、Active Record查询、关联与性能的全面重构Yii 2.0 对 Active Record 做了大量修改最明显的是查询构建与关联处理两个方面。20.1 查询ActiveQuery 取代 CDbCriteria1.1 的CDbCriteria被yii\db\ActiveQuery取代。该类继承自yii\db\Query因此继承了全部查询构建方法。调用ActiveRecord::find()开始构建查询// 获取所有 *激活* 状态的客户并按 ID 排序 $customers Customer::find() -where([status $active]) -orderBy(id) -all();20.2 关联getter 即关联声明声明关联只需声明一个返回ActiveQuery对象的 getter 方法getter 定义的属性名就是关联名而在 1.1 中你需要在统一的relations()方法中集中声明所有关联class Customer extends \yii\db\ActiveRecord { public function getOrders() { return $this-hasMany(Order, [customer_id id]); } }现在可以直接用$customer-orders访问客户的订单也可以在需要时即时附加查询条件$orders $customer-getOrders()-andWhere(status1)-all();20.3 预加载Eager Loading策略变化Yii 2.0 的预加载方式与 1.1 不同1.1 用一条 JOIN 查询同时取回主记录与关联记录2.0 执行两条不带 JOIN 的 SQL——第一条取主表记录第二条按主表主键过滤取关联表记录。20.4 asArray()大数据量场景的性能优化当需要取出大量记录时与其返回ActiveRecord对象不如在查询中链式调用ActiveQuery::asArray()。这会让查询结果以数组形式返回在处理大量记录时可显著降低 CPU 耗时与内存占用$customers Customer::find()-asArray()-all();20.5 默认值从 public 属性移到 init()不能再用 public 属性定义属性默认值了。如有需要应在记录类的init()方法中设置public function init() { parent::init(); $this-status self::STATUS_NEW; }20.6 构造函数的自由度1.1 中覆写 ActiveRecord 构造函数存在一些问题2.0 中已不再有这些问题。注意若你给构造函数添加了参数可能需要同时覆写ActiveRecord::instantiate()。Active Record 还有大量其他改进详见 Active Record。二十一、Active Record 行为Behaviors直接继承 Behavior2.0 已移除基类CActiveRecordBehavior。要创建 Active Record 行为应直接继承yii\base\Behavior。如果行为需要响应所属对象的某些事件必须覆写events()方法namespace app\components; use yii\db\ActiveRecord; use yii\base\Behavior; class MyBehavior extends Behavior { // ... public function events() { return [ ActiveRecord::EVENT_BEFORE_VALIDATE beforeValidate, ]; } public function beforeValidate($event) { // ... } }注意EVENT_BEFORE_VALIDATE等事件常量定义于yii\base\Model见 framework/base/Model.phpActiveRecord继承自Model因而可用。更多行为知识见 行为。二十二、User 与 IdentityInterface认证体系的重构1.1 的CWebUser被yii\web\User取代CUserIdentity类不复存在。取而代之你需要实现yii\web\IdentityInterface接口使用起来更加直接明了。高级项目模板advanced project template中提供了参考实现。核心接口定义见 framework/web/IdentityInterface.phpUser组件实现见 framework/web/User.php。更多信息见 认证、授权 与高级项目模板相关文档。二十三、URL 管理可选参数与路由命名Yii 2.0 的 URL 管理与 1.1 类似主要增强是支持可选参数。例如下面的规则能同时匹配post/popular与post/1/popular——在 1.1 中要达到同样效果需要写两条规则[ pattern post/page:\d/tag, route post/index, defaults [page 1], ]这里page:\d是带正则约束的参数占位符defaults为可选参数提供默认值。详见 URL 解析与生成。路由命名约定的重要变化控制器和动作的驼峰命名现在会转换为小写、单词间以连字符分隔如CamelCaseController的控制器 ID 为camel-case。详见 控制器 ID 与 动作 ID 相关章节。二十四、同时使用 Yii 1.1 与 2.x如果你有希望与 Yii 2.0 共存的遗留 1.1 代码请参考 同时使用 Yii 1.1 和 2.0 一节该指南的英文版对应 tutorial-yii-integration.md。迁移速查1.1 → 2.0 关键对照表主题Yii 1.1Yii 2.0类名风格C前缀CComponent、CController命名空间 无前缀yii\base\Component、yii\web\Controller基类拆分CComponentyii\base\BaseObject属性/yii\base\Component属性事件行为对象配置无统一约定构造器末尾$config参数 init()配合Yii::createObject()事件on方法onBeforeSave任意事件名 trigger()/on()/off()视图$this指向控制器/小部件指向视图对象$this-context访问上下文部分视图渲染renderPartial()$this-render() 显式echo表单模型CFormModel直接继承yii\base\Model场景/安全性safe/unsafe验证器scenarios()!前缀标记不安全属性控制器输出直接 echoreturn渲染结果小部件实例化调用静态Widget::widget()/begin()/end()主题CThemeManagerview组件theme属性 路径映射控制台CConsoleCommandyii\console\Controlleryii 路由动作过滤器独立机制继承yii\base\ActionFilter 作为行为附加前端资源脚本包yii\web\AssetBundle资源包查询构建CDbCommand/CDbCriteria/CDbCommandBuilderyii\db\Queryyii\db\QueryBuilderAR 查询CDbCriteriayii\db\ActiveQuery继承QueryAR 关联relations()集中声明getter 方法返回ActiveQueryAR 预加载JOIN 单查询两条独立 SQL无 JOINAR 默认值public 属性init()中设置AR 行为CActiveRecordBehavior直接继承yii\base\Behaviorevents()用户认证CWebUser/CUserIdentityyii\web\User/ 实现yii\web\IdentityInterfaceURL 规则无可选参数支持可选参数defaults路由命名原样保留驼峰转连字符小写延伸阅读开始使用安装 Yii · Yii 简介核心概念配置 · 事件 · 行为 · 路径别名 · 属性结构模型 · 控制器 · 视图 · 小部件 · 资源 · 过滤器数据访问查询构建器 · Active Record进阶国际化 · 模板引擎 · 控制台命令 · 主题化 · 同时使用 Yii 1.1 和 2.0赞分享后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载相关推荐Yii 2.0 升级指南从 1.1 迁移到 Yii 2 的核心差异与实践要点Yii 2.0 升级指南从 1.1 迁移到 Yii 2 的核心差异与实践要点 本文以 docs/guide id/intro upgrade from v1.后端Web框架从 Yii 1.1 升级到 Yii 2.0核心差异全解析与迁移实战指南从 Yii 1.1 升级到 Yii 2.0核心差异全解析与迁移实战指南 Yii 2.0 对框架进行了完全重写从 1.1 升级并非简单的版本号跨越而是一次架后端Web框架Yii 2.0 从 1.1 升级完全指南Yii 2 框架核心差异、重构要点与迁移实战Yii 2.0 从 1.1 升级完全指南Yii 2 框架核心差异、重构要点与迁移实战 Yii 框架为 2.0 版本进行了彻底重写因此 1.1 与 2.0 之后端Web框架创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考