Functions.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of Hyperf.
  5. *
  6. * @link https://www.hyperf.io
  7. * @document https://hyperf.wiki
  8. * @contact group@hyperf.io
  9. * @license https://github.com/hyperf/hyperf/blob/master/LICENSE
  10. */
  11. namespace Hyperf\Collection;
  12. use Closure;
  13. /**
  14. * Create a collection from the given value.
  15. *
  16. * @template TKey of array-key
  17. * @template TValue
  18. *
  19. * @param null|\Hyperf\Contract\Arrayable<TKey, TValue>|iterable<TKey, TValue> $value
  20. * @return Collection<TKey, TValue>
  21. */
  22. function collect($value = []): Collection
  23. {
  24. return new Collection($value);
  25. }
  26. /**
  27. * Fill in data where it's missing.
  28. *
  29. * @param mixed $target
  30. * @param array|string $key
  31. * @param mixed $value
  32. * @return mixed
  33. */
  34. function data_fill(&$target, $key, $value)
  35. {
  36. return data_set($target, $key, $value, false);
  37. }
  38. /**
  39. * Get an item from an array or object using "dot" notation.
  40. *
  41. * @param mixed $target
  42. * @param null|array|int|string $key
  43. * @param mixed $default
  44. * @return mixed
  45. */
  46. function data_get($target, $key, $default = null)
  47. {
  48. if (is_null($key)) {
  49. return $target;
  50. }
  51. $key = is_array($key) ? $key : explode('.', $key);
  52. foreach ($key as $i => $segment) {
  53. unset($key[$i]);
  54. if (is_null($segment)) {
  55. return $target;
  56. }
  57. if ($segment === '*') {
  58. if ($target instanceof Collection) {
  59. $target = $target->all();
  60. } elseif (! is_iterable($target)) {
  61. return value($default);
  62. }
  63. $result = [];
  64. foreach ($target as $item) {
  65. $result[] = data_get($item, $key);
  66. }
  67. return in_array('*', $key) ? Arr::collapse($result) : $result;
  68. }
  69. if (Arr::accessible($target) && Arr::exists($target, $segment)) {
  70. $target = $target[$segment];
  71. } elseif (is_object($target) && isset($target->{$segment})) {
  72. $target = $target->{$segment};
  73. } else {
  74. return value($default);
  75. }
  76. }
  77. return $target;
  78. }
  79. /**
  80. * Set an item on an array or object using dot notation.
  81. *
  82. * @param mixed $target
  83. * @param array|string $key
  84. * @param mixed $value
  85. * @param bool $overwrite
  86. * @return mixed
  87. */
  88. function data_set(&$target, $key, $value, $overwrite = true)
  89. {
  90. $segments = is_array($key) ? $key : explode('.', $key);
  91. if (($segment = array_shift($segments)) === '*') {
  92. if (! Arr::accessible($target)) {
  93. $target = [];
  94. }
  95. if ($segments) {
  96. foreach ($target as &$inner) {
  97. data_set($inner, $segments, $value, $overwrite);
  98. }
  99. } elseif ($overwrite) {
  100. foreach ($target as &$inner) {
  101. $inner = $value;
  102. }
  103. }
  104. } elseif (Arr::accessible($target)) {
  105. if ($segments) {
  106. if (! Arr::exists($target, $segment)) {
  107. $target[$segment] = [];
  108. }
  109. data_set($target[$segment], $segments, $value, $overwrite);
  110. } elseif ($overwrite || ! Arr::exists($target, $segment)) {
  111. $target[$segment] = $value;
  112. }
  113. } elseif (is_object($target)) {
  114. if ($segments) {
  115. if (! isset($target->{$segment})) {
  116. $target->{$segment} = [];
  117. }
  118. data_set($target->{$segment}, $segments, $value, $overwrite);
  119. } elseif ($overwrite || ! isset($target->{$segment})) {
  120. $target->{$segment} = $value;
  121. }
  122. } else {
  123. $target = [];
  124. if ($segments) {
  125. /* @phpstan-ignore-next-line */
  126. data_set($target[$segment], $segments, $value, $overwrite);
  127. } elseif ($overwrite) {
  128. $target[$segment] = $value;
  129. }
  130. }
  131. return $target;
  132. }
  133. if (! function_exists('data_forget')) {
  134. /**
  135. * Remove / unset an item from an array or object using "dot" notation.
  136. *
  137. * @param mixed $target
  138. * @param null|array|int|string $key
  139. * @return mixed
  140. */
  141. function data_forget(&$target, $key)
  142. {
  143. $segments = is_array($key) ? $key : explode('.', $key);
  144. if (($segment = array_shift($segments)) === '*' && Arr::accessible($target)) {
  145. if ($segments) {
  146. foreach ($target as &$inner) {
  147. data_forget($inner, $segments);
  148. }
  149. }
  150. } elseif (Arr::accessible($target)) {
  151. if ($segments && Arr::exists($target, $segment)) {
  152. data_forget($target[$segment], $segments);
  153. } else {
  154. Arr::forget($target, $segment);
  155. }
  156. } elseif (is_object($target)) {
  157. if ($segments && isset($target->{$segment})) {
  158. data_forget($target->{$segment}, $segments);
  159. } elseif (isset($target->{$segment})) {
  160. unset($target->{$segment});
  161. }
  162. }
  163. return $target;
  164. }
  165. }
  166. /**
  167. * Get the first element of an array. Useful for method chaining.
  168. *
  169. * @param array $array
  170. * @return mixed
  171. */
  172. function head($array)
  173. {
  174. return reset($array);
  175. }
  176. /**
  177. * Get the last element from an array.
  178. *
  179. * @param array $array
  180. * @return mixed
  181. */
  182. function last($array)
  183. {
  184. return end($array);
  185. }
  186. /**
  187. * Return the default value of the given value.
  188. *
  189. * @param mixed ...$args
  190. * @return mixed
  191. */
  192. function value(mixed $value, ...$args)
  193. {
  194. return $value instanceof Closure ? $value(...$args) : $value;
  195. }