Base.php 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113
  1. <?php
  2. namespace Qii\Driver\Entity;
  3. use Qii\Driver\Model;
  4. use Qii\Driver\Response;
  5. use Qii\Exceptions\InvalidParams;
  6. class Base {
  7. /**
  8. * 字段及值
  9. *
  10. * @var array $properties
  11. */
  12. protected $properties;
  13. /**
  14. * 配置信息
  15. *
  16. * @var array $config
  17. */
  18. public static $config;
  19. /**
  20. * @var Model $db
  21. */
  22. public static $db = null;
  23. /**
  24. * 主键
  25. * @var mix $privateKeys null
  26. */
  27. protected $privateKeys = null;
  28. /**
  29. * 唯一字段
  30. *
  31. * @var array $uniqKeys
  32. */
  33. protected $uniqKeys = null;
  34. /**
  35. * 设置排除项
  36. *
  37. * @var array $exclude
  38. */
  39. protected $exclude = [];
  40. /**
  41. * @var string 表别名
  42. */
  43. private $alias;
  44. private $nullFields = [];
  45. /**
  46. * hooker for fields 查询字段/ where 查询条件 / order 排序 / cache 缓存 / with 关联查询
  47. * @var array $hooker
  48. */
  49. private $hooker = array();
  50. /**
  51. * 默认过期时间
  52. *
  53. * @var int $defaultExpired
  54. */
  55. private $defaultExpired = 600;
  56. /**
  57. * 当前执行的sql
  58. *
  59. * @var string
  60. */
  61. private $calledSQL = "";
  62. /**
  63. * 最后插入数据的自增ID
  64. *
  65. * @var int $lastInsertID
  66. */
  67. private $lastInsertID;
  68. /** 表名
  69. *
  70. * @var null
  71. */
  72. private $tableName = null;
  73. /**
  74. * 错误信息
  75. *
  76. * @var array $__Error {code:0, msg:'', body:mixed}
  77. */
  78. public $__Error;
  79. public function __construct(){
  80. $this->cleanVars();
  81. }
  82. /**
  83. * 初始化的时候清除所有静态变量的值
  84. *
  85. * @return void
  86. */
  87. final public function cleanVars() {
  88. $this->properties = [];
  89. $this->uniqKeys = null;
  90. $this->privateKeys = null;
  91. $this->exclude = [];
  92. }
  93. /**
  94. * 默认值,仅在新增数据的时候支持,更新不支持
  95. *
  96. * @return array
  97. */
  98. public function defaultFieldsValue(){}
  99. /**
  100. * 设置表名
  101. *
  102. * @param $tableName
  103. * @return void
  104. */
  105. public function setTableName($tableName) {
  106. if(is_callable($tableName)) {
  107. $this->tableName = $tableName();
  108. }
  109. if($tableName) $this->tableName = $tableName;
  110. }
  111. /**
  112. * 返回 table 的名字,以便分库分表的时候指定使用
  113. *
  114. * @return mixed
  115. * @throws \Exception
  116. */
  117. public function getTable() {
  118. if($this->tableName != null) {
  119. return $this->tableName;
  120. }
  121. throw new \Exception('请先设置需要保存的数据表');
  122. }
  123. /**
  124. * 当前表名别名
  125. *
  126. * @param string $name
  127. * @return $this
  128. */
  129. public function alias($name) {
  130. $this->alias = $name;
  131. return $this;
  132. }
  133. /**
  134. * 预处理表名
  135. *
  136. * @return mixed|string
  137. * @throws \Exception
  138. */
  139. public function prepareTable() {
  140. if($this->alias == '') {
  141. return $this->getTable();
  142. }
  143. return $this->getTable() . ' ' . $this->alias;
  144. }
  145. /**
  146. * set hooker for method
  147. * 目前 where 和 order 及 fields 支持
  148. * @param $key
  149. * @param $hooker
  150. * @return $this
  151. */
  152. protected function setHooker($key, $hooker, $args) {
  153. $this->hooker[$key]['func'] = $hooker;
  154. $this->hooker[$key]['args'] = $args;
  155. return $this;
  156. }
  157. /**
  158. * or 查询
  159. * @param array | string $condition 条件
  160. * @param mixed $args 参数
  161. * @return $this
  162. * @throws \Exception
  163. */
  164. final public function or($condition, $args = null) {
  165. $this->setOrHooker(function($or) use($condition){
  166. if(is_array($condition)) {
  167. $or = array_merge($or, $condition);
  168. return $or;
  169. }
  170. return $condition;
  171. });
  172. return $this;
  173. }
  174. /**
  175. * Or Hooker
  176. * @param $hooker
  177. * @param $args
  178. * @return $this
  179. * @throws \Exception
  180. */
  181. public function setOrHooker($hooker, $args = null){
  182. $this->checkCallable($hooker);
  183. if(!isset($this->hooker['or'])) {
  184. $this->hooker['or'] = [];
  185. }
  186. $this->hooker['or'][] = ['func' => $hooker, 'args' => $args];
  187. return $this;
  188. }
  189. /**
  190. * 获取or条件
  191. *
  192. * @return array
  193. */
  194. public function getOrHooker() {
  195. $or = [];
  196. if(isset($this->hooker['or'])) {
  197. foreach ($this->hooker['or'] as $value) {
  198. if(is_callable($value['func'])) {
  199. $or[] = call_user_func($value['func'], [], $value['args']);
  200. }
  201. }
  202. }
  203. return $or;
  204. }
  205. /**
  206. * where 条件 多个where就用and来连接
  207. * @param array $where where条件
  208. * @param mixed $args 参数
  209. * @return $this
  210. * @throws \Exception
  211. */
  212. final public function where($where, $args = null) {
  213. $this->setWhereHooker(function($w) use($where){
  214. /*if(is_array($where)) {
  215. $w[] = $where;
  216. return $w;
  217. }*/
  218. $w[] = $where;
  219. return $w;
  220. }, $args);
  221. return $this;
  222. }
  223. /**
  224. * 设置where hooker
  225. * @param object $hooker
  226. * @return $this
  227. * @throws \Exception
  228. */
  229. public function setWhereHooker($hooker, $args = null) {
  230. $this->checkCallable($hooker);
  231. if(!isset($this->hooker['where'])) {
  232. $this->hooker['where'] = [];
  233. }
  234. $this->hooker['where'][] = ['func' => $hooker, 'args' => $args];
  235. return $this;
  236. }
  237. /**
  238. * 获取where条件
  239. *
  240. * @return array|mixed
  241. */
  242. public function getWhereHooker() {
  243. $where = $this->properties();
  244. if(!isset($this->hooker['where']) || !is_array($this->hooker['where'])) {
  245. return $where;
  246. }
  247. // 遍历
  248. foreach ($this->hooker['where'] as $item) {
  249. if(is_callable($item['func'])) {
  250. $subWhere = call_user_func($item['func'], $where, $item['args']);
  251. foreach ($subWhere as $key => $value) {
  252. if($this->alias != "") {
  253. if(!preg_match("/{$this->alias}\.{$key}/", $key)) {
  254. $where[$this->alias . '.' . $key] = $value;
  255. unset($subWhere[$key]);
  256. }
  257. }else{
  258. $where[$key] = $value;
  259. }
  260. }
  261. }
  262. }
  263. return $where;
  264. }
  265. /**
  266. * join 条件
  267. * @param mixed $join 条件
  268. * @param mixed $args 参数
  269. * @return $this
  270. * @throws \Exception
  271. */
  272. final public function join($join, $args = null) {
  273. $this->setJoinHooker(function($j) use($join){
  274. $j[] = $join;
  275. return $j;
  276. }, $args);
  277. return $this;
  278. }
  279. /**
  280. * join hooker
  281. * @param \Closure $hooker
  282. * @param mix $args
  283. * @return $this
  284. * @throws \Exception
  285. */
  286. public function setJoinHooker($hooker, $args = null) {
  287. $this->checkCallable($hooker);
  288. if(!isset($this->hooker['join'])) {
  289. $this->hooker['join'] = [];
  290. }
  291. $this->hooker['join'][] = ['func' => $hooker, 'args' => $args];
  292. return $this;
  293. }
  294. /**
  295. * 获取 join hooker
  296. * @return array
  297. */
  298. public function getJoinHooker() {
  299. $join = [];
  300. if(isset($this->hooker['join'])) {
  301. foreach ($this->hooker['join'] as $value) {
  302. if(is_callable($value['func'])) {
  303. $join[] = call_user_func($value['func'], [], $value['args']);
  304. }
  305. }
  306. }
  307. return $join;
  308. }
  309. /**
  310. * 设置group
  311. *
  312. * @param array $group group对应的数组
  313. * @param mixed $args
  314. * @return void
  315. */
  316. final public function group($group, $args = null) {
  317. if(!isset($this->hooker['group'])) {
  318. $this->hooker['group'] = [];
  319. }
  320. $this->hooker['group'][] = ['func' => function ()use ($group) {
  321. return $group;
  322. }, 'args' => $args];
  323. return $this;
  324. }
  325. /**
  326. * get group hooker
  327. * @return array
  328. */
  329. final public function getGroupBy() {
  330. if(!isset($this->hooker['group']) || !is_array($this->hooker['group'])) {
  331. return [];
  332. }
  333. $group = [];
  334. foreach ($this->hooker['group'] as $value) {
  335. $group = array_merge(call_user_func($value['func'], [], $value['args']));
  336. }
  337. return $group;
  338. }
  339. /**
  340. * order by
  341. * @param array $order
  342. * @param mix $args 参数
  343. * @return $this
  344. * @throws \Exception
  345. */
  346. final public function order($order, $args = null) {
  347. $this->setOrderHooker(function() use($order) {
  348. return $order;
  349. }, $args);
  350. return $this;
  351. }
  352. /**
  353. * 设置order by hooker
  354. * @param object $hooker
  355. * @return $this
  356. * @throws \Exception
  357. */
  358. public function setOrderHooker($hooker, $args = null) {
  359. $this->checkCallable($hooker);
  360. $this->setHooker('order', $hooker, $args);
  361. return $this;
  362. }
  363. /**
  364. * limit
  365. * @param array $limit [page, limit]
  366. * @param mixed $args 参数
  367. * @return $this
  368. * @throws \Exception
  369. */
  370. final public function limit($limit, $args = null) {
  371. $this->setLimitHooker(function() use($limit){
  372. return $limit;
  373. }, $args);
  374. return $this;
  375. }
  376. /**
  377. * 设置 limit hooker
  378. *
  379. * @param object $hooker
  380. * @return $this
  381. * @throws \Exception
  382. */
  383. public function setLimitHooker($hooker, $args = null) {
  384. $this->checkCallable($hooker);
  385. $this->setHooker('limit', $hooker, $args);
  386. return $this;
  387. }
  388. /**
  389. * 获取limit
  390. * @return int|mixed
  391. */
  392. public function getLimitHooker() {
  393. if(isset($this->hooker['limit']) && is_callable($this->hooker['limit']['func'])) {
  394. return call_user_func($this->hooker['limit']['func'], [], $this->hooker['limit']['args']);
  395. }
  396. return [];
  397. }
  398. /**
  399. * 设置缓存插件
  400. *
  401. * @param array $cache 缓存类
  402. * @return $this
  403. * @throws \Exception
  404. */
  405. final public function cache($cache) {
  406. $this->setCacheHooker(function() use($cache){
  407. return $cache;
  408. });
  409. return $this;
  410. }
  411. /**
  412. * 设置 cache hooker
  413. *
  414. * @param callable $hooker
  415. * @param array| mixed $args
  416. * @return $this
  417. * @throws \Exception
  418. */
  419. public function setCacheHooker($hooker, $args = null) {
  420. $this->checkCallable($hooker);
  421. $this->setHooker('cache', $hooker, $args);
  422. return $this;
  423. }
  424. /**
  425. * 获取Cache Hooker
  426. * @return mixed|null[]
  427. */
  428. public function getCacheHooker() {
  429. if(isset($this->hooker['cache']) && is_callable($this->hooker['cache']['func'])) {
  430. return call_user_func($this->hooker['cache']['func'], [], $this->hooker['cache']['args']);
  431. }
  432. return [null, null, null];
  433. }
  434. /**
  435. * 缓存设置
  436. *
  437. * @param array $config 缓存配置
  438. * @return void
  439. */
  440. public function setCacheConfig($config) {
  441. if(!is_array($config)) {
  442. return;
  443. }
  444. self::$config['cache'] = $config;
  445. }
  446. /**
  447. * 获取缓存的配置信息
  448. *
  449. * @return array
  450. */
  451. public function getCacheConfig() {
  452. if(is_array(self::$config) && isset(self::$config['cache']) && is_array(self::$config['cache'])) {
  453. return self::$config['cache'];
  454. }
  455. return array();
  456. }
  457. /**
  458. * with
  459. *
  460. * @param array $with 获取信息 [$rel, 'with name', 'hasOne/hasMany', 'key', 'rel_pri_key']
  461. * @return $this
  462. * @throws \Exception
  463. */
  464. public function with($with) {
  465. $this->setWith(function ()use($with){
  466. return $with;
  467. });
  468. return $this;
  469. }
  470. /**
  471. * 设置关联子查询
  472. *
  473. * @param $hooker [关联对象, 返回数据key, hasOne/hasMany, 主键, rel 主键]
  474. * @params $args
  475. * @return $this
  476. * @throws \Exception
  477. */
  478. public function setWith($hooker, $args = null){
  479. $this->checkCallable($hooker);
  480. if(!isset($this->hooker['with'])) {
  481. $this->hooker['with'] = [];
  482. }
  483. $this->hooker['with'][] = ['func' => $hooker, 'args' => $args];
  484. return $this;
  485. }
  486. /**
  487. * 获取with hooker
  488. *
  489. * @return array
  490. */
  491. public function getWithHooker() {
  492. $callback = [];
  493. if(isset($this->hooker['with'])) {
  494. foreach ($this->hooker['with'] AS $hooker) {
  495. if(is_callable($hooker['func'])) {
  496. $callback[] = call_user_func($hooker['func'], [], $hooker['args']);
  497. }
  498. }
  499. }
  500. return $callback;
  501. }
  502. /**
  503. * 如果hooker不可调用即抛出异常
  504. *
  505. * @param object $hooker
  506. * @return void
  507. * @throws \Exception
  508. */
  509. private function checkCallable($hooker) {
  510. if($hooker && !is_callable($hooker)) {
  511. throw new \Exception('Hooker is uncallable');
  512. }
  513. }
  514. /**
  515. * 设置order by hooker
  516. * @param object $hooker
  517. * @return void
  518. * @throws \Exception
  519. */
  520. public function setQueryFieldsHooker($hooker, $args = null) {
  521. if(!is_callable($hooker)) {
  522. throw new \Exception('Hooker is un callable');
  523. }
  524. $this->setHooker('fields', $hooker, $args);
  525. }
  526. /**
  527. * 通过field hooker返回查询的字段
  528. *
  529. * @return mixed|string
  530. */
  531. public function getFieldsHooker() {
  532. if(isset($this->hooker['fields']) && is_callable($this->hooker['fields']['func'])) {
  533. return call_user_func($this->hooker['fields']['func'], [], $this->hooker['fields']['args']);
  534. }
  535. return '*';
  536. }
  537. /**
  538. * 获取指定field的值
  539. * @param string $field
  540. * @return mixed
  541. */
  542. public function getFieldVal($field) {
  543. if(!preg_match('/^[a-zA-Z]/', $field)) {
  544. throw new \Exception('Field is illegal');
  545. }
  546. $property = $this->entity()->convertToProperty($field);
  547. return $this->{$property};
  548. }
  549. /**
  550. * 返回使用的db信息
  551. *
  552. * @return \Qii\Driver\Base
  553. */
  554. public function db() {
  555. if(self::$db !== null && self::$db instanceof Model) {
  556. return self::$db;
  557. }
  558. return _loadClass('\Qii\Driver\Model');
  559. }
  560. /**
  561. * DB 必须是Model类型
  562. *
  563. * @param $db
  564. * @return void
  565. * @throws \Exception
  566. */
  567. final public function setDB($db) {
  568. if(!($db instanceof \Qii\Driver\Model)) {
  569. throw new \Exception('DB is illegal');
  570. }
  571. self::$db = $db;
  572. }
  573. /**
  574. * 返回 entity 信息
  575. * @return \Qii\Driver\Entity\Entity
  576. */
  577. public function entity() {
  578. return _loadClass('\Qii\Driver\Entity\Entity');
  579. }
  580. /**
  581. * 设置查询字段
  582. *
  583. * @param array|string $fields 字段名称
  584. * @param $args
  585. * @return void
  586. * @throws \Exception
  587. */
  588. final public function field($fields, $args = null) {
  589. $this->setQueryFieldsHooker(function() use($fields){
  590. return $fields;
  591. }, $args);
  592. }
  593. /**
  594. * 返回所有 Fields
  595. * @return array
  596. */
  597. public function fields()
  598. {
  599. return [];
  600. }
  601. /**
  602. * 设置唯一字段
  603. *
  604. * @param mixed $uniqKeys 唯一字段
  605. * @return void
  606. */
  607. public function setUniqKeys($uniqKeys) {
  608. $this->uniqKeys = $uniqKeys;
  609. }
  610. /**
  611. * unique (unique 如果是 array('a,b') 则表示 a,b联合唯一,array('a,b', 'b,c') 表示a,b唯一 或 b,c唯一
  612. * 'a,b' 字符串则表示任意唯一 类似于array ('a','b')
  613. *
  614. * @return mixed
  615. * @throws \Exception
  616. */
  617. public function uniqueKey(){
  618. if($this->uniqKeys !== null) {
  619. return $this->uniqKeys;
  620. }
  621. throw new \Exception('请设置唯一值');
  622. }
  623. /**
  624. * 设置主键
  625. *
  626. * @param mixed $privateKeys
  627. * @return void
  628. */
  629. public function setPrivateKey($privateKeys){
  630. $this->privateKeys = $privateKeys;
  631. }
  632. /**
  633. * 主键
  634. *
  635. * @return mixed
  636. * @throws \Exception
  637. */
  638. public function primaryKey(){
  639. if($this->privateKeys !== null) {
  640. return $this->privateKeys;
  641. }
  642. throw new \Exception('请设置主键');
  643. }
  644. /**
  645. * 设置排除项
  646. * @param array $exclude
  647. * @return void
  648. */
  649. public function setExclude($exclude) {
  650. if(!is_array($exclude)) {
  651. return;
  652. }
  653. $this->exclude = $exclude;
  654. }
  655. /**
  656. * 保存数据的时候,验证唯一需要排除的值,此处仅支持,单个或联合排除,不支持单个异或排除
  657. *
  658. * @return array
  659. */
  660. public function exclude(){
  661. if($this->exclude !== null) {
  662. return $this->exclude;
  663. }
  664. return array();
  665. }
  666. /**
  667. * order by
  668. * @return string[]
  669. */
  670. public function orderBy() {
  671. return array();
  672. }
  673. /**
  674. * explode string
  675. * @param string $separator 分隔符
  676. * @param string $string 分割的字符串
  677. * @param int $limit 是否
  678. * @return array|false|string[]
  679. */
  680. public function explode($separator, $string, $limit = PHP_INT_MAX) {
  681. if($string == '') {
  682. return [];
  683. }
  684. return explode($separator, $string, $limit);
  685. }
  686. /**
  687. * 添加数据验证字段
  688. *
  689. * $fields = [];
  690. * return $this->valid($fields);
  691. *
  692. * @return mixed
  693. * @throws \Exception
  694. */
  695. public function validFieldsForAdd(){
  696. throw new \Exception('请设置插入数据验证的字段,格式如:["Id", "Title"],Id和Title为entity的属性');
  697. }
  698. /**
  699. * 更新数据验证字段
  700. *
  701. * $fields = [];
  702. * return $this->valid($fields);
  703. *
  704. * @return mixed
  705. * @throws \Exception
  706. */
  707. public function validFieldsForUpdate() {
  708. throw new \Exception('请设置更新数据验证的字段,格式如:["Id", "Title"],Id和Title为entity的属性');
  709. }
  710. /**
  711. * 更新数据验证字段
  712. *
  713. * $fields = [];
  714. * return $this->valid($fields);
  715. *
  716. * @return mixed
  717. * @throws \Exception
  718. */
  719. public function validFieldsForReplace() {
  720. throw new \Exception('请设置更新数据验证的字段,格式如:["Id", "Title"],Id和Title为entity的属性');
  721. }
  722. /**
  723. * 设置需要更新为空的字段列表
  724. *
  725. * @param $fields
  726. * @return $this
  727. */
  728. public function setNull($fields) {
  729. $tableFields = $this->fields();
  730. foreach ($fields AS $field) {
  731. if(!in_array($field, $tableFields)) {
  732. continue;
  733. }
  734. $field = $this->entity()->convertToProperty($field);
  735. $this->nullFields[] = $field;
  736. }
  737. return $this;
  738. }
  739. /**
  740. * 获取不为空的属性
  741. *
  742. * @return array
  743. */
  744. public function properties() {
  745. $class = get_called_class();
  746. $method = new \ReflectionClass($class);
  747. $properties = $method->getproperties();
  748. $fields = [];
  749. foreach($properties as $property) {
  750. if($property->isPublic() && !$property->isStatic()) {
  751. $name = $property->getName();
  752. if(!isset($this->$name) || !preg_match('/^[A-Z\_].*?/', $name)) {
  753. continue;
  754. }
  755. $field = $this->entity()->convertToField($name);
  756. $fields[$field] = $this->$name;
  757. }
  758. }
  759. if(count($this->nullFields) > 0) {
  760. foreach ($this->nullFields AS $field) {
  761. $field = $this->entity()->convertToField($field);
  762. $fields[$field] = null;
  763. }
  764. }
  765. return $fields;
  766. }
  767. /**
  768. * 获取默认值
  769. *
  770. * @return array
  771. */
  772. public function getDefaultValue() {
  773. $default = [];
  774. $defaultValue = $this->defaultFieldsValue();
  775. if(!$defaultValue || !is_array($defaultValue) || count($defaultValue) == 0) {
  776. return $default;
  777. }
  778. foreach ($defaultValue as $key => $value) {
  779. $field = $this->entity()->convertToField($key);
  780. $default[$field] = $value;
  781. }
  782. return $default;
  783. }
  784. /**
  785. * 获取总行数
  786. *
  787. * @return mixed
  788. * @throws \Exception
  789. */
  790. public function count() {
  791. $query = $this->createQuery();
  792. $query->fields(' COUNT(1) as count');
  793. $query->groupBy($this->getGroupBy());
  794. return $query->selectOne($this->prepareTable());
  795. }
  796. /**
  797. * 检查是否有对应的属性
  798. *
  799. * @param $key
  800. * @return bool
  801. * @throws \ReflectionException
  802. */
  803. private $__property = [];
  804. public function hasProperty($key) {
  805. $class = get_called_class();
  806. $key = $this->entity()->convertToProperty($key);
  807. if(isset($this->properties[$class])) {
  808. return isset($this->properties[$class][$key]);
  809. }
  810. $method = new \ReflectionClass($class);
  811. $properties = $method->getproperties();
  812. $fields = array();
  813. foreach($properties as $property) {
  814. $name = $property->getName();
  815. if($property->isPublic() && preg_match('/^[A-Z\_].*?/', $name)) {
  816. $fields[$name] = '';
  817. }
  818. }
  819. $this->properties[$class] = $fields;
  820. return isset($fields[$key]);
  821. }
  822. /**
  823. * bind value
  824. * @param $values
  825. * @return $this
  826. * @throws \ReflectionException
  827. */
  828. public function bindValues($values) {
  829. if(!is_array($values)) {
  830. return $this;
  831. }
  832. foreach ($values as $key => $value) {
  833. $property = $this->entity()->convertToProperty($key);
  834. if($this->hasProperty($key)) {
  835. if(is_array($value)) {
  836. $value = json_encode($value, JSON_UNESCAPED_UNICODE);
  837. }
  838. if(is_object($value)) {
  839. $value = serialize($value);
  840. }
  841. $this->$property = $value;
  842. }
  843. }
  844. return $this;
  845. }
  846. /**
  847. * 回去当前执行的sql
  848. *
  849. * @return string
  850. */
  851. public function getCalledSQL() {
  852. return $this->calledSQL;
  853. }
  854. /**
  855. * 获取数据
  856. *
  857. * @return Object
  858. * @throws \Exception
  859. */
  860. public function get() {
  861. $class = get_called_class();
  862. $obj = new $class();
  863. $response = $this->info();
  864. if($response->isError()) {
  865. $obj->__Error = $response->getResult();
  866. return $obj;
  867. }
  868. $info = $response->getResult()['body'];
  869. if(!$info) {
  870. return $obj;
  871. }
  872. foreach ($info as $key => $val) {
  873. $key = $this->entity()->convertToProperty($key);
  874. $obj->$key = $val;
  875. }
  876. return $obj;
  877. }
  878. /**
  879. * get 是否返回了错误
  880. *
  881. * @return bool
  882. */
  883. public function isError() {
  884. if(isset($this->__Error)) {
  885. return true;
  886. }
  887. return false;
  888. }
  889. /**
  890. * get 返回的code
  891. *
  892. * @return int
  893. */
  894. public function getCode() {
  895. if(!$this->isError()) {
  896. return 0;
  897. }
  898. return isset($this->__Error['code']) ? $this->__Error['code'] : 0;
  899. }
  900. /**
  901. * 获取错误信息
  902. * @return array
  903. */
  904. public function getErrorInfo() {
  905. if(!$this->isError()) {
  906. return ['code' => 0, 'msg' => ''];
  907. }
  908. return ['code' => $this->getCode(), 'msg' => $this->getMessage()];
  909. }
  910. /**
  911. * get 返回的msg
  912. *
  913. * @return string
  914. */
  915. public function getMessage() {
  916. if(!$this->isError()) {
  917. return '';
  918. }
  919. return isset($this->__Error['msg']) ? $this->__Error['msg'] : '';
  920. }
  921. /**
  922. * 与get不同的这个返回的是Response
  923. *
  924. * @return mixed|Response
  925. */
  926. public function info() {
  927. try{
  928. $query = $this->createQuery();
  929. $info = $query->selectRow($this->prepareTable());
  930. $this->calledSQL = $query->executeSQL;
  931. if($info) $this->withRow($info);
  932. return Response::Success(static::class .'::'. __FUNCTION__,
  933. [
  934. '_result' => ['code' => Response::DO_SUCCESS, 'msg' => '获取成功', 'body' => $info]
  935. ]
  936. );
  937. }catch (\Exception $e) {
  938. return Response::Fail(static::class .'::'. __FUNCTION__,
  939. [
  940. '_result' => ['code' => Response::FAIL_FOR_SELECT, 'msg' =>$e->getMessage(), 'body' => []],
  941. 'message' => $e->getMessage()
  942. ]
  943. );
  944. }
  945. }
  946. /**
  947. * 将表对象对应的字段转换成array
  948. *
  949. * @return array
  950. */
  951. final public function toArray($returnFields = false)
  952. {
  953. $arr = [];
  954. $method = new \ReflectionClass($this);
  955. $vars = [];
  956. foreach ($this as $k => $t) {
  957. if(preg_match("/^[A-Z]+/", $k)) {
  958. $vars[] = $k;
  959. }
  960. }
  961. $fields = $this->fields();
  962. if(count($fields)) {
  963. if($returnFields) {
  964. foreach ($fields as $key => $value) {
  965. $arr['__fields__'][$key] = $value;
  966. }
  967. }
  968. foreach ($vars as $extra) {
  969. if(!isset($arr[$extra])) {
  970. $field = $this->entity()->convertToField($extra);
  971. if(isset($this->$extra)) $arr[$field] = $this->$extra;
  972. }
  973. }
  974. return $arr;
  975. }
  976. $properties = $method->getproperties();
  977. foreach($properties as $property) {
  978. if($property->isPublic() && !$property->isStatic()) {
  979. $name = $property->getName();
  980. $field = $this->entity()->convertToField($name);
  981. if(isset($this->$name)) $arr[$field] = $this->$name;
  982. continue;
  983. }
  984. //移除非public的变量
  985. $i = array_search($property->getName(), $vars);
  986. if($i !== false) {
  987. array_splice($vars, $i, 1);
  988. }
  989. }
  990. foreach ($vars as $extra) {
  991. if(!isset($arr[$extra])) {
  992. $field = $this->entity()->convertToField($extra);
  993. if(isset($this->$extra)) $arr[$field] = $this->$extra;
  994. }
  995. }
  996. return $arr;
  997. }
  998. /**
  999. * 将结果转换成json
  1000. *
  1001. * @return false|string
  1002. */
  1003. final public function toJson() {
  1004. $arr = $this->toArray();
  1005. return json_encode($arr, JSON_UNESCAPED_UNICODE);
  1006. }
  1007. /**
  1008. * 是否相关数据存在
  1009. *
  1010. * @return bool
  1011. */
  1012. final public function exist() {
  1013. $where = $this->getWhereHooker();
  1014. if(!$where) {
  1015. return false;
  1016. }
  1017. return (bool) $this->db()->where($where)->selectOne($this->prepareTable());
  1018. }
  1019. /**
  1020. * replace into database
  1021. *
  1022. * @return mixed|Response
  1023. * @throws InvalidParams
  1024. */
  1025. final public function replace(){
  1026. $valid = $this->validFieldsForReplace();
  1027. if($valid->isError()) {
  1028. return $valid;
  1029. }
  1030. //如果设置了 unique 就先验证唯一性
  1031. list($uniqueWhere, $uniqueOr, $exclude, $primary) = $this->condition();
  1032. unset($uniqueWhere, $uniqueOr, $exclude, $exclude);
  1033. if(count($primary) == 0) {
  1034. throw new InvalidParams('DB::replace需要设置主键');
  1035. }
  1036. $values = array_merge($this->getDefaultValue(), $this->properties());
  1037. $this->lastInsertID = $res = $this->db()->replaceObject($this->prepareTable(), $values);
  1038. if($this->db()->isError()) {
  1039. return Response::FailSave(static::class .'::'. __FUNCTION__,
  1040. [
  1041. '_result' => ['code' => Response::FAIL_FOR_SAVE, 'msg' => $this->db()->getMessage(), 'body' => []],
  1042. 'message' => $this->db()->getMessage()
  1043. ]);
  1044. }
  1045. return Response::Success(static::class .'::'. __FUNCTION__,
  1046. [
  1047. '_result' => ['code' => Response::DO_SUCCESS, 'msg' => '添加成功', 'body' => $res]
  1048. ]
  1049. );
  1050. }
  1051. /**
  1052. * 保存数据
  1053. *
  1054. * @return mixed|Response
  1055. * @throws \Exception
  1056. */
  1057. final public function add() {
  1058. $valid = $this->validFieldsForAdd();
  1059. if($valid->isError()) {
  1060. return $valid;
  1061. }
  1062. //如果设置了 unique 就先验证唯一性
  1063. list($uniqueWhere, $uniqueOr, $exclude, $primary) = $this->condition();
  1064. unset($exclude);
  1065. //如果 $where $or 为空,看看主键是否有设置值,有设置值说明验证主键就可以,反之设置了主键,主键值设置了,只验证主键就可以了
  1066. if(count($primary) > 0) {
  1067. $exist = $this->db()->limit(1)->where($primary)->selectRow($this->prepareTable());
  1068. if($exist) {
  1069. return Response::Exist(static::class .'::'. __FUNCTION__,
  1070. [
  1071. '_result' => ['code' => Response::DOES_EXIST, 'msg' => '数据已经存在(1)', 'body' => $exist],
  1072. 'message' => '数据已经存在(1)'
  1073. ]
  1074. );
  1075. }
  1076. }
  1077. if(count($uniqueWhere) > 0 || count($uniqueOr) > 0) {
  1078. $exist = $this->db()->limit(1)->where($uniqueWhere)->orTerms($uniqueOr)->selectRow($this->prepareTable());
  1079. if($exist) {
  1080. return Response::Exist(static::class .'::'. __FUNCTION__,
  1081. [
  1082. '_result' => ['code' => Response::DOES_EXIST, 'msg' => '数据已经存在(2)', 'body' => $exist],
  1083. 'message' => '数据已存在(2)'
  1084. ]
  1085. );
  1086. }
  1087. }
  1088. $values = array_merge($this->getDefaultValue(), $this->properties());
  1089. $this->lastInsertID = $res = $this->db()->insertObject($this->prepareTable(), $values);
  1090. if($this->db()->isError()) {
  1091. return Response::FailSave(static::class .'::'. __FUNCTION__,
  1092. [
  1093. '_result' => ['code' => Response::FAIL_FOR_SAVE, 'msg' => $this->db()->getMessage() . "(3)", 'body' => []],
  1094. 'message' => $this->db()->getMessage() . "(3)"
  1095. ]);
  1096. }
  1097. return Response::Success(static::class .'::'. __FUNCTION__,
  1098. [
  1099. '_result' => ['code' => Response::DO_SUCCESS, 'msg' => '添加成功', 'body' => $res]
  1100. ]
  1101. );
  1102. }
  1103. /**
  1104. * 获取最后一条插入记录的自增ID
  1105. *
  1106. * @return mixed
  1107. */
  1108. final public function lastInsertID() {
  1109. return $this->lastInsertID;
  1110. }
  1111. /**
  1112. * 删除指定数据
  1113. *
  1114. * @return false|Response
  1115. */
  1116. final public function remove() {
  1117. if(!$this->properties() && empty($this->getWhereHooker())) {
  1118. return Response::Fail(static::class .'::'. __FUNCTION__,
  1119. [
  1120. '_result' => ['code' => Response::FAIL_FOR_VALIDATE, 'msg' => '未指定删除目标', 'body' => []],
  1121. 'message' => '未指定删除目标'
  1122. ]
  1123. );
  1124. }
  1125. $properties = [];
  1126. foreach ($this->properties() as $key => $val) {
  1127. $properties[] = $this->entity()->convertToProperty($key);
  1128. }
  1129. $valid = $this->valid($properties);
  1130. if($valid->isError()) {
  1131. return $valid;
  1132. }
  1133. $query = $this->createQuery();
  1134. $affectedRows = $query->delete($this->prepareTable());
  1135. if($this->db()->isError()) {
  1136. return Response::FailSave(static::class .'::'. __FUNCTION__,
  1137. [
  1138. '_result' => ['code' => Response::FAIL_FOR_SAVE, 'msg' => $this->db()->getMessage(), 'body' => []],
  1139. 'message' => $this->db()->getMessage()
  1140. ]
  1141. );
  1142. }
  1143. return Response::Success(static::class .'::'. __FUNCTION__,
  1144. [
  1145. '_result' => ['code' => Response::DO_SUCCESS, 'msg' => '删除成功,总共删除了'. $affectedRows . '条记录', 'body' => $affectedRows],
  1146. 'message' => '删除成功,总共删除了'. $affectedRows . '条记录'
  1147. ]
  1148. );
  1149. }
  1150. /**
  1151. * 排除操作符
  1152. *
  1153. * @param array $array1 数组1
  1154. * @param array $array2 数组2
  1155. * @return array
  1156. */
  1157. final public function array_diff_assoc($array1, $array2) {
  1158. $arr = array_diff_assoc($array1, $array2);
  1159. foreach($arr as $k => $v) {
  1160. if(is_numeric($k) && in_array($v, ['or', 'and'])) {
  1161. unset($arr[$k]);
  1162. }
  1163. }
  1164. return $arr;
  1165. }
  1166. /**
  1167. * 更新
  1168. *
  1169. * @return mixed | Response
  1170. * @throws \Exception
  1171. */
  1172. final public function update(){
  1173. $valid = $this->validFieldsForUpdate();
  1174. if($valid->isError()) {
  1175. return $valid;
  1176. }
  1177. //检查是否有重复的
  1178. list($uniqueWhere, $uniqueOr, $exclude, $primaryKey) = $this->condition();
  1179. // 检查 unique 是否已经存在相关数据
  1180. $diffWhere = $this->array_diff_assoc($uniqueWhere, $primaryKey);
  1181. $diffOr = $this->array_diff_assoc($uniqueOr, $primaryKey);
  1182. /*print_r(
  1183. [
  1184. 'where' => $uniqueWhere,
  1185. 'or' => $uniqueOr,
  1186. 'exclude' => $exclude,
  1187. 'primary' => $primaryKey
  1188. ]
  1189. );*/
  1190. /*$diffExclude = array_diff_assoc($exclude, $primaryKey);
  1191. print_r(
  1192. [
  1193. 'diffWhere' => $diffWhere,
  1194. 'diffOr' => $diffOr,
  1195. 'diffExclude' => $diffExclude
  1196. ]
  1197. );*/
  1198. if(count($diffWhere) > 0 || count($diffOr) > 0) {
  1199. $unique = $this->db()->limit(1)->where($diffWhere)->orTerms($diffOr)->exclude($exclude)->selectRow($this->prepareTable());
  1200. if($unique) {
  1201. return Response::Exist(static::class .'::'. __FUNCTION__,
  1202. ['_result' => ['code' => Response::DOES_EXIST, 'msg' => '已经存在相关记录', 'body' => $unique]]
  1203. );
  1204. }
  1205. }
  1206. //检查更新的数据是否存在,以主键为主
  1207. $exit = $this->db()->limit(1)->where($primaryKey)->selectOne($this->prepareTable());
  1208. if($exit === null || $exit === false) {
  1209. return Response::NotExist(static::class .'::'. __FUNCTION__,
  1210. ['_result' => ['code' => Response::DOES_NOT_EXIST, 'msg' => '未找到相关记录', 'body' => []]]
  1211. );
  1212. }
  1213. //获取默认值
  1214. //更新的时候不使用默认值
  1215. //$values = array_merge($this->getDefaultValue(), $this->properties());
  1216. $affectedRows = $this->db()->updateObject($this->prepareTable(), $this->properties(), $primaryKey);
  1217. if($this->db()->isError()) {
  1218. return Response::FailUpdate(static::class .'::'. __FUNCTION__,
  1219. [
  1220. '_result' => ['code' => Response::FAIL_FOR_UPDATE, 'msg' => $this->db()->getMessage(), 'body' => []]
  1221. ]
  1222. );
  1223. }
  1224. $msg = '更新成功';
  1225. if($affectedRows > 0) {
  1226. $msg .= ',共更新了'. $affectedRows . '条记录';
  1227. }
  1228. return Response::Success(static::class .'::'. __FUNCTION__,
  1229. [
  1230. '_result' => ['code' => Response::DO_SUCCESS, 'msg' => $msg, 'body' => $affectedRows],
  1231. 'message' => $msg
  1232. ]
  1233. );
  1234. }
  1235. /**
  1236. * 更新字段
  1237. *
  1238. * @return mixed| Response
  1239. * @throws \Exception
  1240. */
  1241. final public function updateFields() {
  1242. $properties = $this->properties();
  1243. $fields = $this->entity()->convertToProperties(array_keys($properties));
  1244. $valid = $this->valid($fields);
  1245. if($valid->isError()) {
  1246. return $valid;
  1247. }
  1248. list($uniqueWhere, $uniqueOr, $exclude, $primaryKey) = $this->condition();
  1249. /*print_r(
  1250. [
  1251. 'where' => $uniqueWhere,
  1252. 'or' => $uniqueOr,
  1253. 'exclude' => $exclude,
  1254. 'primary' => $primaryKey
  1255. ]
  1256. );*/
  1257. // 检查 unique 是否已经存在相关数据
  1258. $diffWhere = $this->array_diff_assoc($uniqueWhere, $primaryKey);
  1259. $diffOr = $this->array_diff_assoc($uniqueOr, $primaryKey);
  1260. /*$diffExclude = array_diff_assoc($exclude, $primaryKey);
  1261. print_r(
  1262. [
  1263. 'diffWhere' => $diffWhere,
  1264. 'diffOr' => $diffOr,
  1265. 'diffExclude' => $diffExclude
  1266. ]
  1267. );*/
  1268. if(count($diffWhere) > 0 || count($diffOr) > 0) {
  1269. $unique = $this->db()->limit(1)->where($diffWhere)->orTerms($diffOr)->exclude($exclude)->selectRow($this->prepareTable());
  1270. if($unique) {
  1271. return Response::Exist(static::class .'::'. __FUNCTION__,
  1272. ['_result' => ['code' => Response::DOES_EXIST, 'msg' => '已经存在相关记录', 'body' => $unique]]
  1273. );
  1274. }
  1275. }
  1276. //检查更新的数据是否存在,以主键为主
  1277. $exit = $this->db()->limit(1)->where($primaryKey)->selectOne($this->prepareTable());
  1278. if($exit === null || $exit === false) {
  1279. return Response::NotExist(static::class .'::'. __FUNCTION__,
  1280. [
  1281. '_result' => ['code' => Response::DOES_NOT_EXIST, 'msg' => '未找到相关记录', 'body' => []],
  1282. 'message' => '未找到相关记录'
  1283. ]
  1284. );
  1285. }
  1286. //获取默认值
  1287. //更新的时候不使用默认值
  1288. //$values = array_merge($this->getDefaultValue(), $this->properties());
  1289. $affectedRows = $this->db()->updateObject($this->prepareTable(), $this->properties(), $primaryKey);
  1290. if($this->db()->isError()) {
  1291. return Response::FailUpdate(static::class .'::'. __FUNCTION__,
  1292. [
  1293. '_result' => ['code' => Response::FAIL_FOR_UPDATE, 'msg' => $this->db()->getMessage(), 'body' => []],
  1294. 'message' => $this->db()->getMessage()
  1295. ]
  1296. );
  1297. }
  1298. return Response::Success(static::class .'::'. __FUNCTION__,
  1299. [
  1300. '_result' => ['code' => Response::DO_SUCCESS, 'msg' => '数据更新成功', 'body' => $affectedRows]
  1301. ]
  1302. );
  1303. }
  1304. /**
  1305. * 增加或减少某一个字段的值
  1306. *
  1307. * @return mixed|Response
  1308. * @throws \Exception
  1309. */
  1310. final public function incr() {
  1311. list($where, $or, $exclude, $primary) = $this->condition();
  1312. unset($where, $or, $exclude);
  1313. $property = $this->properties();
  1314. $incr = [];
  1315. $sets = [];
  1316. foreach ($property as $key => $value) {
  1317. if(!is_numeric($value)) {
  1318. $sets[$key] = $value;
  1319. continue;
  1320. }
  1321. $incr[$key] = $value;
  1322. }
  1323. $diff = $this->array_diff_assoc($incr, $primary);
  1324. if(count($diff) == 0) {
  1325. return Response::Fail(self::class .'::'. __FUNCTION__,
  1326. [
  1327. '_result' => ['code' => Response::DO_FAIL, 'msg' => 'INCR 参数错误'],
  1328. 'message' => 'INCR 参数错误',
  1329. ]
  1330. );
  1331. }
  1332. foreach ($diff as $key => $val) {
  1333. if($val == 0) {
  1334. $sets[$key] = $val;
  1335. }else if($val > 0) {
  1336. $sets[$key . ':plus'] = $val;
  1337. }else if($val < 0) {
  1338. $sets[$key . ':minus'] = $val * -1;
  1339. }
  1340. }
  1341. $affectedRows = $this->db()->set($sets)->where($primary)->update($this->prepareTable());
  1342. if($this->db()->isError()) {
  1343. return Response::FailUpdate(static::class .'::'. __FUNCTION__,
  1344. [
  1345. '_result' => ['code' => Response::FAIL_FOR_UPDATE, 'msg' => $this->db()->getMessage(), 'body' => []],
  1346. 'message' => $this->db()->getMessage()
  1347. ]
  1348. );
  1349. }
  1350. return Response::Success(static::class .'::'. __FUNCTION__,
  1351. [
  1352. '_result' => ['code' => Response::DO_SUCCESS, 'msg' => 'INCR 成功', 'body' => $affectedRows]
  1353. ]
  1354. );
  1355. }
  1356. /**
  1357. * 获取fields
  1358. *
  1359. * @return false|mixed|string|string[]
  1360. */
  1361. final public function getFields() {
  1362. $fields = $this->getFieldsHooker();
  1363. if(!is_array($fields)) {
  1364. $fields = explode(',', preg_replace("/\s{2,}/", " ", preg_replace("/\s(~as)/", "", $fields)));
  1365. }
  1366. return $fields;
  1367. }
  1368. /**
  1369. * 获取where及or条件并创建查询条件
  1370. *
  1371. * @return \Qii\Driver\Base
  1372. */
  1373. final public function createQuery($fields = []) {
  1374. if(empty($fields)) {
  1375. $fields = $this->getFields();
  1376. }
  1377. $query = $this->db()->fields($fields)->where($this->getWhereHooker())->fetchSql($this->calledSQL);
  1378. $or = $this->getOrHooker();
  1379. foreach ($or as $v) {
  1380. $query = $query->orTerms($v);
  1381. }
  1382. $join = $this->getJoinHooker();
  1383. foreach ($join as $j) {
  1384. $query = $query->join($j);
  1385. }
  1386. return $query;
  1387. }
  1388. /**
  1389. * 获取第一条数据
  1390. *
  1391. * @return mixed|Response
  1392. * @throws \Exception
  1393. */
  1394. final public function first() {
  1395. $orderBy = $this->getOrderBy();
  1396. foreach ($orderBy as $key => $value) {
  1397. $orderBy[$key] = 'ASC';
  1398. }
  1399. $query = $this->createQuery();
  1400. $row = $query->limit(1)->groupBy($this->getGroupBy())->orderBy($orderBy)->selectRow($this->prepareTable());
  1401. if($this->db()->isError()) {
  1402. return Response::Fail(static::class .'::'. __FUNCTION__,
  1403. [
  1404. '_result' => ['code' => Response::FAIL_FOR_SELECT, 'msg' => 'Query 失败' . $this->db()->getMessage(), 'body' => []],
  1405. 'message' => $this->db()->getMessage()
  1406. ]
  1407. );
  1408. }
  1409. if($row) {
  1410. $this->withRow($row);
  1411. }
  1412. return Response::Success(static::class .'::'. __FUNCTION__,
  1413. [
  1414. '_result' => ['code' => Response::DO_SUCCESS, 'msg' => 'Query 成功', 'body' => $row]
  1415. ]
  1416. );
  1417. }
  1418. /**
  1419. * 获取第一条数据
  1420. *
  1421. * @return mixed|Response
  1422. * @throws \Exception
  1423. */
  1424. final public function last() {
  1425. $orderBy = $this->getOrderBy();
  1426. foreach ($orderBy as $key => $value) {
  1427. $orderBy[$key] = 'DESC';
  1428. }
  1429. $query = $this->createQuery();
  1430. $row = $query->groupBy($this->getGroupBy())->orderBy($orderBy)->limit(1)->selectRow($this->prepareTable());
  1431. $this->calledSQL = $query->executeSQL;
  1432. if($this->db()->isError()) {
  1433. return Response::Fail(static::class .'::'. __FUNCTION__,
  1434. [
  1435. '_result' => ['code' => Response::FAIL_FOR_SELECT, 'msg' => 'Query 失败', 'body' => []],
  1436. 'messsage' => $this->db()->getMessage()
  1437. ]
  1438. );
  1439. }
  1440. if($row) {
  1441. $this->withRow($row);
  1442. }
  1443. return Response::Success(static::class .'::'. __FUNCTION__,
  1444. [
  1445. '_result' => ['code' => Response::DO_SUCCESS, 'msg' => 'Query 成功', 'body' => $row]
  1446. ]
  1447. );
  1448. }
  1449. /**
  1450. * 附带一行数据
  1451. *
  1452. * @param $row
  1453. * @return void
  1454. */
  1455. final public function withRow(&$row) {
  1456. if(!is_array($row)) {
  1457. return;
  1458. }
  1459. $hooks = $this->getWithHooker();
  1460. foreach ($hooks as $with) {
  1461. if(!is_array($with) || count($with) < 5 || !is_object($with[0])) {
  1462. continue;
  1463. }
  1464. $callable = $with[0];
  1465. $relField = $with[1];
  1466. $method = $with[2];
  1467. $foreignKey = $with[3];
  1468. $associationForeignkey = $with[4];
  1469. $fields = [];
  1470. if(count($with) >= 6) {
  1471. $fields = $with[5];
  1472. }
  1473. $row[$relField] = [];
  1474. if(!isset($row[$foreignKey])) {
  1475. continue;
  1476. }
  1477. $params = [
  1478. $associationForeignkey,
  1479. [$associationForeignkey => $row[$foreignKey]],
  1480. $fields
  1481. ];
  1482. $res = call_user_func_array(array($callable, $method), $params);
  1483. if($res && isset($res[$row[$foreignKey]])) {
  1484. $row[$relField] = $res[$row[$foreignKey]];
  1485. }
  1486. }
  1487. }
  1488. /**
  1489. * 返回游标
  1490. *
  1491. * @param int | null $page 页码
  1492. * @param int | null $pageSize 页大小
  1493. * @return mixed
  1494. * @throws \Qii\Exceptions\InvalidParams
  1495. */
  1496. final public function rs($page = null, $pageSize = null) {
  1497. $query = $this->createQuery()->groupBy($this->getGroupBy())->orderBy($this->getOrderBy());
  1498. if($page && $pageSize) {
  1499. $start = ((max($page, 1)) - 1) * $pageSize;
  1500. $query->limit($start, $pageSize);
  1501. }
  1502. return $query->rs($this->prepareTable());
  1503. }
  1504. /**
  1505. * select rows
  1506. * @param int $page 页码
  1507. * @param int $pageSize 页大小
  1508. * @return array
  1509. * @throws \Qii\Exceptions\InvalidParams
  1510. */
  1511. final public function select($page = null, $pageSize = null) {
  1512. $limit = $this->getLimitHooker();
  1513. if(count($limit) > 0) {
  1514. $page = $limit[0];
  1515. $pageSize = isset($limit[1]) ? $limit[1] : null;
  1516. }
  1517. $query = $this->createQuery();
  1518. $query = $query->groupBy($this->getGroupBy());
  1519. $query = $query->orderBy($this->getOrderBy());
  1520. if($page !== null) {
  1521. $query = $query->limit($page, $pageSize);
  1522. }
  1523. $lists = $query->selectRows($this->prepareTable());
  1524. $this->withList($lists);
  1525. return $lists;
  1526. }
  1527. /**
  1528. * listts
  1529. * @param int $page 页码
  1530. * @param int $pageSize 页大小
  1531. * @return array
  1532. * @throws \Exception
  1533. */
  1534. final public function lists($page = 1, $pageSize = 20) {
  1535. $limit = $this->getLimitHooker();
  1536. if(count($limit) > 0) {
  1537. $page = $limit[0];
  1538. $pageSize = isset($limit[1]) ? $limit[1] : null;
  1539. }
  1540. $count = $this->count();
  1541. if(!$this->initPages($data, $count, $page, $pageSize)) {
  1542. return $data;
  1543. }
  1544. /*$query = $this->createQuery();
  1545. $lists = $query->orderBy($this->getOrderBy())->limit($data['pages']['limitStart'], $pageSize)->selectRows($this->prepareTable());
  1546. $this->withList($lists);
  1547. $data['lists'] = $lists;*/
  1548. $data['lists'] = $this->select($data['pages']['limitStart'], $pageSize);
  1549. return $data;
  1550. }
  1551. /**
  1552. * 附带一行数据
  1553. *
  1554. * @param array $lists
  1555. * @return void
  1556. */
  1557. final public function withList(&$lists) {
  1558. if(!is_array($lists)) {
  1559. return;
  1560. }
  1561. $hooks = $this->getWithHooker();
  1562. foreach ($hooks as $with) {
  1563. if(!is_array($with) || count($with) < 5 || !is_object($with[0])) {
  1564. continue;
  1565. }
  1566. $callable = $with[0];
  1567. $relField = $with[1];
  1568. $method = $with[2];
  1569. $foreignKey = $with[3];
  1570. $associationForeignkey = $with[4];
  1571. $fields = [];
  1572. if(count($with) == 6) {
  1573. $fields = $with[5];
  1574. }
  1575. $rel = [];
  1576. foreach ($lists as $v1) {
  1577. if(isset($v1[$foreignKey])) {
  1578. $rel[] = $v1[$foreignKey];
  1579. }
  1580. }
  1581. if(count($rel) == 0) {
  1582. return;
  1583. }
  1584. // [rel key, where]
  1585. $params = [
  1586. $associationForeignkey,
  1587. [$associationForeignkey . ':in' => array_unique($rel)],
  1588. $fields
  1589. ];
  1590. $res = call_user_func_array(array($callable, $method), $params);
  1591. foreach ($lists as &$v) {
  1592. if(isset($res[$v[$foreignKey]])) {
  1593. $v[$relField] = $res[$v[$foreignKey]];
  1594. }
  1595. }
  1596. }
  1597. }
  1598. /**
  1599. * 关联查询 has one
  1600. * params[rel_key, where, fields]
  1601. *
  1602. * @return array
  1603. * @throws \Exception
  1604. */
  1605. final public function hasOne() {
  1606. $args = func_get_args();
  1607. $relKey = $args[0];
  1608. $fields = [];
  1609. if(count($args) == 3 && !empty($args[2])) {
  1610. $fields = $args[2];
  1611. if(!in_array($relKey, $fields)) $fields[] = $relKey;
  1612. }
  1613. if(count($fields) == 0) {
  1614. $fields = $this->getFields();
  1615. }
  1616. if(count($this->getFields()) > 0 && !in_array($relKey, $this->getFields())) {
  1617. $fields[] = $relKey;
  1618. }
  1619. $fields = array_unique($fields);
  1620. $query = $this->createQuery($fields);
  1621. $res = $query->where($args[1])->rs($this->prepareTable());
  1622. $rows = [];
  1623. foreach($res as $v) {
  1624. $rows[$v[$relKey]] = $v;
  1625. }
  1626. return $rows;
  1627. }
  1628. /**
  1629. * 关联查询
  1630. * params[rel_key, where, fields]
  1631. *
  1632. * @return array
  1633. * @throws \Exception
  1634. */
  1635. final public function hasMany()
  1636. {
  1637. $args = func_get_args();
  1638. $relKey = $args[0];
  1639. $fields = [];
  1640. if(count($args) == 3 && !empty($args[2])) {
  1641. $fields = $args[2];
  1642. if(!in_array($relKey, $fields)) $fields[] = $relKey;
  1643. }
  1644. if(count($fields) == 0) {
  1645. $fields = $this->getFields();
  1646. }
  1647. if(count($this->getFields()) > 0 && !in_array($relKey, $this->getFields())) {
  1648. $fields[] = $relKey;
  1649. }
  1650. if(array_search('*', $fields) !== false) {
  1651. $fields = ['*'];
  1652. }
  1653. $query = $this->createQuery($fields);
  1654. $res = $query->where($args[1])->rs($this->prepareTable());
  1655. $rows = [];
  1656. foreach($res as $v) {
  1657. $rows[$v[$relKey]][] = $v;
  1658. }
  1659. return $rows;
  1660. }
  1661. /**
  1662. * 获取所有数据,这里不分页,但支持限条数,通过 setLimitHooker来实现
  1663. * $this->setLimitHooker(function(){
  1664. * return [x,y];//从第x条开始获取y条; return [1];//获取一条 return [0];//获取所有的
  1665. * });
  1666. * @return mixed
  1667. * @throws \Exception
  1668. */
  1669. final public function listAll() {
  1670. $limit = $this->getLimitHooker();
  1671. $query = $this->createQuery()->groupBy($this->getGroupBy())->orderBy($this->getOrderBy());
  1672. if(empty($limit) || !is_array($limit)) {
  1673. $list = $query
  1674. ->selectRows($this->prepareTable());
  1675. $this->withList($list);
  1676. return $list;
  1677. }
  1678. if(count($limit) == 1) {
  1679. $list = $query->limit($limit[0])->selectRows($this->prepareTable());
  1680. $this->withList($list);
  1681. return $list;
  1682. }
  1683. $list = $query
  1684. ->limit($limit[0], $limit[1])->selectRows($this->prepareTable());
  1685. $this->withList($list);
  1686. return $list;
  1687. }
  1688. /**
  1689. * 验证相关字段
  1690. *
  1691. * @param array $fields 字段列表
  1692. * @return Response
  1693. */
  1694. final public function valid($fields = array()) {
  1695. if(!is_array($fields)) {
  1696. return Response::FailValidate(static::class .'::'. __FUNCTION__,
  1697. [
  1698. '_result' => ['code' => Response::FAIL_FOR_VALIDATE, 'msg' => '字段必须是数组', 'fields' => []],
  1699. 'message' => '字段必须是数组'
  1700. ]
  1701. );
  1702. }
  1703. $rules = $this->rules();
  1704. $result = [];
  1705. $invalidKey = [];
  1706. $values = array_merge($this->getDefaultValue(), $this->properties());
  1707. foreach ($rules as $valid => $rule) {
  1708. foreach ($rule as $val) {
  1709. $key = $this->entity()->convertToProperty($val[0]);
  1710. if(!in_array($key, $fields)) {
  1711. continue;
  1712. }
  1713. $field = $this->entity()->convertToField($key);
  1714. $verify = new Verify($val[0], $values[$field] ?? null, strtolower($valid), $val[1], $val[2] ?? '');
  1715. $res = $verify->valid();
  1716. if($res->isError()) {
  1717. $result[] = $res->getResult() .',获取的是'. ($values[$field] ?? '空');
  1718. if(!in_array($field, $invalidKey)) {
  1719. $invalidKey[] = $field;
  1720. }
  1721. }
  1722. }
  1723. }
  1724. if(count($result) > 0) {
  1725. return Response::FailValidate(static::class .'::'. __FUNCTION__,
  1726. [
  1727. '_result' => ['code' => Response::FAIL_FOR_VALIDATE, 'msg' => $result, 'fields' => $invalidKey],
  1728. 'message' => join("\n", $result)
  1729. ]
  1730. );
  1731. }
  1732. return Response::Success(static::class .'::'. __FUNCTION__, ['_result' => true]);
  1733. }
  1734. /**
  1735. * 合并多个 valid 结果 $this->valids($this->valid(['Uid']), $this->valid(['Nickname', 'Email']));
  1736. * @param ...
  1737. * @return mixed|Response
  1738. * @throws \Exception
  1739. */
  1740. final public function valids() {
  1741. $validArr = func_get_args();
  1742. if(count($validArr) == 0) {
  1743. return Response::Success(static::class .'::'. __FUNCTION__, ['_result' => true]);
  1744. }
  1745. if(count($validArr) == 1) {
  1746. return $validArr[0];
  1747. }
  1748. $invalid = array();
  1749. $invalid['message'] = array();
  1750. $invalid['fields'] = array();
  1751. foreach ($validArr as $valid) {
  1752. if(!($valid instanceof Response)) {
  1753. throw new \Exception('验证结果类型必须是\Qii\Driver\Response类型');
  1754. }
  1755. if($valid->isError()) {
  1756. $result = $valid->getResult();
  1757. $invalid['message'] = array_merge($invalid['message'], $result['message']);
  1758. $invalid['fields'] = array_merge($invalid['fields'], $result['fields']);;
  1759. }
  1760. }
  1761. if(count($invalid['message']) > 0) {
  1762. return Response::Fail(static::class .'::'. __FUNCTION__, [
  1763. '_result' => ['message' => $invalid['message'], 'fields' => $invalid['fields']],
  1764. 'message' => $invalid['message']
  1765. ]);
  1766. }
  1767. return Response::Success(static::class .'::'. __FUNCTION__, ['_result' => true]);
  1768. }
  1769. /**
  1770. * unique 条件
  1771. *
  1772. * @return array[]
  1773. * @throws \Exception
  1774. */
  1775. protected function uniqueCondition() {
  1776. $unique = $this->uniqueKey();
  1777. if(!is_array($unique)) {
  1778. if(strpos($unique, ',') !== false) {
  1779. $unique = explode(',', $unique);
  1780. }else{
  1781. $unique = array($unique);
  1782. }
  1783. }
  1784. $where = ['and' => [], 'or' => []];
  1785. $a1 = array_reduce($unique, function ($where, $item){
  1786. if(strpos($item, ',') !== false) {
  1787. $item = explode(',', $item);
  1788. foreach($item as $k){
  1789. $key = $this->entity()->convertToField($k);
  1790. $property = $this->entity()->convertToProperty($k);
  1791. $where['and'][$key] = $this->$property;
  1792. }
  1793. }else{
  1794. $key = $this->entity()->convertToField($item);
  1795. $property = $this->entity()->convertToProperty($item);
  1796. $where['or'][$key] = $this->$property;
  1797. $where['or'][] = 'or';
  1798. }
  1799. return $where;
  1800. }, $where);
  1801. //弹出or的最后一个or操作符
  1802. array_pop($a1['or']);
  1803. return [$a1['and'], $a1['or']];
  1804. }
  1805. /**
  1806. * exclude Condition
  1807. *
  1808. * @return array
  1809. */
  1810. protected function excludeCondition() {
  1811. $exclude = $this->exclude();
  1812. if(!$exclude) {
  1813. $exclude = $this->primaryKey();
  1814. }
  1815. if(!is_array($exclude)) {
  1816. $exclude = (array) $this->explode(',', $exclude);
  1817. }
  1818. $excludeCondition = [];
  1819. foreach ($exclude as $key) {
  1820. $field = $this->entity()->convertToField($key);
  1821. $property = $this->entity()->convertToProperty($key);
  1822. $excludeCondition[$field] = $this->$property;
  1823. }
  1824. return $excludeCondition;
  1825. }
  1826. /**
  1827. * 主键
  1828. *
  1829. * @return array
  1830. * @throws \Exception
  1831. */
  1832. protected function primaryCondition(){
  1833. $primary = array();
  1834. $primaryKey = $this->primaryKey();
  1835. if(!is_array($primaryKey)) {
  1836. $primaryKey = $this->explode(',', $primaryKey);
  1837. }
  1838. foreach ($primaryKey as $key) {
  1839. $key = $this->entity()->convertToProperty($key);
  1840. $field = $this->entity()->convertToField($key);
  1841. $value = $this->$key;
  1842. $primary[$field] = $value;
  1843. }
  1844. return $primary;
  1845. }
  1846. /**
  1847. * 获取查询条件
  1848. *
  1849. * @return array [$uniqueWhere, $uniqueOr, $excludeCondition, $primaryCondition]
  1850. */
  1851. public function condition() {
  1852. //如果设置了 unique 就先验证唯一性,保存的时候验证 uniqueKey,更新的时候验证uniqueKey并排primaryKey
  1853. //保存数据的时候验证uniqueKey;更新时验证 uniqueKey,并且排除 primaryKey,如果uniqueKey == primaryKey则不去做唯一性验证
  1854. list($uniqueWhere, $uniqueOr) = $this->uniqueCondition();
  1855. $excludeCondition = $this->excludeCondition();
  1856. $primaryCondition = $this->primaryCondition();
  1857. return [$uniqueWhere, $uniqueOr, $excludeCondition, $primaryCondition];
  1858. }
  1859. /**
  1860. * 获取order by
  1861. *
  1862. * @return array
  1863. */
  1864. public function getOrderBy() {
  1865. $order = array();
  1866. $orderBy = $this->orderBy();
  1867. if(isset($this->hooker['order']) && is_callable($this->hooker['order']['func'])) {
  1868. $orderBy = call_user_func($this->hooker['order']['func'], $order, $this->hooker['order']['args']);
  1869. }
  1870. foreach ($orderBy as $key => $val) {
  1871. $field = $this->entity()->convertToField($key);
  1872. if($this->alias != "" && strpos($field, '.') === false) {
  1873. $field = $this->alias . '.' . $field;
  1874. }
  1875. $val = strtoupper($val);
  1876. if(!in_array($val, array('DESC', 'ASC'))) {
  1877. continue;
  1878. }
  1879. $order[$field] = $val;
  1880. }
  1881. return $order;
  1882. }
  1883. /**
  1884. * 初始化page
  1885. * @param array $data 返回的数据
  1886. * @param int $count 总数量
  1887. * @param int $page 页码
  1888. * @param int $pageSize 显示数量
  1889. * @param int $pagination 分页显示最多页码
  1890. * @return bool
  1891. */
  1892. public function initPages(&$data, $count, $page, $pageSize = 20, $pagination = 5) {
  1893. $page = intval(max(1, $page));
  1894. $pageSize = intval(max(1, $pageSize));
  1895. $data['start'] = 0;
  1896. $data['pages'] = array('total' => 0, 'currentPage' => 0, 'totalPage' => 0);
  1897. $data['pages']['total'] = (int) ($count ? $count : 0);
  1898. $data['pages']['currentPage'] = $page;
  1899. $data['pages']['totalPage'] = ceil($data['pages']['total'] / $pageSize);
  1900. $data['lists'] = isset($data['lists']) ? $data['lists'] : array();
  1901. if ($data['pages']['currentPage'] > $data['pages']['totalPage']) {
  1902. return false;
  1903. }
  1904. $pagination = min($pagination, $data['pages']['totalPage']);
  1905. if($data['pages']['currentPage'] - floor($pagination / 2) <= 0) {
  1906. $frames['left'] = 1;
  1907. $frames['right'] = $frames['left'] + $pagination - 1;
  1908. } else if($data['pages']['currentPage'] + floor($pagination / 2) >= $data['pages']['totalPage']) {
  1909. $frames['right'] = $data['pages']['totalPage'];
  1910. $frames['left'] = $frames['right'] - $pagination + 1;
  1911. } else {
  1912. $frames['left'] = $data['pages']['currentPage'] - floor($pagination / 2);
  1913. $frames['right'] = $data['pages']['currentPage'] + ceil($pagination / 2) - 1;
  1914. }
  1915. $data['start'] = $frames['left'];
  1916. $data['pages']['start'] = $data['start'];
  1917. $data['pages']['end'] = $frames['right'];
  1918. $data['pages']['pagination'] = $pagination;
  1919. $data['pages']['limitStart'] = (min($page, $data['pages']['totalPage']) - 1) * $pageSize;
  1920. $data['pages']['pageSize'] = (int) $pageSize;
  1921. return true;
  1922. }
  1923. /**
  1924. * response as object
  1925. *
  1926. * @return mixed|Response
  1927. */
  1928. final public function response() {
  1929. $properties = $this->properties();
  1930. if(!$properties) {
  1931. return Response::Fail(static::class .'::'. __FUNCTION__,
  1932. ['_result' => ['code' => Response::FAIL_FOR_SELECT, 'msg' => '未找到相关数据', 'body' => []]
  1933. ]
  1934. );
  1935. }
  1936. return Response::Success(static::class .'::'. __FUNCTION__,
  1937. ['_result' => ['code' => Response::DO_SUCCESS, 'msg' => '获取成功', 'body' => $properties]]
  1938. );
  1939. }
  1940. /**
  1941. * 方法名 + ByCache/ByRedis/ByMemcache/会将结果缓存,这里使用的缓存类是通过hooker设置的,否则使用对应的
  1942. * ByClean 则会移除当前缓存, 默认转发到 db model上
  1943. * @param string $method method
  1944. * @param array $args
  1945. * @return mixed
  1946. */
  1947. public function __call($method, $args) {
  1948. $cache = '';
  1949. preg_match("/(byredis|bymemcache|bycache|byclean)$/i", $method, $matches);
  1950. if($matches && count($matches) > 0) {
  1951. $cache = strtolower($matches[0]);
  1952. }
  1953. if($cache && in_array($cache, ['bymemcache', 'byredis', 'bycache', 'byclean'])){
  1954. list($func, $cacheID, $config) = $this->getCacheHooker();
  1955. $policy = $this->getCacheConfig();
  1956. if($func == null) {
  1957. $func = $cache == 'bymemcache' ? $this->db()->setCache('memcached', $policy) : $this->db()->setCache('redis', $policy);
  1958. }
  1959. $method = substr($method, 0, strlen($cache) * -1);
  1960. if (method_exists($this, $method)) {
  1961. if($cacheID != '') {
  1962. $key = $cacheID;
  1963. }else{
  1964. $key = get_called_class() .':'. $method .':'. substr(md5(serialize($this->properties())), -16);
  1965. }
  1966. if($cache == 'byclean') {
  1967. return $func->del($key);
  1968. }
  1969. if(is_object($func) && method_exists($func, 'get')) {
  1970. $res = $func->get($key);
  1971. if ($res) {
  1972. return unserialize($res);
  1973. }
  1974. }
  1975. $expiredAt = isset($config['life_time']) ? (int) $config['life_time'] :
  1976. ($policy['life_time'] ?? $this->defaultExpired);
  1977. $res = call_user_func_array(array($this, $method), $args);
  1978. $str = serialize($res);
  1979. $func->set($key, $str, ['life_time' => $expiredAt]);
  1980. return $res;
  1981. }
  1982. }
  1983. return call_user_func_array(array($this->db(), $method), $args);
  1984. }
  1985. /**
  1986. * 开始事务
  1987. *
  1988. * @return mixed
  1989. */
  1990. final public function startTrans() {
  1991. return $this->db()->transaction();
  1992. }
  1993. /**
  1994. * 提交事务
  1995. *
  1996. * @return mixed
  1997. */
  1998. final public function commit() {
  1999. return $this->db()->commit();
  2000. }
  2001. /**
  2002. * 回退
  2003. *
  2004. * @return mixed
  2005. */
  2006. final public function rollback() {
  2007. return $this->db()->rollback();
  2008. }
  2009. /**
  2010. * 验证规则,由子类继承去修改
  2011. *
  2012. * @return array
  2013. */
  2014. public function rules()
  2015. {
  2016. return [];
  2017. }
  2018. }