继续阅读model.php
<?php /** * 将 $scenarios 从 * * ~~~ * [ * 'default' => [], * 'scenario1' => ['attribute11' => true, 'attribute12' => true, ...], * 'scenario2' => ['attribute21' => true, 'attribute22' => true, ...], * 'scenario3' => [], * ... * ] * ~~~ * 转化为 * ~~~ * [ * 'default' => [], * 'scenario1' => ['attribute11', 'attribute12', ...], * 'scenario2' => ['attribute21', 'attribute22', ...], * ... * ] * ~~~ */ foreach ($scenarios as $scenario => $attributes) { // 去除掉没有属性值的场景 if (empty($attributes) && $scenario !== self::SCENARIO_DEFAULT) { unset($scenarios[$scenario]); } else { // 取出场景中的属性名称 $scenarios[$scenario] = array_keys($attributes); } } return $scenarios; } /** * Returns the form name that this model class should use. * * 返回表单的名称,就是这个 model 的类名 * * The form name is mainly used by [[yiiwidgetsActiveForm]] to determine how to name * the input fields for the attributes in a model. If the form name is "A" and an attribute * name is "b", then the corresponding input name would be "A[b]". If the form name is * an empty string, then the input name would be "b". * 表单名称用于[[yiiwidgetsActiveForm]]确定模型中的属性名对应的输入域的名称 * 如果表单名为A,属性名为b,对应的输入名为A[b],如果表单名为空,则输入名为b * By default, this method returns the model class name (without the namespace part) * as the form name. You may override it when the model is used in different forms. * 默认情况下该方法返回不包含命名空间的类名称,可以通过重写使用别的表名 * @return string the form name of this model class. */ public function formName() { // ReflectionClass 类包含了一个类的有关信息 $reflector = new ReflectionClass($this); // 获取类的短名,就是不含命名空间(namespace)的那一部分 return $reflector->getShortName(); } /** * Returns the list of attribute names. * 返回属性名的列表,注意:只会返回 public 且不是 static 的属性 * 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 = []; // ReflectionClass::getProperties — 获取一组属性 // ReflectionProperty::IS_STATIC 指示了 static 的属性。 // ReflectionProperty::IS_PUBLIC 指示了 public 的属性。 // ReflectionProperty::IS_PROTECTED 指示了 protected 的属性。 // ReflectionProperty::IS_PRIVATE 指示了 private 的属性。 foreach ($class->getProperties(ReflectionProperty::IS_PUBLIC) as $property) { // 如果是public的属性,并且不是static的,就认为是它的attribute if (!$property->isStatic()) { // 获取该属性的名称 $names[] = $property->getName(); } } return $names; } /** * Returns the attribute labels. * 返回属性的标签 * * Attribute labels are mainly used for display purpose. For example, given an attribute * `firstName`, we can declare a label `First Name` which is more user-friendly and can * be displayed to end users. * 属性标签主要用于显示目的。例如,给定一个属性“firstName”,我们可以声明一个标签“名字”哪个更用户友好的,可以 显示给最终用户。 * By default an attribute label is generated using [[generateAttributeLabel()]]. * 在默认情况下生成一个属性标签使用[[generateAttributeLabel()]] * This method allows you to explicitly specify attribute labels. * 这种方法允许您显式地指定属性标签。 * Note, in order to inherit labels defined in the parent class, a child class needs to * merge the parent labels with child labels using functions such as `array_merge()`. * 请注意,为了继承父类中定义的标签,一个类需要子类合并父签使用等功能的array_merge()”。 * @return array attribute labels (name => label) * @see generateAttributeLabel() */ public function attributeLabels() { return []; } /** * Sets the attribute values in a massive way. * 设置属性值在一个大量运用的方式。 * @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. * A safe attribute is one that is associated with a validation rule in the current [[scenario]]. * @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); } } } }