namespaceIlluminate\Database\Eloquent\Concerns;useCarbon\CarbonImmutable;useCarbon\CarbonInterface;useDateTimeInterface;useIlluminate\Contracts\Database\Eloquent\Castable;useIlluminate\Contracts\Database\Eloquent\CastsInboundAttributes;useIlluminate\Contracts\Support\Arrayable;useIlluminate\Database\Eloquent\Casts\AsArrayObject;useIlluminate\Database\Eloquent\Casts\AsCollection;useIlluminate\Database\Eloquent\Casts\Attribute;useIlluminate\Database\Eloquent\InvalidCastException;useIlluminate\Database\Eloquent\JsonEncodingException;useIlluminate\Database\Eloquent\Relations\Relation;useIlluminate\Database\LazyLoadingViolationException;useIlluminate\Support\Arr;useIlluminate\Support\Carbon;useIlluminate\Support\Collectionas BaseCollection;useIlluminate\Support\Facades\Crypt;useIlluminate\Support\Facades\Date;useIlluminate\Support\Str;useInvalidArgumentException;useLogicException;useReflectionClass;useReflectionMethod;useReflectionNamedType;traitHasAttributes{publicfunctiongetAttribute($key){if(!$key){return;}// If the attribute exists in the attribute array or has a "get" mutator we will// get the attribute's value. Otherwise, we will proceed as if the developers// are asking for a relationship's value. This covers both types of values.if(array_key_exists($key,$this->attributes)||array_key_exists($key,$this->casts)||$this->hasGetMutator($key)||$this->hasAttributeMutator($key)||$this->isClassCastable($key)){return$this->getAttributeValue($key);}// Here we will determine if the model base class itself contains this given key// since we don't want to treat any of those methods as relationships because// they are all intended as helper methods and none of these are relations.if(method_exists(self::class,$key)){return;}return$this->getRelationValue($key);}publicfunctiongetAttributeValue($key){return$this->transformModelValue($key,$this->getAttributeFromArray($key));}protectedfunctiontransformModelValue($key,$value){// If the attribute has a get mutator, we will call that then return what// it returns as the value, which is useful for transforming values on// retrieval from the model to a form that is more useful for usage.if($this->hasGetMutator($key)){return$this->mutateAttribute($key,$value);}elseif($this->hasAttributeGetMutator($key)){return$this->mutateAttributeMarkedAttribute($key,$value);}// If the attribute exists within the cast array, we will convert it to// an appropriate native PHP type dependent upon the associated value// given with the key in the pair. Dayle made this comment line up.if($this->hasCast($key)){return$this->castAttribute($key,$value);}// If the attribute is listed as a date, we will convert it to a DateTime// instance on retrieval, which makes it quite convenient to work with// date fields without having to create a mutator for each property.# 主要看這里if($value!==null&&\in_array($key,$this->getDates(),false)){return$this->asDateTime($value);}return$value;}publicfunctiongetDates(){if(!$this->usesTimestamps()){return$this->dates;}$defaults=[$this->getCreatedAtColumn(),$this->getUpdatedAtColumn(),];returnarray_unique(array_merge($this->dates,$defaults));}publicfunctiongetDates(){if(!$this->usesTimestamps()){return$this->dates;}$defaults=[$this->getCreatedAtColumn(),$this->getUpdatedAtColumn(),];returnarray_unique(array_merge($this->dates,$defaults));}protectedfunctionasDateTime($value){// If this value is already a Carbon instance, we shall just return it as is.// This prevents us having to re-instantiate a Carbon instance when we know// it already is one, which wouldn't be fulfilled by the DateTime check.if($valueinstanceofCarbonInterface){returnDate::instance($value);}// If the value is already a DateTime instance, we will just skip the rest of// these checks since they will be a waste of time, and hinder performance// when checking the field. We will just return the DateTime right away.if($valueinstanceofDateTimeInterface){returnDate::parse($value->format('Y-m-d H:i:s.u'),$value->getTimezone());}// If this value is an integer, we will assume it is a UNIX timestamp's value// and format a Carbon object from this timestamp. This allows flexibility// when defining your date fields as they might be UNIX timestamps here.if(is_numeric($value)){returnDate::createFromTimestamp($value);}// If the value is in simply year, month, day format, we will instantiate the// Carbon instances from that format. Again, this provides for simple date// fields on the database, while still supporting Carbonized conversion.if($this->isStandardDateFormat($value)){returnDate::instance(Carbon::createFromFormat('Y-m-d',$value)->startOfDay());}$format=$this->getDateFormat();// Finally, we will just assume this date is in the format used by default on// the database connection and use that format to create the Carbon object// that is returned back out to the developers after we convert it here.try{$date=Date::createFromFormat($format,$value);}catch(InvalidArgumentException$e){$date=false;}return$date?:Date::parse($value);}}