protected function applyRule($fields, array $rule, array $onlyChecked)
    {
        $fields    = \is_string($fields) ? Filters::explode($fields) : (array)$fields;
        $validator = \array_shift($rule);

        // How to determine the property is empty(default use the Validators::isEmpty)
        $isEmpty = [Validators::class, 'isEmpty'];
        if (!empty($rule['isEmpty']) && (\is_string($rule['isEmpty']) || $rule['isEmpty'] instanceof \Closure)) {
            $isEmpty = $rule['isEmpty'];
        }

        // Preconditions for verification -- If do not meet the conditions, skip this rule
        $when = $rule['when'] ?? null;
        if ($when && ($when instanceof \Closure) && $when($this->data, $this) !== true) {
            return;
        }

        // Whether to skip when empty(When not required). ref yii2
        $skipOnEmpty = $rule['skipOnEmpty'] ?? $this->_skipOnEmpty;
        $filters     = $rule['filter'] ?? null;  // filter
        $defMsg      = $rule['msg'] ?? null; // Custom error message
        $defValue    = $rule['default'] ?? null;// Allow default

        // clear all keywords options. 0 is the validator
        unset($rule['msg'], $rule['default'], $rule['skipOnEmpty'], $rule['isEmpty'], $rule['when'], $rule['filter']);

        // The rest are validator parameters. Some validators require parameters. e.g. size()
        $args = $rule;

        foreach ($fields as $field) {
            if (!$field || ($onlyChecked && !\in_array($field, $onlyChecked, true))) {
                continue;
            }

            $value = $this->getByPath($field, $defValue);

            if (\is_string($validator)) {
                if ($validator === 'safe') {
                    $this->setSafe($field, $value);
                    continue;
                }

                // required*系列字段检查 || 文件资源检查
                if (self::isCheckRequired($validator) || self::isCheckFile($validator)) {
                    $result = $this->fieldValidate($field, $value, $validator, $args, $defMsg);

                    if (false === $result && $this->isStopOnError()) {
                        break;
                    }
                    continue;
                }
            }

            // skip On Empty && The value is empty
            if ($skipOnEmpty && Helper::call($isEmpty, $value)) {
                continue;
            }

            // Field value filtering(有通配符`*`的字段, 不应用过滤器)
            if ($filters && !\strpos($field, '.*')) {
                $value = $this->valueFiltering($value, $filters);
                // save
                $this->data[$field] = $value;
            }

            // Field value verification check
            if (!$this->valueValidate($field, $value, $validator, $args, $defMsg) && $this->isStopOnError()) {
                break;
            }
        }
    }