YII model学习笔记

块赋值

只用一行代码将用户所有输入填充到一个模型,非常方便, 它直接将输入数据对应填充到 yii\base\Model::attributes() 属性。 以下两段代码效果是相同的, 都是将终端用户输入的表单数据赋值到 ContactForm 模型的属性, 明显地前一段块赋值的代码比后一段代码简洁且不易出错。

$model = new \app\models\ContactForm;
$model->attributes = \Yii::$app->request->post('ContactForm');

public function rules()
{
    return [
        // 在"register" 场景下 username, email 和 password 必须有值
        [['username', 'email', 'password'], 'required', 'on' => 'register'],

        // 在 "login" 场景下 username 和 password 必须有值
        [['username', 'password'], 'required', 'on' => 'login'],
    ];
}

一个属性只会属于scenarios()中定义的活动属性且在rules() 申明对应一条或多条活动规则的情况下被验证。

要给 model 填充其所需的用户输入数据,你可以调用 yii\base\Model::validate() 方法验证它们。该方法会返回一个布尔值,指明是否通过验证。若没有通过,你能通过 yii\base\Model::$errors 属性获取相应的报错信息。比如,

$model = new \app\models\ContactForm();


输入验证
// 根据用户的输入填充到模型的属性中
$model->load(\Yii::$app->request->post());
// 等效于下面这样:
// $model->attributes = \Yii::$app->request->post('ContactForm');

if ($model->validate()) {
    // 所有输入通过验证
} else {
    // 验证失败: $errors 是一个包含错误信息的数组
    $errors = $model->errors;
}

安全属性

块赋值只应用在模型当前scenario 场景yii\base\Model::scenarios()方法 列出的称之为 安全属性 的属性上,例如,如果User模型申明以下场景, 当当前场景为login时候,只有username and password 可被块赋值, 其他属性不会被赋值。

public function scenarios()
{
    return [
        'login' => ['username', 'password'],
        'register' => ['username', 'email', 'password'],
    ];
}

由于默认yii\base\Model::scenarios()的实现会返回 yii\base\Model::rules()所有属性和数据, 如果不覆盖这个方法,表示所有只要出现在活动验证规则中的属性都是安全的。

为此,提供一个特别的别名为 safe 的验证器来申明 哪些属性是安全的不需要被验证, 如下示例的规则申明 title 和 description 都为安全属性。

public function rules()
{
    return [
        [['title', 'description'], 'safe'],
    ];
}

非安全属性

如上所述,yii\base\Model::scenarios() 方法提供两个用处:定义哪些属性应被验证,定义哪些属性安全。 在某些情况下,你可能想验证一个属性但不想让他是安全的, 可在scenarios()方法中属性名加一个惊叹号 !。 例如像如下的secret属性。

public function scenarios()
{
    return [
        'login' => ['username', 'password', '!secret'],
    ];
}

当模型在 login 场景下,三个属性都会被验证, 但只有 username和 password 属性会被块赋值, 要对secret属性赋值,必须像如下例子明确对它赋值。

$model->secret = $secret;

//The same can be done in rules() method:

public function rules()
{
    return [
        [['username', 'password', '!secret'], 'required', 'on' => 'login']
    ];
}

在这种情况下,属性 username, password 和 secret 是必须的,但是 secret必须被明确指定。

数据导出

最佳实践

模型是代表业务数据、规则和逻辑的中心地方,通常在很多地方重用, 在一个设计良好的应用中,模型通常比 控制器代码多。

归纳起来,模型

可包含属性来展示业务数据;
可包含验证规则确保数据有效和完整;
可包含方法实现业务逻辑;
不应直接访问请求,session和其他环境数据, 这些数据应该由控制器传入到模型;
应避免嵌入HTML或其他展示代码,这些代码最好在 视图中处理;
单个模型中避免太多的 场景.

在开发大型复杂系统时应经常考虑最后一条建议, 在这些系统中,模型会很大并在很多地方使用,因此会包含需要规则集和业务逻辑, 最后维护这些模型代码成为一个噩梦, 因为一个简单修改会影响好多地方, 为确保模型好维护,最好使用以下策略:

定义可被多个 应用主体 或 模块 共享的模型基类集合。 这些模型类应包含通用的最小规则集合和逻辑。
在每个使用模型的 应用主体 或 模块中, 通过继承对应的模型基类来定义具体的模型类, 具体模型类包含应用主体或模块指定的规则和逻辑。

例如,在高级应用模板, 你可以定义一个模型基类common\models\Post, 然后在前台应用中,定义并使用一个继承common\models\Post的具体模型类frontend\models\Post, 在后台应用中可以类似地定义backend\models\Post。 通过这种策略,你清楚frontend\models\Post只对应前台应用,如果你修改它, 就无需担忧修改会影响后台应用。

查询数据(Querying Data)

定义 Active Record 类后,你可以从相应的数据库表中查询数据。 查询过程大致如下三个步骤:

通过 yii\db\ActiveRecord::find() 方法创建一个新的查询生成器对象;
使用查询生成器的构建方法来构建你的查询;
调用查询生成器的查询方法来取出数据到 Active Record 实例中。

正如你看到的,是不是跟查询生成器的步骤差不多。 唯一有区别的地方在于你用 yii\db\ActiveRecord::find() 去获得一个新的查询生成器对象,这个对象是 yii\db\ActiveQuery, 而不是使用 new 操作符创建一个查询生成器对象。

下面是一些例子,介绍如何使用 Active Query 查询数据:

// 返回 ID 为 123 的客户:
// SELECT * FROM `customer` WHERE `id` = 123
$customer = Customer::find()
    ->where(['id' => 123])
    ->one();
// 取回所有活跃客户并以他们的 ID 排序:
// SELECT * FROM `customer` WHERE `status` = 1 ORDER BY `id`
$customers = Customer::find()
    ->where(['status' => Customer::STATUS_ACTIVE])
    ->orderBy('id')
    ->all();
// 取回活跃客户的数量:
// SELECT COUNT(*) FROM `customer` WHERE `status` = 1
$count = Customer::find()
    ->where(['status' => Customer::STATUS_ACTIVE])
    ->count();

// 以客户 ID 索引结果集:
// SELECT * FROM `customer`
$customers = Customer::find()
    ->indexBy('id')
    ->all();

上述代码中,$customer 是个 Customer 对象,而 $customers 是个以 Customer 对象为元素的数组。 它们两都是以 customer 表中取回的数据结果集填充的。

当你调用 save() 时,默认情况下会自动调用 validate()。 只有当验证通过时,它才会真正地保存数据; 否则将简单地返回 false, 您可以检查 errors 属性来获取验证过程的错误消息。

$list = MemberRole::find()
            ->select('magnus_ldap_user.id,magnus_ldap_user.truename')
            ->leftJoin('magnus_ldap_user','magnus_ldap_user.id = magnus_member_role.uid')
            ->where(['magnus_member_role.is_del'=>1,'magnus_member_role.plat_id'=>$m_role['plat_id']])
            ->asArray()
            ->all();//同平台下用户列表
MemberRole::find()->where(['id'=>$id])->asArray()->one();

注:self为改类,asArray()是将所查数据数组化

2.ActiveRecord类常用的方法

all()/one() -----返回一条还是所有

orderBy()/andOrderBy() ----- 对数据进行排序

count() -----返回查询条件下的数据条数

with() -----指定关联表的字段

where()/andWhere()/orWhere() ---- 条件查询
column
joinWith
indexBy
asArray
use yii\helpers\ArrayHelper;
ArrayHelper::toArray($data)  使用自带的方法

fields 定义数据关系。 返回的是一个数组。key=>v v可能是匿名函数
在 toArray的时候解析kv 和匿名函数。

asArray 返回的结果直接返回。 否者 转成AR对象。

Query对象 返回数组
ARQuery对象返回数组或者AR对象。继承自Query 。重写了populate 方法。
所以可以把数组转成AR对象。

Query查询构造器。

AR继承BAR 继承model
更新插入的方法定义的model里。在哪里能实现。查看下。

AR定义了 save inster update等操作方法。

ARQuery和Query是没有增删改操作的。

$this::find() 返回一个ARQuery对象。没有save方法。

asArray 返回$this 和where等一样。在one all 前调用。

rest 返回值

['data'=>Yii::createObject($this->serializer)->serialize($model->getList($params)),'status'=>0,'message'=>'默认提示信息'];

查看下

验证规则

rules 返回的也是数组。规则。验证时候用。插入 更新是自动调用验证。可以设置为 false 跳过验证。

场景

scenarios

批量插入

Yii::$app->db->createCommand()->batchInsert('user', ['name', 'age'], [
['Tom', 30],
['Jane', 20],
['Linda', 25],
])->execute();

循环多次插入

$model = new User();
foreach($data as $attributes)
{
      $model->isNewRecord = true;
      $model->setAttributes($attributes);
      $model->save() && $model->id=0;
}

$query = Car::find()->from(Car::tableName() . ' t'); 
//设置别名
 //基础过滤
$query->andFilterWhere(['=', 'status', 3]);#在售
$query->andFilterWhere(['>', 'stime', $first_time]);#在售
$query->andFilterWhere(['=', 'expo_pos', 0]);#在售
#车型
$query->andFilterWhere([
    't.pbid' => $this->pbid,
    't.pserid' => $this->pserid,
]);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值