关于 yii2 中 yii2\base\model 中那些事

前面讲过数据,通过load方式导入数据对象的原理。

下面主要分析下:

$this->fields();

追踪源码,在yii2/base/model:

    /* * @return array the list of field names or field definitions.
     * @see toArray()
     */
    public function fields()
    {
        $fields = $this->attributes();

        return array_combine($fields, $fields);
    }

继续:

    /**
     * Returns the list of attribute names.
     * By default, this method returns all public non-static properties of the class.
     * You may override this method to change the default behavior.
     * @return array list of attribute names.
     */
    public function attributes()
    {
        $class = new ReflectionClass($this);
        $names = [];
        foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
            if (!$property->isStatic()) {
                $names[] = $property->getName();
            }
        }

        return $names;
    }

其实这两步就是返回,model中所有的public属性数组(key和value一致)。

$fields = $this->fields();返回结果:
array(39) {
  ["_params"]=>
  string(7) "_params"
  ["debug"]=>
  string(5) "debug"
  ["accessToken"]=>
  string(11) "accessToken"
  ["adminId"]=>
  string(7) "adminId"
  ["period"]=>
  string(6) "period"
  ["dimen"]=>
  string(5) "dimen"
  ["unionGameId"]=>
  string(11) "unionGameId"
  ["unionGameName"]=>
  string(13) "unionGameName"
  ["gameId"]=>
  string(6) "gameId"
  ["gameName"]=>
  string(8) "gameName"
  ["folderId"]=>
  string(8) "folderId"
  ["folderName"]=>
  string(10) "folderName"
  ["groupId"]=>
  string(7) "groupId"
  ["groupType"]=>
  string(9) "groupType"
  ["groupName"]=>
  string(9) "groupName"
  ["sDay"]=>
  string(4) "sDay"
  ["eDay"]=>
  string(4) "eDay"
  ["sHour"]=>
  string(5) "sHour"
  ["eHour"]=>
  string(5) "eHour"
  ["sMonth"]=>
  string(6) "sMonth"
  ["eMonth"]=>
  string(6) "eMonth"
  ["sTime"]=>
  string(5) "sTime"
  ["eTime"]=>
  string(5) "eTime"
  ["aggr"]=>
  string(4) "aggr"
  ["channel"]=>
  string(7) "channel"
  ["threshold"]=>
  string(9) "threshold"
  ["isNatural"]=>
  string(9) "isNatural"
  ["userId"]=>
  string(6) "userId"
  ["company"]=>
  string(7) "company"
  ["supplier"]=>
  string(8) "supplier"
  ["advertising_admin_id"]=>
  string(20) "advertising_admin_id"
  ["serverId"]=>
  string(8) "serverId"
  ["costAndNoReg"]=>
  string(12) "costAndNoReg"
  ["fackFilter"]=>
  string(10) "fackFilter"
  ["advertiserId"]=>
  string(12) "advertiserId"
  ["gid"]=>
  string(3) "gid"
  ["fid"]=>
  string(3) "fid"
  ["types"]=>
  string(5) "types"
  ["reportConfig"]=>
  string(12) "reportConfig"
}

继续,看一下  $this->isAttributeActive() 方法:

    /**
     * Returns a value indicating whether the attribute is active in the current scenario.
     * @param string $attribute attribute name
     * @return bool whether the attribute is active in the current scenario
     * @see activeAttributes()
     */
    public function isAttributeActive($attribute)
    {
        return in_array($attribute, $this->activeAttributes(), true);
    }
   /**
     * Returns the attribute names that are subject to validation in the current scenario.
     * @return string[] safe attribute names
     */
    public function activeAttributes()
    {
        $scenario = $this->getScenario();
        $scenarios = $this->scenarios();
        if (!isset($scenarios[$scenario])) {
            return [];
        }
        $attributes = array_keys(array_flip($scenarios[$scenario]));
        foreach ($attributes as $i => $attribute) {
            if ($attribute[0] === '!') {
                $attributes[$i] = substr($attribute, 1);
            }
        }

        return $attributes;
    }

上面,两步,其实就是返回,定义的场景下,定义的类属性。如果$this->load()方法,对相关属性赋值,则有值,反之,则为null:

定义场景如下:

  /**
     * 场景
     * @return array
     */
    public function scenarios()
    {
        $basicFields = [
            'debug', 'sDay', 'eDay', 'aggr', 'dimen', 'period', 'unionGameId', 'gameId', 'folderId', 'groupId',
            'unionGameName', 'folderName', 'gameName', 'groupName', 'groupType', 'channel', 'company', 'supplier',
            'serverId','threshold','fackFilter'
        ];
    }

相关操作判断如下,过滤null数值后,返回结果如下:

    $where  = [];
        $fields = $this->fields();
        foreach($fields as $f) {
            if($this->isAttributeActive($f))  {
                if ($this->$f != '') {
                    $where[$f] = $this->$f;
                }
            }
        }
        var_dump($where);die;
array(4) {
  ["period"]=>
  string(1) "1"
  ["sDay"]=>
  string(10) "2020-05-23"
  ["eDay"]=>
  string(10) "2020-05-29"
  ["aggr"]=>
  string(1) "0"
}

通过上篇文章可以知道AR模式的 $this->attributes()方法,是跟数据库字段相关;

而通过yii/base/model中的 $this->attributes()方法,是跟Model类中自定义的公有public属性相关。

注意两者之间差异。

对应方法定义再看一下吧:

AR模式,yii2/db/ActiveRecord中:

  /**
     * Returns the list of all attribute names of the model.
     * The default implementation will return all column names of the table associated with this AR class.
     * @return array list of attribute names.
     */
    public function attributes()
    {
        return array_keys(static::getTableSchema()->columns);
    }

Model类中,yii2/base/Model中:

    /**
     * Returns the list of attribute names.
     * By default, this method returns all public non-static properties of the class.
     * You may override this method to change the default behavior.
     * @return array list of attribute names.
     */
    public function attributes()
    {
        $class = new ReflectionClass($this);
        $names = [];
        foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
            if (!$property->isStatic()) {
                $names[] = $property->getName();
            }
        }

        return $names;
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值