code: public static function getAttributeValue($model, $attribute)
      {
          if (!preg_match(static::$attributeRegex, $attribute, $matches)) {
              throw new InvalidArgumentException('Attribute name must contain word characters only.');
          }
          $attribute = $matches[2];
          $value = $model->$attribute;
          if ($matches[3] !== '') {
              foreach (explode('][', trim($matches[3], '[]')) as $id) {
                  if ((is_array($value) || $value instanceof \ArrayAccess) && isset($value[$id])) {
                      $value = $value[$id];
                  } else {
                      return null;
                  }
              }
          }
  
          // https://github.com/yiisoft/yii2/issues/1457
          if (is_array($value)) {
              foreach ($value as $i => $v) {
                  if ($v instanceof ActiveRecordInterface) {
                      $v = $v->getPrimaryKey(false);
                      $value[$i] = is_array($v) ? json_encode($v) : $v;
                  }
              }
          } elseif ($value instanceof ActiveRecordInterface) {
              $value = $value->getPrimaryKey(false);
  
              return is_array($value) ? json_encode($value) : $value;
          }
  
          return $value;
      }
docs: Returns the value of the specified attribute name or expression.
  
  For an attribute expression like `[0]dates[0]`, this method will return the value of `$model->dates[0]`.
  See [[getAttributeName()]] for more details about attribute expression.
  
  If an attribute value is an instance of [[ActiveRecordInterface]] or an array of such instances,
  the primary value(s) of the AR instance(s) will be returned instead.
  
  @param Model $model the model object
  @param string $attribute the attribute name or expression
  @return string|array the corresponding attribute value
  @throws InvalidArgumentException if the attribute name contains non-word characters.