Model.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. namespace think;
  12. use think\db\Query;
  13. /**
  14. * Class Model
  15. * @package think
  16. * @mixin Query
  17. */
  18. abstract class Model implements \JsonSerializable, \ArrayAccess
  19. {
  20. use model\concern\Attribute;
  21. use model\concern\RelationShip;
  22. use model\concern\ModelEvent;
  23. use model\concern\TimeStamp;
  24. use model\concern\Conversion;
  25. /**
  26. * 是否更新数据
  27. * @var bool
  28. */
  29. private $isUpdate = false;
  30. /**
  31. * 是否强制更新所有数据
  32. * @var bool
  33. */
  34. private $force = false;
  35. /**
  36. * 更新条件
  37. * @var array
  38. */
  39. private $updateWhere;
  40. /**
  41. * 数据库配置信息
  42. * @var array|string
  43. */
  44. protected $connection = [];
  45. /**
  46. * 数据库查询对象类名
  47. * @var string
  48. */
  49. protected $query;
  50. /**
  51. * 模型名称
  52. * @var string
  53. */
  54. protected $name;
  55. /**
  56. * 数据表名称
  57. * @var string
  58. */
  59. protected $table;
  60. /**
  61. * 写入自动完成定义
  62. * @var array
  63. */
  64. protected $auto = [];
  65. /**
  66. * 新增自动完成定义
  67. * @var array
  68. */
  69. protected $insert = [];
  70. /**
  71. * 更新自动完成定义
  72. * @var array
  73. */
  74. protected $update = [];
  75. /**
  76. * 初始化过的模型.
  77. * @var array
  78. */
  79. protected static $initialized = [];
  80. /**
  81. * 查询对象实例
  82. * @var Query
  83. */
  84. protected $queryInstance;
  85. /**
  86. * 错误信息
  87. * @var mixed
  88. */
  89. protected $error;
  90. /**
  91. * 架构函数
  92. * @access public
  93. * @param array|object $data 数据
  94. */
  95. public function __construct($data = [])
  96. {
  97. if (is_object($data)) {
  98. $this->data = get_object_vars($data);
  99. } else {
  100. $this->data = $data;
  101. }
  102. if ($this->disuse) {
  103. // 废弃字段
  104. foreach ((array) $this->disuse as $key) {
  105. if (array_key_exists($key, $this->data)) {
  106. unset($this->data[$key]);
  107. }
  108. }
  109. }
  110. // 记录原始数据
  111. $this->origin = $this->data;
  112. $config = Container::get('config');
  113. if (empty($this->name)) {
  114. // 当前模型名
  115. $name = str_replace('\\', '/', static::class);
  116. $this->name = basename($name);
  117. if ($config->get('class_suffix')) {
  118. $suffix = basename(dirname($name));
  119. $this->name = substr($this->name, 0, -strlen($suffix));
  120. }
  121. }
  122. if (is_null($this->autoWriteTimestamp)) {
  123. // 自动写入时间戳
  124. $this->autoWriteTimestamp = $config->get('database.auto_timestamp');
  125. }
  126. if (is_null($this->dateFormat)) {
  127. // 设置时间戳格式
  128. $this->dateFormat = $config->get('database.datetime_format');
  129. }
  130. if (is_null($this->resultSetType)) {
  131. $this->resultSetType = $config->get('database.resultset_type');
  132. }
  133. if (is_null($this->query)) {
  134. // 设置查询对象
  135. $this->query = $config->get('database.query');
  136. }
  137. if (!empty($this->connection) && is_array($this->connection)) {
  138. // 设置模型的数据库连接
  139. $this->connection = array_merge($config->pull('database'), $this->connection);
  140. }
  141. // 执行初始化操作
  142. $this->initialize();
  143. }
  144. /**
  145. * 获取当前模型名称
  146. * @access public
  147. * @return string
  148. */
  149. public function getName()
  150. {
  151. return $this->name;
  152. }
  153. /**
  154. * 创建新的模型实例
  155. * @access public
  156. * @param array|object $data 数据
  157. * @param bool $isUpdate 是否为更新
  158. * @param mixed $where 更新条件
  159. * @return Model
  160. */
  161. public function newInstance($data = [], $isUpdate = false, $where = null)
  162. {
  163. return (new static($data))->isUpdate($isUpdate, $where);
  164. }
  165. /**
  166. * 创建模型的查询对象
  167. * @access protected
  168. * @return Query
  169. */
  170. protected function buildQuery()
  171. {
  172. // 设置当前模型 确保查询返回模型对象
  173. $class = $this->query;
  174. $query = (new $class())->connect($this->connection)->model($this)->json($this->json);
  175. // 设置当前数据表和模型名
  176. if (!empty($this->table)) {
  177. $query->table($this->table);
  178. } else {
  179. $query->name($this->name);
  180. }
  181. if (!empty($this->pk)) {
  182. $query->pk($this->pk);
  183. }
  184. return $query;
  185. }
  186. /**
  187. * 获取当前模型的数据库查询对象
  188. * @access public
  189. * @param Query $query 查询对象实例
  190. * @return $this
  191. */
  192. public function setQuery($query)
  193. {
  194. $this->queryInstance = $query;
  195. return $this;
  196. }
  197. /**
  198. * 获取当前模型的数据库查询对象
  199. * @access public
  200. * @param bool $useBaseQuery 是否调用全局查询范围
  201. * @return Query
  202. */
  203. public function db($useBaseQuery = true)
  204. {
  205. if ($this->queryInstance) {
  206. return $this->queryInstance;
  207. }
  208. $query = $this->buildQuery();
  209. if ($useBaseQuery) {
  210. // 软删除
  211. if (method_exists($this, 'getDeleteTimeField')) {
  212. $field = $this->getDeleteTimeField(true);
  213. if ($field) {
  214. $query->useSoftDelete($field);
  215. }
  216. }
  217. // 全局作用域
  218. if (method_exists($this, 'base')) {
  219. call_user_func_array([$this, 'base'], [ & $query]);
  220. }
  221. }
  222. // 返回当前模型的数据库查询对象
  223. return $query;
  224. }
  225. /**
  226. * 初始化模型
  227. * @access protected
  228. * @return void
  229. */
  230. protected function initialize()
  231. {
  232. if (!isset(static::$initialized[static::class])) {
  233. static::$initialized[static::class] = true;
  234. static::init();
  235. }
  236. }
  237. /**
  238. * 初始化处理
  239. * @access protected
  240. * @return void
  241. */
  242. protected static function init()
  243. {}
  244. /**
  245. * 数据自动完成
  246. * @access protected
  247. * @param array $auto 要自动更新的字段列表
  248. * @return void
  249. */
  250. protected function autoCompleteData($auto = [])
  251. {
  252. foreach ($auto as $field => $value) {
  253. if (is_integer($field)) {
  254. $field = $value;
  255. $value = null;
  256. }
  257. if (!isset($this->data[$field])) {
  258. $default = null;
  259. } else {
  260. $default = $this->data[$field];
  261. }
  262. $this->setAttr($field, !is_null($value) ? $value : $default);
  263. }
  264. }
  265. /**
  266. * 更新是否强制写入数据 而不做比较
  267. * @access public
  268. * @param bool $force
  269. * @return $this
  270. */
  271. public function force($force = true)
  272. {
  273. $this->force = $force;
  274. return $this;
  275. }
  276. /**
  277. * 保存当前数据对象
  278. * @access public
  279. * @param array $data 数据
  280. * @param array $where 更新条件
  281. * @param string $sequence 自增序列名
  282. * @return integer|false
  283. */
  284. public function save($data = [], $where = [], $sequence = null)
  285. {
  286. if (is_string($data)) {
  287. $sequence = $data;
  288. $data = [];
  289. }
  290. if (!$this->checkBeforeSave($data, $where)) {
  291. return false;
  292. }
  293. $result = $this->isUpdate ? $this->updateData($where) : $this->insertData($sequence);
  294. if (false === $result) {
  295. return false;
  296. }
  297. // 写入回调
  298. $this->trigger('after_write');
  299. // 重新记录原始数据
  300. $this->origin = $this->data;
  301. return $result;
  302. }
  303. /**
  304. * 写入之前检查数据
  305. * @access protected
  306. * @param array $data 数据
  307. * @param array $where 保存条件
  308. * @return bool
  309. */
  310. protected function checkBeforeSave($data, $where)
  311. {
  312. if (!empty($data)) {
  313. // 数据对象赋值
  314. foreach ($data as $key => $value) {
  315. $this->setAttr($key, $value, $data);
  316. }
  317. if (!empty($where)) {
  318. $this->isUpdate = true;
  319. $this->updateWhere = $where;
  320. }
  321. }
  322. // 数据自动完成
  323. $this->autoCompleteData($this->auto);
  324. // 事件回调
  325. if (false === $this->trigger('before_write')) {
  326. return false;
  327. }
  328. return true;
  329. }
  330. /**
  331. * 检查数据是否允许写入
  332. * @access protected
  333. * @param array $autoFields 自动完成的字段列表
  334. * @return array
  335. */
  336. protected function checkAllowFields(array $append = [])
  337. {
  338. // 检测字段
  339. if (empty($this->field) || true === $this->field) {
  340. $query = $this->db(false);
  341. $table = $this->table ?: $query->getTable();
  342. $this->field = $query->getConnection()->getTableFields($table);
  343. $field = $this->field;
  344. } else {
  345. $field = array_merge($this->field, $append);
  346. if ($this->autoWriteTimestamp) {
  347. array_push($field, $this->createTime, $this->updateTime);
  348. }
  349. }
  350. if ($this->disuse) {
  351. // 废弃字段
  352. $field = array_diff($field, (array) $this->disuse);
  353. }
  354. return $field;
  355. }
  356. /**
  357. * 保存写入数据
  358. * @access protected
  359. * @param array $where 保存条件
  360. * @return int|false
  361. */
  362. protected function updateData($where)
  363. {
  364. // 自动更新
  365. $this->autoCompleteData($this->update);
  366. // 事件回调
  367. if (false === $this->trigger('before_update')) {
  368. return false;
  369. }
  370. // 获取有更新的数据
  371. $data = $this->getChangedData();
  372. if (empty($data)) {
  373. // 关联更新
  374. if (!empty($this->relationWrite)) {
  375. $this->autoRelationUpdate();
  376. }
  377. return 0;
  378. } elseif ($this->autoWriteTimestamp && $this->updateTime && !isset($data[$this->updateTime])) {
  379. // 自动写入更新时间
  380. $data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime);
  381. $this->data[$this->updateTime] = $data[$this->updateTime];
  382. }
  383. if (empty($where) && !empty($this->updateWhere)) {
  384. $where = $this->updateWhere;
  385. }
  386. // 检查允许字段
  387. $allowFields = $this->checkAllowFields(array_merge($this->auto, $this->update));
  388. // 保留主键数据
  389. foreach ($this->data as $key => $val) {
  390. if ($this->isPk($key)) {
  391. $data[$key] = $val;
  392. }
  393. }
  394. $pk = $this->getPk();
  395. $array = [];
  396. foreach ((array) $pk as $key) {
  397. if (isset($data[$key])) {
  398. $array[$key] = [$key, '=', $data[$key]];
  399. unset($data[$key]);
  400. }
  401. }
  402. if (!empty($array)) {
  403. $where = $array;
  404. }
  405. if (!empty($this->relationWrite)) {
  406. foreach ($this->relationWrite as $name => $val) {
  407. if (is_array($val)) {
  408. foreach ($val as $key) {
  409. if (isset($data[$key])) {
  410. unset($data[$key]);
  411. }
  412. }
  413. }
  414. }
  415. }
  416. // 模型更新
  417. $result = $this->db(false)->where($where)->strict(false)->field($allowFields)->update($data);
  418. // 关联更新
  419. if (!empty($this->relationWrite)) {
  420. $this->autoRelationUpdate();
  421. }
  422. // 更新回调
  423. $this->trigger('after_update');
  424. return $result;
  425. }
  426. /**
  427. * 新增写入数据
  428. * @access protected
  429. * @param string $sequence 自增名
  430. * @return int|false
  431. */
  432. protected function insertData($sequence)
  433. {
  434. // 自动写入
  435. $this->autoCompleteData($this->insert);
  436. // 时间戳自动写入
  437. $this->checkTimeStampWrite();
  438. if (false === $this->trigger('before_insert')) {
  439. return false;
  440. }
  441. // 检查允许字段
  442. $allowFields = $this->checkAllowFields(array_merge($this->auto, $this->insert));
  443. $result = $this->db(false)->strict(false)->field($allowFields)->insert($this->data, false, false, $sequence);
  444. // 获取自动增长主键
  445. if ($result && $insertId = $this->db(false)->getLastInsID($sequence)) {
  446. $pk = $this->getPk();
  447. foreach ((array) $pk as $key) {
  448. if (!isset($this->data[$key]) || '' == $this->data[$key]) {
  449. $this->data[$key] = $insertId;
  450. }
  451. }
  452. }
  453. // 关联写入
  454. if (!empty($this->relationWrite)) {
  455. $this->autoRelationInsert();
  456. }
  457. // 标记为更新
  458. $this->isUpdate = true;
  459. // 新增回调
  460. $this->trigger('after_insert');
  461. return $result;
  462. }
  463. /**
  464. * 字段值(延迟)增长
  465. * @access public
  466. * @param string $field 字段名
  467. * @param integer $step 增长值
  468. * @param integer $lazyTime 延时时间(s)
  469. * @return integer|true
  470. * @throws Exception
  471. */
  472. public function setInc($field, $step = 1, $lazyTime = 0)
  473. {
  474. // 读取更新条件
  475. $where = $this->getWhere();
  476. $result = $this->db(false)->where($where)->setInc($field, $step, $lazyTime);
  477. if (true !== $result) {
  478. $this->data[$field] += $step;
  479. }
  480. return $result;
  481. }
  482. /**
  483. * 字段值(延迟)增长
  484. * @access public
  485. * @param string $field 字段名
  486. * @param integer $step 增长值
  487. * @param integer $lazyTime 延时时间(s)
  488. * @return integer|true
  489. * @throws Exception
  490. */
  491. public function setDec($field, $step = 1, $lazyTime = 0)
  492. {
  493. // 读取更新条件
  494. $where = $this->getWhere();
  495. $result = $this->db(false)->where($where)->setDec($field, $step, $lazyTime);
  496. if (true !== $result) {
  497. $this->data[$field] -= $step;
  498. }
  499. return $result;
  500. }
  501. /**
  502. * 获取当前的更新条件
  503. * @access protected
  504. * @return mixed
  505. */
  506. protected function getWhere()
  507. {
  508. // 删除条件
  509. $pk = $this->getPk();
  510. if (is_string($pk) && isset($this->data[$pk])) {
  511. $where[] = [$pk, '=', $this->data[$pk]];
  512. } elseif (!empty($this->updateWhere)) {
  513. $where = $this->updateWhere;
  514. } else {
  515. $where = null;
  516. }
  517. return $where;
  518. }
  519. /**
  520. * 保存多个数据到当前数据对象
  521. * @access public
  522. * @param array $dataSet 数据
  523. * @param boolean $replace 是否自动识别更新和写入
  524. * @return Collection
  525. * @throws \Exception
  526. */
  527. public function saveAll($dataSet, $replace = true)
  528. {
  529. $result = [];
  530. $db = $this->db(false);
  531. $db->startTrans();
  532. try {
  533. $pk = $this->getPk();
  534. if (is_string($pk) && $replace) {
  535. $auto = true;
  536. }
  537. foreach ($dataSet as $key => $data) {
  538. if ($this->isUpdate || (!empty($auto) && isset($data[$pk]))) {
  539. $result[$key] = self::update($data, [], $this->field);
  540. } else {
  541. $result[$key] = self::create($data, $this->field);
  542. }
  543. }
  544. $db->commit();
  545. return $this->toCollection($result);
  546. } catch (\Exception $e) {
  547. $db->rollback();
  548. throw $e;
  549. }
  550. }
  551. /**
  552. * 是否为更新数据
  553. * @access public
  554. * @param mixed $update
  555. * @param mixed $where
  556. * @return $this
  557. */
  558. public function isUpdate($update = true, $where = null)
  559. {
  560. if (is_bool($update)) {
  561. $this->isUpdate = $update;
  562. if (!empty($where)) {
  563. $this->updateWhere = $where;
  564. }
  565. } else {
  566. $this->isUpdate = true;
  567. $this->updateWhere = $update;
  568. }
  569. return $this;
  570. }
  571. /**
  572. * 删除当前的记录
  573. * @access public
  574. * @return integer
  575. */
  576. public function delete()
  577. {
  578. if (false === $this->trigger('before_delete')) {
  579. return false;
  580. }
  581. // 读取更新条件
  582. $where = $this->getWhere();
  583. // 删除当前模型数据
  584. $result = $this->db(false)->where($where)->delete();
  585. // 关联删除
  586. if (!empty($this->relationWrite)) {
  587. $this->autoRelationDelete();
  588. }
  589. $this->trigger('after_delete');
  590. // 清空数据
  591. $this->data = [];
  592. $this->origin = [];
  593. return $result;
  594. }
  595. /**
  596. * 设置自动完成的字段( 规则通过修改器定义)
  597. * @access public
  598. * @param array $fields 需要自动完成的字段
  599. * @return $this
  600. */
  601. public function auto($fields)
  602. {
  603. $this->auto = $fields;
  604. return $this;
  605. }
  606. /**
  607. * 写入数据
  608. * @access public
  609. * @param array $data 数据数组
  610. * @param array|true $field 允许字段
  611. * @return static
  612. */
  613. public static function create($data = [], $field = null)
  614. {
  615. $model = new static();
  616. if (!empty($field)) {
  617. $model->allowField($field);
  618. }
  619. $model->isUpdate(false)->save($data, []);
  620. return $model;
  621. }
  622. /**
  623. * 更新数据
  624. * @access public
  625. * @param array $data 数据数组
  626. * @param array $where 更新条件
  627. * @param array|true $field 允许字段
  628. * @return static
  629. */
  630. public static function update($data = [], $where = [], $field = null)
  631. {
  632. $model = new static();
  633. if (!empty($field)) {
  634. $model->allowField($field);
  635. }
  636. $model->isUpdate(true)->save($data, $where);
  637. return $model;
  638. }
  639. /**
  640. * 查找单条记录
  641. * @access public
  642. * @param mixed $data 主键值或者查询条件(闭包)
  643. * @param mixed $with 关联预查询
  644. * @param bool $cache 是否缓存
  645. * @param bool $failException 是否抛出异常
  646. * @return static|null
  647. * @throws exception\DbException
  648. */
  649. public static function get($data, $with = [], $cache = false, $failException = false)
  650. {
  651. if (is_null($data)) {
  652. return;
  653. }
  654. if (true === $with || is_int($with)) {
  655. $cache = $with;
  656. $with = [];
  657. }
  658. $query = static::parseQuery($data, $with, $cache);
  659. return $query->failException($failException)->find($data);
  660. }
  661. /**
  662. * 查找单条记录 如果不存在直接抛出异常
  663. * @access public
  664. * @param mixed $data 主键值或者查询条件(闭包)
  665. * @param mixed $with 关联预查询
  666. * @param bool $cache 是否缓存
  667. * @return static|null
  668. * @throws exception\DbException
  669. */
  670. public static function getOrFail($data, $with = [], $cache = false)
  671. {
  672. return self::get($data, $with, $cache, true);
  673. }
  674. /**
  675. * 查找所有记录
  676. * @access public
  677. * @param mixed $data 主键列表或者查询条件(闭包)
  678. * @param array|string $with 关联预查询
  679. * @param bool $cache 是否缓存
  680. * @return static[]|false
  681. * @throws exception\DbException
  682. */
  683. public static function all($data = null, $with = [], $cache = false)
  684. {
  685. if (true === $with || is_int($with)) {
  686. $cache = $with;
  687. $with = [];
  688. }
  689. $query = static::parseQuery($data, $with, $cache);
  690. return $query->select($data);
  691. }
  692. /**
  693. * 分析查询表达式
  694. * @access public
  695. * @param mixed $data 主键列表或者查询条件(闭包)
  696. * @param string $with 关联预查询
  697. * @param bool $cache 是否缓存
  698. * @return Query
  699. */
  700. protected static function parseQuery(&$data, $with, $cache)
  701. {
  702. $result = self::with($with)->cache($cache);
  703. if (is_array($data) && key($data) !== 0) {
  704. $result = $result->where($data);
  705. $data = null;
  706. } elseif ($data instanceof \Closure) {
  707. $data($result);
  708. $data = null;
  709. } elseif ($data instanceof Query) {
  710. $result = $data->with($with)->cache($cache);
  711. $data = null;
  712. }
  713. return $result;
  714. }
  715. /**
  716. * 删除记录
  717. * @access public
  718. * @param mixed $data 主键列表 支持闭包查询条件
  719. * @return integer 成功删除的记录数
  720. */
  721. public static function destroy($data)
  722. {
  723. $model = new static();
  724. $query = $model->db();
  725. if (empty($data) && 0 !== $data) {
  726. return 0;
  727. } elseif (is_array($data) && key($data) !== 0) {
  728. $query->where($data);
  729. $data = null;
  730. } elseif ($data instanceof \Closure) {
  731. $data($query);
  732. $data = null;
  733. }
  734. $resultSet = $query->select($data);
  735. $count = 0;
  736. if ($resultSet) {
  737. foreach ($resultSet as $data) {
  738. $result = $data->delete();
  739. $count += $result;
  740. }
  741. }
  742. return $count;
  743. }
  744. /**
  745. * 获取错误信息
  746. * @access public
  747. * @return mixed
  748. */
  749. public function getError()
  750. {
  751. return $this->error;
  752. }
  753. /**
  754. * 解序列化后处理
  755. */
  756. public function __wakeup()
  757. {
  758. $this->initialize();
  759. }
  760. public function __debugInfo()
  761. {
  762. return [
  763. 'data' => $this->data,
  764. 'relation' => $this->relation,
  765. ];
  766. }
  767. /**
  768. * 修改器 设置数据对象的值
  769. * @access public
  770. * @param string $name 名称
  771. * @param mixed $value 值
  772. * @return void
  773. */
  774. public function __set($name, $value)
  775. {
  776. $this->setAttr($name, $value);
  777. }
  778. /**
  779. * 获取器 获取数据对象的值
  780. * @access public
  781. * @param string $name 名称
  782. * @return mixed
  783. */
  784. public function __get($name)
  785. {
  786. return $this->getAttr($name);
  787. }
  788. /**
  789. * 检测数据对象的值
  790. * @access public
  791. * @param string $name 名称
  792. * @return boolean
  793. */
  794. public function __isset($name)
  795. {
  796. if (array_key_exists($name, $this->data) || array_key_exists($name, $this->relation)) {
  797. return true;
  798. } else {
  799. return false;
  800. }
  801. }
  802. /**
  803. * 销毁数据对象的值
  804. * @access public
  805. * @param string $name 名称
  806. * @return void
  807. */
  808. public function __unset($name)
  809. {
  810. unset($this->data[$name], $this->relation[$name]);
  811. }
  812. // ArrayAccess
  813. public function offsetSet($name, $value)
  814. {
  815. $this->setAttr($name, $value);
  816. }
  817. public function offsetExists($name)
  818. {
  819. return $this->__isset($name);
  820. }
  821. public function offsetUnset($name)
  822. {
  823. $this->__unset($name);
  824. }
  825. public function offsetGet($name)
  826. {
  827. return $this->getAttr($name);
  828. }
  829. /**
  830. * 设置是否使用全局查询范围
  831. * @access public
  832. * @param bool $use 是否启用全局查询范围
  833. * @return Query
  834. */
  835. public static function useGlobalScope($use)
  836. {
  837. $model = new static();
  838. return $model->db($use);
  839. }
  840. public function __call($method, $args)
  841. {
  842. return call_user_func_array([$this->db(), $method], $args);
  843. }
  844. public static function __callStatic($method, $args)
  845. {
  846. $model = new static();
  847. return call_user_func_array([$model->db(), $method], $args);
  848. }
  849. }