ArrayHelper.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. <?php
  2. namespace common\helpers;
  3. use yii\helpers\BaseArrayHelper;
  4. use yii\helpers\Json;
  5. /**
  6. * Class ArrayHelper
  7. * @package common\helpers
  8. * @author jianyan74 <751393839@qq.com>
  9. */
  10. class ArrayHelper extends BaseArrayHelper
  11. {
  12. /**
  13. * 递归数组
  14. *
  15. * @param array $items
  16. * @param string $idField
  17. * @param int $pid
  18. * @param string $pidField
  19. * @return array
  20. */
  21. public static function itemsMerge(array $items, $pid = 0, $idField = "id", $pidField = 'pid', $child = '-')
  22. {
  23. $map = [];
  24. $tree = [];
  25. foreach ($items as &$it) {
  26. $it[$child] = [];
  27. $map[$it[$idField]] = &$it;
  28. }
  29. foreach ($items as &$it) {
  30. $parent = &$map[$it[$pidField]];
  31. if ($parent) {
  32. $parent[$child][] = &$it;
  33. } else {
  34. $pid == $it[$pidField] && $tree[] = &$it;
  35. }
  36. }
  37. unset($items, $map);
  38. return $tree;
  39. }
  40. /**
  41. * 传递一个子分类ID返回所有的父级分类
  42. *
  43. * @param array $items
  44. * @param $id
  45. * @return array
  46. */
  47. public static function getParents(array $items, $id)
  48. {
  49. $arr = [];
  50. foreach ($items as $v) {
  51. if ($v['id'] == $id) {
  52. $arr[] = $v;
  53. $arr = array_merge(self::getParents($items, $v['pid']), $arr);
  54. }
  55. }
  56. return $arr;
  57. }
  58. /**
  59. * 传递一个父级分类ID返回所有子分类
  60. *
  61. * @param $cate
  62. * @param int $pid
  63. * @return array
  64. */
  65. public static function getChilds($cate, $pid)
  66. {
  67. $arr = [];
  68. foreach ($cate as $v) {
  69. if ($v['pid'] == $pid) {
  70. $arr[] = $v;
  71. $arr = array_merge($arr, self::getChilds($cate, $v['id']));
  72. }
  73. }
  74. return $arr;
  75. }
  76. /**
  77. * 传递一个父级分类ID返回所有子分类ID
  78. *
  79. * @param $cate
  80. * @param $pid
  81. * @param string $idField
  82. * @param string $pidField
  83. * @return array
  84. */
  85. public static function getChildIds($cate, $pid, $idField = "id", $pidField = 'pid')
  86. {
  87. $arr = [];
  88. foreach ($cate as $v) {
  89. if ($v[$pidField] == $pid) {
  90. $arr[] = $v[$idField];
  91. $arr = array_merge($arr, self::getChildIds($cate, $v[$idField], $idField, $pidField));
  92. }
  93. }
  94. return $arr;
  95. }
  96. /**
  97. * php二维数组排序 按照指定的key 对数组进行排序
  98. *
  99. * @param array $arr 将要排序的数组
  100. * @param string $keys 指定排序的key
  101. * @param string $type 排序类型 asc | desc
  102. * @return array
  103. */
  104. public static function arraySort($arr, $keys, $type = 'asc')
  105. {
  106. if (count($arr) <= 1) {
  107. return $arr;
  108. }
  109. $keysValue = [];
  110. $newArray = [];
  111. foreach ($arr as $k => $v) {
  112. $keysValue[$k] = $v[$keys];
  113. }
  114. $type == 'asc' ? asort($keysValue) : arsort($keysValue);
  115. reset($keysValue);
  116. foreach ($keysValue as $k => $v) {
  117. $newArray[$k] = $arr[$k];
  118. }
  119. return $newArray;
  120. }
  121. /**
  122. * 获取数组指定的字段为key
  123. *
  124. * @param array $arr 数组
  125. * @param string $field 要成为key的字段名
  126. * @return array
  127. */
  128. public static function arrayKey($arr, $field)
  129. {
  130. $newArray = [];
  131. if (empty($arr)) {
  132. return $newArray;
  133. }
  134. foreach ($arr as $value) {
  135. isset($value[$field]) && $newArray[$value[$field]] = $value;
  136. }
  137. return $newArray;
  138. }
  139. /**
  140. * 移除数组内某个key的值为传递的值
  141. *
  142. * @param array $array
  143. * @param $value
  144. * @param string $key
  145. * @return array
  146. */
  147. public static function removeByValue(array $array, $value, $key = 'id')
  148. {
  149. foreach ($array as $index => $item) {
  150. if (isset($item[$key]) && $item[$key] == $value) {
  151. unset($array[$index]);
  152. }
  153. }
  154. return $array;
  155. }
  156. /**
  157. * 获取数字区间
  158. *
  159. * @param int $start
  160. * @param int $end
  161. * @return array
  162. */
  163. public static function numBetween($start = 0, $end = 1, $key = true, $step_number = 1, $suffix = '')
  164. {
  165. $arr = [];
  166. for ($i = $start; $i <= $end; $i = $i + $step_number) {
  167. $value = $i . $suffix;
  168. $key == true ? $arr[$i] = $value : $arr[] = $value;
  169. }
  170. return $arr;
  171. }
  172. /**
  173. * 根据级别和数组返回字符串
  174. *
  175. * @param int $level 级别
  176. * @param array $models
  177. * @param $k
  178. * @param int $treeStat 开始计算
  179. * @return bool|string
  180. */
  181. public static function itemsLevel($level, array $models, $k, $treeStat = 1)
  182. {
  183. $str = '';
  184. for ($i = 1; $i < $level; $i++) {
  185. $str .= '  ';
  186. if ($i == $level - $treeStat) {
  187. if (isset($models[$k + 1])) {
  188. return $str . "├──";
  189. }
  190. return $str . "└──";
  191. }
  192. }
  193. return false;
  194. }
  195. /**
  196. * 必须经过递归才能进行重组为下拉框
  197. *
  198. * @param $models
  199. * @param string $idField
  200. * @param string $titleField
  201. * @param int $treeStat
  202. * @return array
  203. */
  204. public static function itemsMergeDropDown($models, $idField = 'id', $titleField = 'title', $treeStat = 1)
  205. {
  206. $arr = [];
  207. foreach ($models as $k => $model) {
  208. $arr[] = [
  209. $idField => $model[$idField],
  210. $titleField => self::itemsLevel($model['level'], $models, $k, $treeStat) . " " . $model[$titleField],
  211. ];
  212. if (!empty($model['-'])) {
  213. $arr = ArrayHelper::merge($arr, self::itemsMergeDropDown($model['-'], $idField, $titleField, $treeStat));
  214. }
  215. }
  216. return $arr;
  217. }
  218. /**
  219. * 获取配送时间
  220. *
  221. * @param $data
  222. * distribution_time 自提时间
  223. * interval_time 自提间隔时间
  224. * make_day 可预约天数
  225. * @return array
  226. */
  227. public static function distributionTime($data, $isDistribution = true)
  228. {
  229. $data = self::toArray($data);
  230. if (empty($data)) {
  231. return [];
  232. }
  233. // 今日可配送时间
  234. $todayTime = [];
  235. // 配送时间
  236. $distributionTime = $data['distribution_time'] ?? [];
  237. $intervalTime = $data['interval_time'] ?? 0;
  238. $makeDay = $data['make_day'] ?? 0;
  239. // 用户只能选择多少时间后的上门时间
  240. $intervalTime = time() + $intervalTime - strtotime(date('Y-m-d'));
  241. foreach ($distributionTime as &$param) {
  242. if ($intervalTime < $param['end_time']) {
  243. // 默认选择
  244. if (empty($todayTime)) {
  245. $explain = $isDistribution ? '尽快送达(' . DateHelper::formatHoursByInt($param['end_time']) . '前)' : DateHelper::formatHoursByInt($param['end_time']) . '前';
  246. $todayTime[] = [
  247. 'start_time' => $param['start_time'],
  248. 'end_time' => $param['end_time'],
  249. 'explain' => $explain
  250. ];
  251. }
  252. $explain = DateHelper::formatHoursByInt($param['start_time']) . '-' . DateHelper::formatHoursByInt($param['end_time']);
  253. $todayTime[] = [
  254. 'start_time' => $param['start_time'],
  255. 'end_time' => $param['end_time'],
  256. 'explain' => $explain
  257. ];
  258. }
  259. $param['explain'] = DateHelper::formatHoursByInt($param['start_time']) . '-' . DateHelper::formatHoursByInt($param['end_time']);
  260. }
  261. // 配送天数
  262. $config = [];
  263. for ($i = 0; $i < $makeDay; $i++) {
  264. $dateTime = strtotime(date('Y-m-d')) + $i * 3600 * 24;
  265. if ($i == 0) {
  266. if (!empty($todayTime)) {
  267. $config[] = [
  268. 'day' => date('m', $dateTime) . '月' . date('d', $dateTime) . '日',
  269. 'time' => $todayTime,
  270. 'daytime' => $dateTime,
  271. ];
  272. }
  273. } else {
  274. $config[] = [
  275. 'day' => date('m', $dateTime) . '月' . date('d', $dateTime) . '日',
  276. 'time' => $distributionTime,
  277. 'daytime' => $dateTime,
  278. ];
  279. }
  280. }
  281. return $config;
  282. }
  283. /**
  284. * 匹配ip在ip数组内支持通配符
  285. *
  286. * @param $ip
  287. * @param $allowedIPs
  288. * @return bool
  289. */
  290. public static function ipInArray($ip, $allowedIPs)
  291. {
  292. foreach ($allowedIPs as $filter) {
  293. if ($filter === '*' || $filter === $ip || (($pos = strpos($filter, '*')) !== false && !strncmp($ip, $filter, $pos))) {
  294. return true;
  295. }
  296. }
  297. return false;
  298. }
  299. /**
  300. * @param string $content 内容
  301. * @param array $data 字段替换数组
  302. */
  303. public static function recursionGetVal($content, $data = [], $start = '{', $end = '}')
  304. {
  305. $data = self::toArray($data);
  306. $keywords = StringHelper::matchStr($content, $start, $end);
  307. foreach ($keywords as $keyword) {
  308. $fields = explode('.', $keyword);
  309. $content = StringHelper::replace($start . $keyword . $end, ArrayHelper::getFieldData($fields, $data), $content);
  310. }
  311. return $content;
  312. }
  313. /**
  314. * 递归获取字段
  315. *
  316. * @param array $fields
  317. * @param $data
  318. * @param string $row
  319. * @return string
  320. */
  321. public static function getFieldData(array $fields, $data)
  322. {
  323. if (empty($data) || empty($fields)) {
  324. return '';
  325. }
  326. foreach ($fields as $key => $field) {
  327. if (isset($data[$field])) {
  328. $data = $data[$field];
  329. unset($fields[$key]);
  330. if (!empty($fields)) {
  331. return self::getFieldData($fields, $data);
  332. }
  333. }
  334. unset($field);
  335. }
  336. return is_array($data) ? '' : $data;
  337. }
  338. /**
  339. * 对比2组id,返回存在的id和被删除的id
  340. *
  341. * @param array $oldIds
  342. * @param array $newIds
  343. * @return array
  344. */
  345. public static function comparisonIds(array $oldIds, array $newIds)
  346. {
  347. $updatedIds = $deleteIds = [];
  348. foreach ($oldIds as $oldId) {
  349. if (in_array($oldId, $newIds)) {
  350. $updatedIds[] = $oldId;
  351. } else {
  352. $deleteIds[] = $oldId;
  353. }
  354. }
  355. return [$updatedIds, $deleteIds];
  356. }
  357. /**
  358. * 获取递归的第一个没有子级的数据
  359. *
  360. * @param $array
  361. * @return mixed
  362. */
  363. public static function getFirstRowByItemsMerge(array $array)
  364. {
  365. foreach ($array as $item) {
  366. if (!empty($item['-'])) {
  367. return self::getFirstRowByItemsMerge($item['-']);
  368. } else {
  369. return $item;
  370. }
  371. }
  372. return false;
  373. }
  374. /**
  375. * 获取所有没有子级的数据
  376. *
  377. * @param $array
  378. * @return mixed
  379. */
  380. public static function getNotChildRowsByItemsMerge(array $array)
  381. {
  382. $arr = [];
  383. foreach ($array as $item) {
  384. if (!empty($item['-'])) {
  385. $arr = array_merge($arr, self::getNotChildRowsByItemsMerge($item['-']));
  386. } else {
  387. $arr[] = $item;
  388. }
  389. }
  390. return $arr;
  391. }
  392. /**
  393. * 递归转普通二维数组
  394. *
  395. * @param $array
  396. * @return mixed
  397. */
  398. public static function getRowsByItemsMerge(array $array, $childField = '-')
  399. {
  400. $arr = [];
  401. foreach ($array as $item) {
  402. if (!empty($item[$childField])) {
  403. $arr = array_merge($arr, self::getRowsByItemsMerge($item[$childField]));
  404. }
  405. unset($item[$childField]);
  406. $arr[] = $item;
  407. }
  408. return $arr;
  409. }
  410. /**
  411. * 重组 map 类型转为正常的数组
  412. *
  413. * @param array $array
  414. * @param string $keyForField
  415. * @param string $valueForField
  416. * @return array
  417. */
  418. public static function regroupMapToArr($array = [], $keyForField = 'name', $valueForField = 'title')
  419. {
  420. $arr = [];
  421. foreach ($array as $key => $item) {
  422. if (!is_array($array[$key])) {
  423. $arr[] = [
  424. $keyForField => $key,
  425. $valueForField => $item,
  426. ];
  427. } else {
  428. $arr[] = $item;
  429. }
  430. }
  431. return $arr;
  432. }
  433. /**
  434. * 统计数组字段合计
  435. *
  436. * @param array $fields
  437. * @param array $data
  438. * @return array
  439. */
  440. public static function sumFieldData(array $fields, $data)
  441. {
  442. $data = self::toArray($data);
  443. $array = [];
  444. foreach ($fields as $field) {
  445. $array[$field] = 0;
  446. }
  447. foreach ($data as $datum) {
  448. foreach ($fields as $field) {
  449. isset($datum[$field]) && $array[$field] = BcHelper::add($array[$field], $datum[$field]);
  450. }
  451. }
  452. return $array;
  453. }
  454. /**
  455. * 数组内某字段转数组
  456. *
  457. * @param array $data
  458. * @param string $field
  459. * @return array
  460. */
  461. public static function fieldToArray(array $data, $field = 'covers')
  462. {
  463. foreach ($data as &$datum) {
  464. if (empty($datum[$field])) {
  465. $datum[$field] = [];
  466. }
  467. if (!is_array($datum[$field])) {
  468. $datum[$field] = Json::decode($datum[$field]);
  469. }
  470. }
  471. return $data;
  472. }
  473. /**
  474. * 数组转xml
  475. *
  476. *
  477. * @param $arr
  478. * 微信回调成功:['return_code' => 'SUCCESS', 'return_msg' => 'OK']
  479. * 微信回调失败:['return_code' => 'FAIL', 'return_msg' => 'OK']
  480. * @return bool|string
  481. */
  482. public static function toXml($arr)
  483. {
  484. if (!is_array($arr) || count($arr) <= 0) {
  485. return false;
  486. }
  487. $xml = "<xml>";
  488. foreach ($arr as $key => $val) {
  489. if (is_numeric($val)) {
  490. $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
  491. } else {
  492. $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
  493. }
  494. }
  495. $xml .= "</xml>";
  496. return $xml;
  497. }
  498. }
粤ICP备19079148号