Yii 2.0相比于Yii 1.1和Laravel有什么特点

「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战」。

今天收到一个需求,需要调研一下YII2框架,和Laravel做对比,从而确定技术选型。

我之前使用过YII框架,但是是1.1版本。目前的YII2是2.0版本,是重写的,可以说和1.1版本有天翻地覆的变化。

下面我介绍一下今天调研的结果:

YII2 简介

Yii 当前有两个主要版本:1.1 和 2.0。 1.1 版是上代的老版本,现在处于维护状态。 2.0 版是一个完全重写的版本,采用了最新的技术和协议,包括依赖包管理器 Composer、PHP 代码规范 PSR、命名空间、Traits(特质)等等。

YII2 系统要求

Yii 2.0 需要 PHP 5.4.0 或以上版本支持。

使用 Yii 需要对面向对象编程(OOP)有基本了解,因为 Yii 是一个纯面向对象的框架。Yii 2.0 还使用了 PHP 的最新特性, 例如命名空间 和Trait(特质)

YII2 特点

相比于YII的1.1版本

  1. 对关系型和 NoSQL 数据库都提供了查询生成器和 ActiveRecord
  2. 全面拥抱Composer,包管理工具

关键点

对象的配置

Object 类引入了一种统一对象配置的方法。 所有 Object 的子类都应该用以下方法声明它的构造方法(如果需要的话), 以正确配置它自身:

class MyClass extends \yii\base\BaseObject
{
    public function __construct($param1, $param2, $config = [])
    {
        // ... 配置生效前的初始化过程

        parent::__construct($config);
    }

    public function init()
    {
        parent::init();

        // ... 配置生效后的初始化过程
    }
}
复制代码

在上面的例子里,构造方法的最后一个参数必须传入一个配置数组, 包含一系列用于在方法结尾初始化相关属性的键值对。 你可以重写 init() 方法来执行一些需要在配置生效后进行的初始化工作。

你可以通过遵循以下约定俗成的编码习惯, 来使用配置数组创建并配置新的对象:

$object = Yii::createObject([
    'class' => 'MyClass',
    'property1' => 'abc',
    'property2' => 'cde',
], [$param1, $param2]);
复制代码

看到上面这个用法我实在太高兴了,因为我有个项目中也是这么设计的。 构造方法的最后一个参数设置为数组,支持传入扩展字段。 没想到自己的项目经验和YII2的框架设计者一致。

有兴趣的同学可以查看我这篇文档,了解一下上面提到的最后一个参数必须传入一个配置数组是多么有意思的设计。

性能优化反思:减少DB查询,合理使用成员变量;扩展字段的灵活使用

查询生成器 query builder

YII的查询生成器 query builder使用起来要比laravel的eloquent复杂的多,适用于一些没有建立model层,直接查询sql的场景。

$query = new \yii\db\Query(); 
$query->select('id, name') ->from('user') ->limit(10); 
$command = $query->createCommand();
$sql = $command->sql;
$rows = $command->queryAll();
复制代码

活动记录 active record

而yii的活动记录(active record)和laravel的eloquent基本一致。

使用都很简单,都支持关联查找,都支持指定返回类型:laravel支持返回集合或者数组;yii支持返回对象或者数组(yii使用asArray()返回数组能降低对CPU和内存的占用)。

yii 1.1 中的 CDbCriteria 类在 Yii 2 中被 yii\db\ActiveQuery 所替代。 这个类是继承自 yii\db\Query,因此也继承了所有查询生成方法。开始拼装一个查询可以调用 yii\db\ActiveRecord::find() 方法进行:

// 检索所有“活动的”客户和订单,并以 ID 排序:
$customers = Customer::find()
    ->where(['status' => $active])
    ->orderBy('id')
    ->all();
复制代码

要声明一个关联关系,只需简单地定义一个 getter 方法来返回一个 ActiveQuery 对象。 getter 方法定义的属性名代表关联表名称。 如,以下代码声明了一个名为 orders 的关系(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('status=1')->all();
复制代码

当贪婪加载一段关联关系时,Yii 2.0 和 1.1 的运作机理并不相同。 具体来说,在 1.1 中使用一条 JOIN 语句同时查询主表和关联表记录。 在 Yii 2.0 中会使用两个没有 JOIN 的 SQL 语句:第一条语句取回主表记录, 第二条通过主表记录经主键筛选后查询关联表记录。

当生成返回大量记录的查询时,可以链式书写 asArray() 方法, 这样会以数组的形式返回查询结果,而不必返回 ActiveRecord 对象,这能显著降低因大量记录读取所消耗的 CPU 时间和内存。如:

$customers = Customer::find()->asArray()->all();
复制代码

总结

整体看下来,YII2 确实比YII 1.1版本有了翻天覆地的变化,在使用上和目前主流的Laravel区别不大,尤其是对数据的操作:Active RecordEloquent简直太像了。

最后

感谢阅读,欢迎大家三连:点赞、收藏、投币(关注)!!!

8e95dac1fd0b2b1ff51c08757667c47a.gif

Guess you like

Origin juejin.im/post/7067893640084848670