1 | <?php |
||
2 | |||
3 | namespace ierusalim\Random; |
||
4 | |||
5 | /** |
||
6 | * This class contains RandomToFile |
||
7 | * |
||
8 | * PHP Version 5.6 |
||
9 | * |
||
10 | * @package ierusalim\RandomToFile |
||
11 | * @author Alexander Jer <[email protected]> |
||
12 | * @copyright 2017, Ierusalim |
||
13 | * @license https://opensource.org/licenses/Apache-2.0 Apache-2.0 |
||
14 | */ |
||
15 | class RandomToFile extends RandomArray |
||
16 | { |
||
17 | /** |
||
18 | * Function for processing data and output to a file |
||
19 | * |
||
20 | * @var callable |
||
21 | */ |
||
22 | public $fn_file_output; |
||
23 | |||
24 | /** |
||
25 | * File name for data output |
||
26 | * |
||
27 | * @var string |
||
28 | */ |
||
29 | public $full_file_name; |
||
30 | |||
31 | /** |
||
32 | * Handler of file opened for write |
||
33 | * |
||
34 | * @var resource|null |
||
35 | */ |
||
36 | public $file_handler; |
||
37 | |||
38 | /** |
||
39 | * Default extention for make file names |
||
40 | * |
||
41 | * @var string |
||
42 | */ |
||
43 | public $default_ext = '.json'; |
||
44 | |||
45 | /** |
||
46 | * Main parameter of this class - function for processing and write data |
||
47 | * By default, this hook is set as a function 'writeFileOutputExample', |
||
48 | * which does the following function: output PHP code for assigning array. |
||
49 | * By analogy, write the necessary output functions for the desired format |
||
50 | * |
||
51 | * @param callable|null $fn_write |
||
52 | */ |
||
53 | public function __construct(callable $fn_write = null) |
||
54 | { |
||
55 | parent::__construct(); |
||
56 | if (is_null($fn_write)) { |
||
57 | $this->fn_file_output = [$this, 'writeFileOutputExample']; |
||
58 | $this->default_ext = '.php'; |
||
59 | } else { |
||
60 | $this->fn_file_output = $fn_write; |
||
61 | } |
||
62 | } |
||
63 | |||
64 | public function writeFileOutputExample($parr) |
||
65 | { |
||
66 | static $keys = []; |
||
67 | |||
68 | //extracting following work variables: |
||
69 | \extract($parr); //$signal, $k, $v, $lim_depth, $root |
||
70 | |||
71 | //begin formin output string |
||
72 | $out_str = '$x'; |
||
73 | |||
74 | switch ($signal) { |
||
75 | //siglan 'next' - when output next scalar element of array [$k]=>$v |
||
76 | case 'next': |
||
77 | if (!\is_numeric($k)) { |
||
78 | $k = "'" . \addcslashes($k, "'\\") . "'"; |
||
79 | } |
||
80 | if (!\is_numeric($v)) { |
||
81 | $v = "'" . \addcslashes($v, "'\\") . "'"; |
||
82 | } |
||
83 | $out_str .= (count($keys) ? |
||
84 | '[' . implode('][', $keys) . ']' |
||
85 | : |
||
86 | '' |
||
87 | ) . '[' . $k . ']=' . $v . ";\r\n"; |
||
88 | |||
89 | break; |
||
90 | |||
91 | //signal 'open' - when root or nested array beginning |
||
92 | case 'open': |
||
93 | if (count($keys) || !empty($root)) { |
||
94 | //nested array beginned |
||
95 | if (!is_numeric($root)) { |
||
96 | $root = "'" . \addcslashes($root, "'\\") . "'"; |
||
97 | } |
||
98 | array_push($keys, $root); |
||
99 | $out_str .= '[' . implode('][', $keys) . ']'; |
||
100 | $out_str .= "=[]; /* Create sub-array in key $out_str */\r\n"; |
||
101 | } else { |
||
102 | //root array beginned |
||
103 | $out_str .= "=[]; /* CREATE ROOT OF ARRAY */\r\n"; |
||
104 | $out_str = '<' . "?php\n" . $out_str; |
||
105 | } |
||
106 | break; |
||
107 | |||
108 | //signal 'close' - when root or nested array ended |
||
109 | case 'close': |
||
110 | if (count($keys)) { |
||
111 | //nested array ended |
||
112 | $out_str = "/* end $out_str" |
||
113 | .'[' . \implode('][', $keys) . ']' |
||
114 | . "*/\r\n"; |
||
115 | \array_pop($keys); |
||
116 | } else { |
||
117 | //root array ended |
||
118 | $out_str = " /* END OF ARRAY */\r\n"; |
||
119 | } |
||
120 | break; |
||
121 | |||
122 | //signal 'init' - when file open for write |
||
123 | case 'init': |
||
124 | $keys = []; |
||
125 | $out_str = ''; |
||
126 | } |
||
127 | //write formed string to output file |
||
128 | \fwrite($fh, $out_str); |
||
129 | } |
||
130 | |||
131 | public function genRandomToFile( |
||
132 | $min_elem_cnt = 3, |
||
133 | $max_elem_cnt = 10, |
||
134 | $threshold = 32768, |
||
135 | $lim_depth = 3, |
||
136 | $lim_elements = 10000, |
||
137 | $root = '' |
||
138 | ) { |
||
139 | if ($lim_elements) { |
||
140 | $this->lim_elements = $lim_elements; |
||
141 | } |
||
142 | if ($lim_depth < 1 |
||
143 | || $this->lim_elements < 0 |
||
144 | || $this->max_arr_key < 0 |
||
145 | || $this->max_arr_key < $this->min_arr_key |
||
146 | || $this->max_arr_val < 0 |
||
147 | || $this->max_arr_val < $this->min_arr_val |
||
148 | ) { |
||
149 | return false; |
||
150 | } |
||
151 | |||
152 | if (!$oh = $fh = $this->file_handler) { |
||
153 | $this->openOutputFile(); |
||
154 | $fh = $this->file_handler; |
||
155 | $signal = 'init'; |
||
156 | \call_user_func($this->fn_file_output, |
||
157 | \compact('signal', 'fh', 'threshold', 'lim_depth', 'root') |
||
158 | ); |
||
159 | } |
||
160 | |||
161 | $elem_cnt = mt_rand($min_elem_cnt, $max_elem_cnt); |
||
162 | if ($elem_cnt > $this->lim_elements) { |
||
163 | $elem_cnt = $this->lim_elements; |
||
164 | } |
||
165 | |||
166 | $this->lim_elements -= $elem_cnt; |
||
167 | |||
168 | $signal = 'open'; |
||
169 | \call_user_func($this->fn_file_output, |
||
170 | \compact('signal', 'fh', 'elem_cnt', 'lim_depth', 'root') |
||
171 | ); |
||
172 | |||
173 | $signal = 'next'; |
||
174 | |||
175 | foreach ($this->genBigRange($elem_cnt) as $k => $v) { |
||
176 | if ($this->keys_model) { |
||
177 | if ($this->keys_model === 3) { |
||
178 | $k = \call_user_func($this->fn_gen_key, |
||
179 | \compact('k', 'v', 'threshold', 'lim_depth', 'root') |
||
180 | ); |
||
181 | } else { |
||
182 | $k = \mt_rand($this->min_arr_key, $this->max_arr_key); |
||
183 | if ($this->keys_model === 2) { |
||
184 | $k = $this->genRandomStr($k, 1); |
||
185 | } |
||
186 | } |
||
187 | } |
||
188 | |||
189 | if ($v > $threshold || $lim_depth < 2 || $this->lim_elements < 2) { |
||
190 | if ($this->values_model) { |
||
191 | if ($this->values_model == 3) { |
||
192 | $v = \call_user_func($this->fn_gen_value, |
||
193 | \compact('k', 'v', 'threshold', 'lim_depth', 'root') |
||
194 | ); |
||
195 | } else { |
||
196 | $v = mt_rand($this->min_arr_val, $this->max_arr_val); |
||
197 | if ($this->values_model == 2) { |
||
198 | $v = $this->genRandomStr($v, 2); |
||
199 | } |
||
200 | } |
||
201 | } |
||
202 | } else { |
||
203 | $this->genRandomToFile( |
||
204 | $min_elem_cnt, |
||
205 | $max_elem_cnt, |
||
206 | $threshold, |
||
207 | $lim_depth - 1, |
||
208 | 0, |
||
209 | $k |
||
210 | ); |
||
211 | continue; |
||
212 | } |
||
213 | |||
214 | \call_user_func($this->fn_file_output, |
||
215 | \compact('signal', 'k', 'v', 'fh', 'lim_depth', 'root') |
||
216 | ); |
||
217 | } |
||
218 | |||
219 | $signal = 'close'; |
||
220 | \call_user_func($this->fn_file_output, |
||
221 | \compact('signal', 'fh', 'elem_cnt', 'lim_depth', 'root') |
||
222 | ); |
||
223 | |||
224 | if (!$oh) { |
||
0 ignored issues
–
show
introduced
by
![]() |
|||
225 | $this->closeOutputFile(); |
||
226 | } |
||
227 | return true; |
||
228 | } |
||
229 | |||
230 | public function genBigRange($total_elements) |
||
231 | { |
||
232 | for ($k = 1; $k <= $total_elements; $k++) { |
||
233 | $v = \mt_rand(0, 65535); |
||
234 | yield $k => $v; |
||
235 | } |
||
236 | } |
||
237 | |||
238 | public function genTempFileName($ext = null, $test_exception = false) |
||
239 | { |
||
240 | $file_name = \sys_get_temp_dir() . \DIRECTORY_SEPARATOR . 'genRandom'; |
||
241 | if ($test_exception || (!is_dir($file_name) && !\mkdir($file_name))) { |
||
242 | throw new \Exception("Can't mkdir $file_name for random file"); |
||
243 | } |
||
244 | if (is_null($ext)) { |
||
245 | $ext = $this->default_ext; |
||
246 | } |
||
247 | $file_name .= DIRECTORY_SEPARATOR . md5(microtime()) . $ext; |
||
248 | return $file_name; |
||
249 | } |
||
250 | |||
251 | public function setOutputFile($file_name = null, $ext = null) |
||
252 | { |
||
253 | if (empty($file_name) || !is_string($file_name)) { |
||
254 | if (is_null($ext)) { |
||
255 | $ext = $this->default_ext; |
||
256 | } |
||
257 | $file_name = $this->genTempFileName($ext); |
||
258 | } |
||
259 | return $this->full_file_name = $file_name; |
||
260 | } |
||
261 | |||
262 | public function openOutputFile() |
||
263 | { |
||
264 | if (!$this->file_handler = @\fopen($this->full_file_name, 'w')) { |
||
265 | throw new \Exception("Error write file " . $this->full_file_name); |
||
266 | } |
||
267 | return $this->file_handler; |
||
268 | } |
||
269 | |||
270 | public function closeOutputFile() |
||
271 | { |
||
272 | if ($this->file_handler) { |
||
273 | \fclose($this->file_handler); |
||
274 | $this->file_handler = false; |
||
275 | } |
||
276 | } |
||
277 | } |
||
278 |