1717use BackedEnum ;
1818use InvalidArgumentException ;
1919use JsonSerializable ;
20- use ReflectionClass ;
21- use ReflectionProperty ;
2220use Stringable ;
2321use think \contract \Arrayable ;
2422use think \contract \Jsonable ;
4644abstract class Entity implements JsonSerializable, ArrayAccess, Arrayable, Jsonable, Modelable
4745{
4846 private static ?WeakMap $ weakMap = null ;
49- private static array $ _schema = [];
5047
5148 /**
5249 * 架构函数.
@@ -91,8 +88,9 @@ public function __construct(array | object $data = [], ?Model $model = null)
9188 'relation_keys ' => $ options ['relation_keys ' ] ?? [],
9289 ];
9390
94- // 初始化模型及数据
91+ // 设置模型
9592 self ::$ weakMap [$ this ]['model ' ] = $ this ->initModel ($ model , $ options );
93+ // 初始化数据
9694 $ this ->initializeData ($ data );
9795 }
9896
@@ -173,34 +171,17 @@ protected function getSimpleModel()
173171 */
174172 protected function getFields (?string $ field = null )
175173 {
176- if (isset ( self :: $ _schema [ static ::class] )) {
177- $ schema = self ::$ _schema [ static ::class ];
174+ if ($ this -> isView () || $ this -> isVirtual ( )) {
175+ $ schema = self ::$ weakMap [ $ this ][ ' type ' ] ?: [ ];
178176 } else {
179- $ class = new ReflectionClass ($ this );
180- $ propertys = $ class ->getProperties (ReflectionProperty::IS_PROTECTED );
181- $ schema = [];
182-
183- foreach ($ propertys as $ property ) {
184- $ name = $ this ->getRealFieldName ($ property ->getName ());
185- $ type = $ property ->hasType () ? $ property ->getType ()->getName () : 'string ' ;
186-
187- $ schema [$ name ] = $ type ;
188- }
189-
190- if (empty ($ schema )) {
191- if ($ this ->isView () || $ this ->isVirtual ()) {
192- $ schema = self ::$ weakMap [$ this ]['type ' ] ?: [];
193- } else {
194- // 获取数据表信息
195- $ model = self ::$ weakMap [$ this ]['model ' ];
196- $ fields = $ model ->getFieldsType ();
197- $ schema = array_merge ($ fields , self ::$ weakMap [$ this ]['type ' ] ?: $ model ->getType ());
198- }
199- }
200-
201- self ::$ _schema [static ::class] = $ schema ;
177+ // 获取数据表信息
178+ $ model = self ::$ weakMap [$ this ]['model ' ];
179+ $ fields = $ model ->getFieldsType ();
180+ $ schema = array_merge ($ fields , self ::$ weakMap [$ this ]['type ' ] ?: $ model ->getType ());
202181 }
203182
183+ self ::$ weakMap [$ this ]['schema ' ] = $ schema ;
184+
204185 if ($ field ) {
205186 return $ schema [$ field ] ?? 'string ' ;
206187 }
@@ -253,8 +234,7 @@ protected function parseValidate(): string
253234 */
254235 public function model ()
255236 {
256- $ schema = self ::$ _schema [static ::class];
257- return self ::$ weakMap [$ this ]['model ' ]->schema ($ schema );
237+ return self ::$ weakMap [$ this ]['model ' ];
258238 }
259239
260240 /**
@@ -282,7 +262,7 @@ protected function initializeData(array | object $data, bool $fromSave = false)
282262
283263 if (!empty (self ::$ weakMap [$ this ]['mapping ' ])) {
284264 // 字段映射
285- $ name = array_search ($ name , self ::$ weakMap [$ this ]['mapping ' ])?: $ name ;
265+ $ name = array_search ($ name , self ::$ weakMap [$ this ]['mapping ' ]) ?: $ name ;
286266 }
287267
288268 if (str_contains ($ name , '__ ' )) {
@@ -303,7 +283,7 @@ protected function initializeData(array | object $data, bool $fromSave = false)
303283 // 读取数据后进行类型转换
304284 $ value = $ this ->readTransform ($ val , $ schema [$ trueName ] ?? 'string ' );
305285 // 数据赋值
306- $ this ->$ trueName = $ value ;
286+ $ this ->setValue ( $ trueName, $ value) ;
307287 // 记录原始数据
308288 $ origin [$ trueName ] = $ value ;
309289 }
@@ -1062,7 +1042,7 @@ public function getKey()
10621042 if (is_string ($ pk )) {
10631043 return $ this ->get ($ pk );
10641044 }
1065-
1045+
10661046 foreach ($ pk as $ name ) {
10671047 $ data [$ name ] = $ this ->get ($ name );
10681048 }
@@ -1076,7 +1056,7 @@ public function getKey()
10761056 */
10771057 public function getData (): array
10781058 {
1079- return array_merge ( get_object_vars ( $ this ), self ::$ weakMap [$ this ]['data ' ]) ;
1059+ return self ::$ weakMap [$ this ]['data ' ];
10801060 }
10811061
10821062 /**
@@ -1134,7 +1114,7 @@ public function toArray(array $allow = []): array
11341114
11351115 $ item = [];
11361116 foreach ($ data as $ name => $ val ) {
1137- if ($ val instanceof Entity || $ val instanceof Collection) {
1117+ if ($ val instanceof self || $ val instanceof Collection) {
11381118 if (!empty ($ relation [$ name ])) {
11391119 // 处理关联数据输出
11401120 foreach ($ relation [$ name ] as $ key => $ val ) {
@@ -1187,7 +1167,7 @@ public function isForce(): bool
11871167 }
11881168
11891169 /**
1190- * 设置数据对象的值
1170+ * 设置数据对象的值 并进行类型自动转换
11911171 *
11921172 * @param string $name 名称
11931173 * @param mixed $value 值
@@ -1200,14 +1180,31 @@ public function set(string $name, $value): void
12001180 $ name = array_search ($ name , self ::$ weakMap [$ this ]['mapping ' ]) ?: $ name ;
12011181 }
12021182
1203- $ name = $ this ->getRealFieldName ($ name );
1204- $ value = $ this ->readTransform ($ value , $ this ->getFields ($ name ));
1205- if (property_exists ($ this , $ name )) {
1206- $ this ->$ name = $ value ;
1183+ $ name = $ this ->getRealFieldName ($ name );
1184+ $ type = $ this ->getFields ($ name );
1185+
1186+ if (is_null ($ value ) && is_subclass_of ($ type , Entity::class)) {
1187+ // 关联数据为空 设置一个空模型
1188+ $ value = new $ type ();
12071189 } else {
1208- $ this ->setWeakData ('data ' , $ name , $ value );
1190+ // 类型自动转换
1191+ $ value = $ this ->readTransform ($ value , $ type );
12091192 }
12101193
1194+ $ this ->setValue ($ name , $ value );
1195+ }
1196+
1197+ /**
1198+ * 设置数据对象的实际值
1199+ *
1200+ * @param string $name 名称
1201+ * @param mixed $value 值
1202+ *
1203+ * @return void
1204+ */
1205+ public function setValue ($ name , $ value )
1206+ {
1207+ $ this ->setWeakData ('data ' , $ name , $ value );
12111208 if (isset (self ::$ weakMap [$ this ]['get ' ][$ name ])) {
12121209 self ::$ weakMap [$ this ]['get ' ][$ name ] = null ;
12131210 }
@@ -1268,6 +1265,22 @@ public function get(string $name, bool $attr = true)
12681265 return $ value ;
12691266 }
12701267
1268+ /**
1269+ * 获取数据对象的值
1270+ *
1271+ * @param string $name 名称
1272+ *
1273+ * @return mixed
1274+ */
1275+ private function getValue (string $ name )
1276+ {
1277+ if (!array_key_exists ($ name , self ::$ weakMap [$ this ]['data ' ])) {
1278+ // 动态获取关联数据
1279+ return $ this ->getRelationData ($ name ) ?: null ;
1280+ }
1281+ return self ::$ weakMap [$ this ]['data ' ][$ name ];
1282+ }
1283+
12711284 /**
12721285 * 处理数据对象的值(经过获取器和类型转换)
12731286 *
@@ -1290,9 +1303,6 @@ private function getWithAttr(string $name, $value, array $data = [])
12901303 $ value = $ this ->$ method ($ value , $ data );
12911304 } elseif ($ value instanceof Typeable || is_subclass_of ($ value , EnumTransform::class)) {
12921305 $ value = $ value ->value ();
1293- } elseif (is_null ($ value )) {
1294- // 动态获取关联数据
1295- $ value = $ this ->getRelationData ($ name ) ?: $ value ;
12961306 }
12971307 return $ value ;
12981308 }
@@ -1310,7 +1320,9 @@ protected function getRelationData(string $name)
13101320 if (method_exists ($ this ->model (), $ method )) {
13111321 $ modelRelation = $ this ->$ method ();
13121322 if ($ modelRelation instanceof Relation) {
1313- return $ modelRelation ->getRelation ();
1323+ $ value = $ modelRelation ->getRelation ();
1324+ $ this ->setValue ($ name , $ value );
1325+ return $ value ;
13141326 }
13151327 }
13161328 }
@@ -1343,21 +1355,6 @@ protected function trigger(string $event): bool
13431355 }
13441356 }
13451357
1346- /**
1347- * 获取数据对象的值
1348- *
1349- * @param string $name 名称
1350- *
1351- * @return mixed
1352- */
1353- private function getValue (string $ name )
1354- {
1355- if (property_exists ($ this , $ name )) {
1356- return $ this ->$ name ?? null ;
1357- }
1358- return self ::$ weakMap [$ this ]['data ' ][$ name ] ?? null ;
1359- }
1360-
13611358 /**
13621359 * 构建实体模型查询.
13631360 *
@@ -1459,9 +1456,6 @@ public function bindRelationAttr($entity, $bind = [])
14591456 public function __isset (string $ name ): bool
14601457 {
14611458 $ name = $ this ->getRealFieldName ($ name );
1462- if (property_exists ($ this , $ name )) {
1463- return isset ($ this ->$ name );
1464- }
14651459 return isset (self ::$ weakMap [$ this ]['data ' ][$ name ]);
14661460 }
14671461
@@ -1474,12 +1468,8 @@ public function __isset(string $name): bool
14741468 */
14751469 public function __unset (string $ name ): void
14761470 {
1477- $ name = $ this ->getRealFieldName ($ name );
1478- if (property_exists ($ this , $ name )) {
1479- unset($ this ->$ name );
1480- } else {
1481- self ::$ weakMap [$ this ]['data ' ][$ name ] = null ;
1482- }
1471+ $ name = $ this ->getRealFieldName ($ name );
1472+ self ::$ weakMap [$ this ]['data ' ][$ name ] = null ;
14831473 }
14841474
14851475 public function __toString ()
@@ -1492,7 +1482,7 @@ public function __debugInfo()
14921482 return [
14931483 'data ' => self ::$ weakMap [$ this ]['data ' ],
14941484 'origin ' => self ::$ weakMap [$ this ]['origin ' ],
1495- 'schema ' => self ::$ _schema [ static ::class ],
1485+ 'schema ' => self ::$ weakMap [ $ this ][ ' schema ' ],
14961486 ];
14971487 }
14981488
0 commit comments