1 | <?php |
||||
2 | |||||
3 | namespace ierusalim\Random; |
||||
4 | |||||
5 | /** |
||||
6 | * This class RandomArray is intended for generating Random Arrays |
||||
7 | * |
||||
8 | * PHP Version 5.6 |
||||
9 | * |
||||
10 | * @package ierusalim\RandomArray |
||||
11 | * @author Alexander Jer <[email protected]> |
||||
12 | * @copyright 2017, Ierusalim |
||||
13 | * @license https://opensource.org/licenses/Apache-2.0 Apache-2.0 |
||||
14 | * |
||||
15 | * Examples of use: |
||||
16 | * Initialize: |
||||
17 | * $g = new RandomArray(); |
||||
18 | * |
||||
19 | * //Generate random array with default parameters: |
||||
20 | * $arr = $g->genRandomArray(); |
||||
21 | * print_r($arr); |
||||
22 | * |
||||
23 | * //Generate random array with string keys from listed chars, 3-9 chars length |
||||
24 | * $g->setKeysModel(3,9,'abcdefghijklmnopqrstuvwxyz'); |
||||
25 | * $g->setValuesModel(0,100); //random numeric values range from 0 to 100 |
||||
26 | * $arr = $g->genRandomArray(10,15,0); //generate 10-15 elements (not nested) |
||||
27 | * print_r($arr); |
||||
28 | * |
||||
29 | */ |
||||
30 | class RandomArray extends RandomStr |
||||
31 | { |
||||
32 | /** |
||||
33 | * Set this limit to avoid generation unexpected too large arrays |
||||
34 | * |
||||
35 | * @var integer |
||||
36 | */ |
||||
37 | public $lim_elements = 10000; |
||||
38 | |||||
39 | /** |
||||
40 | * Model number for generation random Keys for Arrays |
||||
41 | * if 0 then array keys will be simple 1,2,3... numeric |
||||
42 | * if 1 then array keys will be numeric from min_arr_key to max_arr_key |
||||
43 | * if 2 then array keys will be string len from min_arr_key to max_arr_key |
||||
44 | * This value setting by function setKeysModel() |
||||
45 | * |
||||
46 | * @var integer |
||||
47 | */ |
||||
48 | protected $keys_model; |
||||
49 | |||||
50 | /** |
||||
51 | * Model number for generation random Values for Arrays |
||||
52 | * if 0 then array values will be numeric from 0 to 65535 |
||||
53 | * if 1 then array values will be numeric from min_arr_val to max_arr_val |
||||
54 | * if 2 then array values will be string len from min_arr_val to max_arr_val |
||||
55 | * This value setting by function setValuesModel() |
||||
56 | * |
||||
57 | * @var integer |
||||
58 | */ |
||||
59 | protected $values_model; |
||||
60 | |||||
61 | /** |
||||
62 | * Value for generation random Keys for Arrays |
||||
63 | * This is minimal number for random numbers generation, |
||||
64 | * or minimal length of string for random string array-keys generation |
||||
65 | * This value setting by function setValuesModel() |
||||
66 | * |
||||
67 | * @var integer |
||||
68 | */ |
||||
69 | protected $min_arr_key; |
||||
70 | |||||
71 | /** |
||||
72 | * Value for generation random Keys for Arrays |
||||
73 | * This is maximal number for random numbers generation, |
||||
74 | * or maximal length of string for random string array-keys generation |
||||
75 | * This value setting by function setKeysModel() |
||||
76 | * |
||||
77 | * @var integer |
||||
78 | */ |
||||
79 | protected $max_arr_key; |
||||
80 | |||||
81 | /** |
||||
82 | * Value for generation random Values for Arrays |
||||
83 | * This is minimal number for random numbers generation, |
||||
84 | * or minimal length of string for random string array-values generation |
||||
85 | * This value setting by function setValuesModel() |
||||
86 | * |
||||
87 | * @var integer |
||||
88 | */ |
||||
89 | protected $min_arr_val; |
||||
90 | |||||
91 | /** |
||||
92 | * Value for generation random Values for Arrays |
||||
93 | * This is maximal number for random numbers generation, |
||||
94 | * or maximal length of string for random string array-values generation |
||||
95 | * |
||||
96 | * @var integer |
||||
97 | */ |
||||
98 | protected $max_arr_val; |
||||
99 | |||||
100 | /** |
||||
101 | * Value generate function |
||||
102 | * calling if values_model == 3 |
||||
103 | * |
||||
104 | * @var callable |
||||
105 | */ |
||||
106 | public $fn_gen_value; |
||||
107 | |||||
108 | /** |
||||
109 | * Key generate function |
||||
110 | * calling if keys_model == 3 |
||||
111 | * |
||||
112 | * @var callable |
||||
113 | */ |
||||
114 | public $fn_gen_key; |
||||
115 | |||||
116 | /** |
||||
117 | * Init parameter - string of chars for generation array values |
||||
118 | * Prefer to leave blank and use function setValuesModel for set it. |
||||
119 | * |
||||
120 | * @param string|null $init_charset_for_val |
||||
121 | */ |
||||
122 | public function __construct($init_charset_for_val = null, $utf8mode = false) |
||||
123 | { |
||||
124 | parent::__construct($init_charset_for_val, $utf8mode); |
||||
125 | $this->setKeysModel(); |
||||
126 | if (\is_null($init_charset_for_val)) { |
||||
127 | $this->setValuesModel(1, 16, $this->char_sets[0]); |
||||
128 | } else { |
||||
129 | $this->setValuesModel(1, 16, $init_charset_for_val); |
||||
130 | } |
||||
131 | } |
||||
132 | |||||
133 | /** |
||||
134 | * Counting all values in array (recursive) |
||||
135 | * |
||||
136 | * @param array $arr |
||||
137 | * @param integer $cnt |
||||
138 | * |
||||
139 | * @return integer |
||||
140 | */ |
||||
141 | public function countArrayValuesRecursive(&$arr, $cnt = 0) |
||||
142 | { |
||||
143 | \array_walk_recursive($arr, function ($v, $k) use (&$cnt) { |
||||
0 ignored issues
–
show
The parameter
$k is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
144 | $cnt++; |
||||
145 | }); |
||||
146 | return $cnt; |
||||
147 | } |
||||
148 | |||||
149 | /** |
||||
150 | * Counting the maximum depth of nesting of arrays in an array (recursive) |
||||
151 | * |
||||
152 | * @param array $arr |
||||
153 | * @param integer $c_depth |
||||
154 | * |
||||
155 | * @return integer |
||||
156 | */ |
||||
157 | public function countArrayMaxDepth($arr, $c_depth = 0) |
||||
158 | { |
||||
159 | if (!is_array($arr)) { |
||||
0 ignored issues
–
show
|
|||||
160 | return false; |
||||
161 | } |
||||
162 | $m_depth = $c_depth; |
||||
163 | \array_walk($arr, function ($v, $k) use ($c_depth, &$m_depth) { |
||||
0 ignored issues
–
show
The parameter
$k is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
164 | if (is_array($v)) { |
||||
165 | $new_depth = $this->countArrayMaxDepth($v, $c_depth+1); |
||||
166 | if ($new_depth > $m_depth) { |
||||
167 | $m_depth = $new_depth; |
||||
168 | } |
||||
169 | } |
||||
170 | }); |
||||
171 | return $m_depth; |
||||
172 | } |
||||
173 | |||||
174 | /** |
||||
175 | * Set model for generation keys for random arrays |
||||
176 | * |
||||
177 | * @param integer $min |
||||
178 | * @param integer $max |
||||
179 | * @param string|null $chars |
||||
180 | */ |
||||
181 | public function setKeysModel( |
||||
182 | $min = 1, |
||||
183 | $max = null, |
||||
184 | $chars = null, |
||||
185 | $utf8mode = false |
||||
186 | ) { |
||||
187 | if (empty($chars)) { |
||||
188 | //Numeric keys model |
||||
189 | $this->keys_model = 1; |
||||
190 | if ($min == 1 && (\is_null($max))) { |
||||
191 | //Non-changes key model (numeric 0,1,2...) |
||||
192 | $this->keys_model = 0; |
||||
193 | } |
||||
194 | if (\is_null($max)) { |
||||
195 | $max = 65535; |
||||
196 | } |
||||
197 | } else { |
||||
198 | //Random-string keys model |
||||
199 | $this->keys_model = 2; |
||||
200 | //set $chars as charset number 1 |
||||
201 | $this->char_sets[1] = $chars; |
||||
202 | if ($utf8mode) { |
||||
203 | $this->explodeUtf8(); |
||||
204 | } |
||||
205 | } |
||||
206 | $this->min_arr_key = $min; |
||||
207 | $this->max_arr_key = is_null($max) ? 16 : $max; |
||||
208 | } |
||||
209 | |||||
210 | /** |
||||
211 | * Set model for generation values for random arrays |
||||
212 | * |
||||
213 | * @param integer $min |
||||
214 | * @param integer $max |
||||
215 | * @param string|null $chars |
||||
216 | */ |
||||
217 | public function setValuesModel( |
||||
218 | $min = 0, |
||||
219 | $max = 65535, |
||||
220 | $chars = null, |
||||
221 | $utf8mode = false |
||||
222 | ) { |
||||
223 | if (empty($chars)) { |
||||
224 | //Numeric values model |
||||
225 | $this->values_model = 1; |
||||
226 | if (!$min && $max==65535) { |
||||
227 | //Non-changes values model (random number from 0 to 65535) |
||||
228 | $this->values_model=0; |
||||
229 | } |
||||
230 | } else { |
||||
231 | //Random-string values model |
||||
232 | $this->values_model = 2; |
||||
233 | //set $chars as charset number 2 |
||||
234 | $this->char_sets[2] = $chars; |
||||
235 | if ($utf8mode) { |
||||
236 | $this->explodeUtf8(); |
||||
237 | } |
||||
238 | } |
||||
239 | $this->min_arr_val = $min; |
||||
240 | $this->max_arr_val = $max; |
||||
241 | } |
||||
242 | |||||
243 | /** |
||||
244 | * Set function for generate values for random array |
||||
245 | * |
||||
246 | * @param callable $gen_fn |
||||
247 | */ |
||||
248 | public function setValuesModelFn(callable $gen_fn) |
||||
249 | { |
||||
250 | $this->values_model = 3; |
||||
251 | $this->fn_gen_value = $gen_fn; |
||||
252 | } |
||||
253 | |||||
254 | /** |
||||
255 | * Set function for generate keys for random array |
||||
256 | * |
||||
257 | * @param callable $gen_fn |
||||
258 | */ |
||||
259 | public function setKeysModelFn(callable $gen_fn) |
||||
260 | { |
||||
261 | $this->keys_model = 3; |
||||
262 | $this->fn_gen_key = $gen_fn; |
||||
263 | } |
||||
264 | |||||
265 | /** |
||||
266 | * Random Array generate |
||||
267 | * |
||||
268 | * Parameters $min_elem_cnt and $max_elem_cnt define the minimum and |
||||
269 | * maximum number of elements of generated arrays |
||||
270 | * |
||||
271 | * Parameter $theshold define chance of generating scalar or nested array |
||||
272 | * If 0 is specified, scalar will always be generated, never nested array |
||||
273 | * if 65535 specified, nested array will be generated until reach $lim_depth |
||||
274 | * if 32768 specified the probability of generating array or scalar is 50/50 |
||||
275 | * Only scalar generate if the depth of array nesting reached $lim_depth |
||||
276 | * |
||||
277 | * No more than $lim_elements of elements will be generated total |
||||
278 | * |
||||
279 | * @param integer $min_elem_cnt Min.count of elements in array (and nested) |
||||
280 | * @param integer $max_elem_cnt Max.count of elements in array (and nested) |
||||
281 | * @param integer $threshold Chance array or string generation (0-65535) |
||||
282 | * @param integer $lim_depth Depth limit of nesting arrays |
||||
283 | * @param integer $lim_elements Limit number of generated elements |
||||
284 | * @param string $root Key of this array (may be needed for nested arrays) |
||||
285 | * |
||||
286 | * @return array |
||||
287 | */ |
||||
288 | public function genRandomArray( |
||||
289 | $min_elem_cnt = 3, |
||||
290 | $max_elem_cnt = 10, |
||||
291 | $threshold = 32768, |
||||
292 | $lim_depth = 3, |
||||
293 | $lim_elements = 10000, |
||||
294 | $root = '' |
||||
295 | ) { |
||||
296 | if ($lim_elements) { |
||||
297 | $this->lim_elements = $lim_elements; |
||||
298 | } |
||||
299 | if ($lim_depth<1 |
||||
300 | || $this->lim_elements < 0 |
||||
301 | || $this->max_arr_key < 0 |
||||
302 | || $this->max_arr_key < $this->min_arr_key |
||||
303 | || $this->max_arr_val < 0 |
||||
304 | || $this->max_arr_val < $this->min_arr_val |
||||
305 | ) { |
||||
306 | return false; |
||||
0 ignored issues
–
show
|
|||||
307 | } |
||||
308 | |||||
309 | $elem_cnt = mt_rand($min_elem_cnt, $max_elem_cnt); |
||||
310 | if ($elem_cnt > $this->lim_elements) { |
||||
311 | $elem_cnt = $this->lim_elements; |
||||
312 | } |
||||
313 | $r_arr = []; |
||||
314 | $gen_arr = \unpack('v*', \call_user_func($this->rnd_fn, $elem_cnt*2)); |
||||
315 | $this->lim_elements-=$elem_cnt; |
||||
316 | |||||
317 | foreach ($gen_arr as $k => $v) { |
||||
318 | if ($v > $threshold || $lim_depth<2 || $this->lim_elements <2) { |
||||
319 | if ($this->values_model) { |
||||
320 | if ($this->values_model == 3) { |
||||
321 | $v = \call_user_func($this->fn_gen_value, |
||||
322 | \compact('k', 'v', 'threshold', 'lim_depth', 'root') |
||||
323 | ); |
||||
324 | } else { |
||||
325 | $v = mt_rand($this->min_arr_val, $this->max_arr_val); |
||||
326 | if ($this->values_model == 2) { |
||||
327 | $v = $this->genRandomStr($v, 2); |
||||
328 | } |
||||
329 | } |
||||
330 | } else { |
||||
331 | if (!$this->keys_model) { |
||||
332 | continue; |
||||
333 | } |
||||
334 | } |
||||
335 | } else { |
||||
336 | $v = $this->genRandomArray( |
||||
337 | $min_elem_cnt, |
||||
338 | $max_elem_cnt, |
||||
339 | $threshold, |
||||
340 | $lim_depth - 1, |
||||
341 | 0 |
||||
342 | ); |
||||
343 | } |
||||
344 | if ($this->keys_model) { |
||||
345 | if ($this->keys_model === 3) { |
||||
346 | $k = \call_user_func($this->fn_gen_key, |
||||
347 | \compact('k', 'v', 'threshold', 'lim_depth', 'root') |
||||
348 | ); |
||||
349 | } else { |
||||
350 | $k = \mt_rand($this->min_arr_key, $this->max_arr_key); |
||||
351 | if ($this->keys_model === 2) { |
||||
352 | $k = $this->genRandomStr($k, 1); |
||||
353 | } |
||||
354 | } |
||||
355 | $r_arr[$k] = $v; |
||||
356 | } else { |
||||
357 | $gen_arr[$k] = $v; |
||||
358 | } |
||||
359 | } |
||||
360 | |||||
361 | return $this->keys_model ? $r_arr : $gen_arr; |
||||
0 ignored issues
–
show
The expression
return $this->keys_model ? $r_arr : $gen_arr could also return false which is incompatible with the documented return type array . Did you maybe forget to handle an error condition?
If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled. ![]() |
|||||
362 | } |
||||
363 | } |
||||
364 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.