zoukankan      html  css  js  c++  java
  • 学习yii2.0框架阅读代码(八)

    vendor/yiisoft/yii2/base/Model.php(续

        /**
         * 设置属性值
         * @param array $values attribute values (name => value) to be assigned to the model.
         * @param boolean $safeOnly whether the assignments should only be done to the safe attributes.
         * 一个安全属性是与一个验证规则在当前的[[情况]]。
         * @see safeAttributes()
         * @see attributes()
         */
        public function setAttributes($values, $safeOnly = true)
        {
            // 必须是个数组
            if (is_array($values)) {
                // array_flip — 交换数组中的键和值
                // 将属性放到了 key 上
                // 默认取 safeAttributes 中的属性
                $attributes = array_flip($safeOnly ? $this->safeAttributes() : $this->attributes());
                foreach ($values as $name => $value) {
                    if (isset($attributes[$name])) {
                        // 如果存在该属性,就直接赋值
                        $this->$name = $value;
                    } elseif ($safeOnly) {
                        // 如果不存在,而且是 safeOnly 的话,就触发一下 onUnsafeAttribute 方法
                        $this->onUnsafeAttribute($name, $value);
                    }
                }
            }
        }
    
        /**
         * This method is invoked when an unsafe attribute is being massively assigned.
         * The default implementation will log a warning message if YII_DEBUG is on.
         * It does nothing otherwise.
         * @param string $name the unsafe attribute name
         * @param mixed $value the attribute value
         */
        public function onUnsafeAttribute($name, $value)
        {
            if (YII_DEBUG) {
                // 如果是调试状态,就打 log 记录下,没有成功设置的不安全的属性
                Yii::trace("Failed to set unsafe attribute '$name' in '" . get_class($this) . "'.", __METHOD__);
            }
        }
    
        /**
         * Returns the scenario that this model is used in.
         *
         * Scenario affects how validation is performed and which attributes can
         * be massively assigned.
         *
         * @return string the scenario that this model is in. Defaults to [[SCENARIO_DEFAULT]].
         */
        public function getScenario()
        {
            // 获取当前的场景
            return $this->_scenario;
        }
    
        /**
         * Sets the scenario for the model.
         * Note that this method does not check if the scenario exists or not.
         * The method [[validate()]] will perform this check.
         * @param string $value the scenario that this model is in.
         */
        public function setScenario($value)
        {
            // 设置当前的场景
            $this->_scenario = $value;
        }
    
        /**
         * Returns the attribute names that are safe to be massively assigned in the current scenario.
         * @return string[] safe attribute names
         */
        public function safeAttributes()
        {
            // 获取当前的场景
            $scenario = $this->getScenario();
            // 获取所有场景及其属性
            $scenarios = $this->scenarios();
            if (!isset($scenarios[$scenario])) {
                // 场景不存在,就返回空
                return [];
            }
            $attributes = [];
            foreach ($scenarios[$scenario] as $attribute) {
                // 将开头不是!的属性才会放入到 safeAttributes 中, 即以!开头的属性不会被放到 safeAttributes 中
                if ($attribute[0] !== '!') {
                    $attributes[] = $attribute;
                }
            }
    
            return $attributes;
        }
    
        /**
         * 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 = $scenarios[$scenario];
            foreach ($attributes as $i => $attribute) {
                // 如果属性名以!开头,就把!截取掉
                // !开头的属性来自rules,加!能够使规则(即 validator)生效,但却能够不出现在 safeAttributes 中
                if ($attribute[0] === '!') {
                    $attributes[$i] = substr($attribute, 1);
                }
            }
    
            return $attributes;
        }
    
        /**
         * Populates the model with the data from end user.
         * The data to be loaded is `$data[formName]`, where `formName` refers to the value of [[formName()]].
         * If [[formName()]] is empty, the whole `$data` array will be used to populate the model.
         * The data being populated is subject to the safety check by [[setAttributes()]].
         * 加载数据到所在的 model 中
         * @param array $data the data array. This is usually `$_POST` or `$_GET`, but can also be any valid array
         * supplied by end user.
         * @param string $formName the form name to be used for loading the data into the model.
         * If not set, [[formName()]] will be used.
         * @return boolean whether the model is successfully populated with some data.
         */
        public function load($data, $formName = null)
        {
            // 如果存在 yii 的 form,就使用该 form,否则就拿到所在类的名称(不含 namespace)
            $scope = $formName === null ? $this->formName() : $formName;
            if ($scope === '' && !empty($data)) {
                // 如果 $scope 为空字符串,且 $data不为空,就设置属性
                // 即 $formName 为空字符串,且 $data不为空
                $this->setAttributes($data);
    
                return true;
            } elseif (isset($data[$scope])) {
                // 否则,必须存在 $data[$scope],使用 $data[$scope] 去设置属性
                $this->setAttributes($data[$scope]);
    
                return true;
            } else {
                return false;
            }
        }
    
        /**
         * Populates a set of models with the data from end user.
         * 加载数据到所在的 model 的集合中
         * This method is mainly used to collect tabular data input.
         * The data to be loaded for each model is `$data[formName][index]`, where `formName`
         * refers to the value of [[formName()]], and `index` the index of the model in the `$models` array.
         * If [[formName()]] is empty, `$data[index]` will be used to populate each model.
         * The data being populated to each model is subject to the safety check by [[setAttributes()]].
         * @param array $models the models to be populated. Note that all models should have the same class.
         * @param array $data the data array. This is usually `$_POST` or `$_GET`, but can also be any valid array
         * supplied by end user.
         * @param string $formName the form name to be used for loading the data into the models.
         * If not set, it will use the [[formName()]] value of the first model in `$models`.
         * This parameter is available since version 2.0.1.
         * @return boolean whether at least one of the models is successfully populated.
         */
        public static function loadMultiple($models, $data, $formName = null)
        {
            if ($formName === null) {
                /* @var $first Model */
                // reset — 将数组的内部指针指向第一个单元
                $first = reset($models);
                if ($first === false) {
                    // 不存在就返回 false
                    return false;
                }
                // 拿到所在类的名称(不含 namespace)
                $formName = $first->formName();
            }
    
            $success = false;
            // 遍历 $models,一个个 load 数据
            foreach ($models as $i => $model) {
                /* @var $model Model */
                if ($formName == '') {
                    if (!empty($data[$i])) {
                        // 数据不为空,就 load 到相应的 model 中
                        $model->load($data[$i], '');
                        $success = true;
                    }
                } elseif (!empty($data[$formName][$i])) {
                    // 存在 $formName,且数据不为空,就 load 到相应的 model 中
                    $model->load($data[$formName][$i], '');
                    $success = true;
                }
            }
    
            return $success;
        }

  • 相关阅读:
    不要随便用#define 沉沉_
    转载堆和栈的区别 沉沉_
    转载include包含源文件引发的错误 沉沉_
    浅议C和C++中的内存分配 沉沉_
    volatile 的应用 沉沉_
    Debian显示txt乱码
    Debian 64位安装wink
    Debian安装vmware虚拟机
    Debian安装scim中文、日语输入法
    Debian安装chrome
  • 原文地址:https://www.cnblogs.com/xwzj/p/5403021.html
Copyright © 2011-2022 走看看