Conditions | 46 |
Paths | > 20000 |
Total Lines | 276 |
Code Lines | 128 |
Lines | 0 |
Ratio | 0 % |
Changes | 2 | ||
Bugs | 1 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | <?php |
||
63 | function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '') |
||
64 | { |
||
65 | $defaults = array( |
||
66 | 'word' => '', |
||
67 | 'img_path' => '', |
||
68 | 'img_url' => '', |
||
69 | 'img_width' => '150', |
||
70 | 'img_height' => '30', |
||
71 | 'font_path' => '', |
||
72 | 'expiration' => 7200, |
||
73 | 'word_length' => 8, |
||
74 | 'font_size' => 16, |
||
75 | 'img_id' => '', |
||
76 | 'pool' => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', |
||
77 | 'colors' => array( |
||
78 | 'background' => array(255,255,255), |
||
79 | 'border' => array(153,102,102), |
||
80 | 'text' => array(204,153,153), |
||
81 | 'grid' => array(255,182,182) |
||
82 | ) |
||
83 | ); |
||
84 | |||
85 | foreach ($defaults as $key => $val) |
||
86 | { |
||
87 | if ( ! is_array($data) && empty($$key)) |
||
88 | { |
||
89 | $$key = $val; |
||
90 | } |
||
91 | else |
||
92 | { |
||
93 | $$key = isset($data[$key]) ? $data[$key] : $val; |
||
94 | } |
||
95 | } |
||
96 | |||
97 | if ($img_path === '' OR $img_url === '' |
||
98 | OR ! is_dir($img_path) OR ! is_really_writable($img_path) |
||
99 | OR ! extension_loaded('gd')) |
||
100 | { |
||
101 | return FALSE; |
||
102 | } |
||
103 | |||
104 | // ----------------------------------- |
||
105 | // Remove old images |
||
106 | // ----------------------------------- |
||
107 | |||
108 | $now = microtime(TRUE); |
||
109 | |||
110 | $current_dir = @opendir($img_path); |
||
111 | while ($filename = @readdir($current_dir)) |
||
112 | { |
||
113 | if (substr($filename, -4) === '.jpg' && (str_replace('.jpg', '', $filename) + $expiration) < $now) |
||
114 | { |
||
115 | @unlink($img_path.$filename); |
||
116 | } |
||
117 | } |
||
118 | |||
119 | @closedir($current_dir); |
||
120 | |||
121 | // ----------------------------------- |
||
122 | // Do we have a "word" yet? |
||
123 | // ----------------------------------- |
||
124 | |||
125 | if (empty($word)) |
||
126 | { |
||
127 | $word = ''; |
||
128 | $pool_length = strlen($pool); |
||
129 | $rand_max = $pool_length - 1; |
||
130 | |||
131 | // PHP7 or a suitable polyfill |
||
132 | if (function_exists('random_int')) |
||
133 | { |
||
134 | try |
||
135 | { |
||
136 | for ($i = 0; $i < $word_length; $i++) |
||
137 | { |
||
138 | $word .= $pool[random_int(0, $rand_max)]; |
||
139 | } |
||
140 | } |
||
141 | catch (Exception $e) |
||
142 | { |
||
143 | // This means fallback to the next possible |
||
144 | // alternative to random_int() |
||
145 | $word = ''; |
||
146 | } |
||
147 | } |
||
148 | } |
||
149 | |||
150 | if (empty($word)) |
||
151 | { |
||
152 | // Nobody will have a larger character pool than |
||
153 | // 256 characters, but let's handle it just in case ... |
||
154 | // |
||
155 | // No, I do not care that the fallback to mt_rand() can |
||
156 | // handle it; if you trigger this, you're very obviously |
||
157 | // trying to break it. -- Narf |
||
158 | if ($pool_length > 256) |
||
159 | { |
||
160 | return FALSE; |
||
161 | } |
||
162 | |||
163 | // We'll try using the operating system's PRNG first, |
||
164 | // which we can access through CI_Security::get_random_bytes() |
||
165 | $security = get_instance()->security; |
||
166 | |||
167 | // To avoid numerous get_random_bytes() calls, we'll |
||
168 | // just try fetching as much bytes as we need at once. |
||
169 | if (($bytes = $security->get_random_bytes($pool_length)) !== FALSE) |
||
170 | { |
||
171 | $byte_index = $word_index = 0; |
||
172 | while ($word_index < $word_length) |
||
173 | { |
||
174 | list(, $rand_index) = unpack('C', $bytes[$byte_index++]); |
||
175 | if ($rand_index > $rand_max) |
||
176 | { |
||
177 | // Was this the last byte we have? |
||
178 | // If so, try to fetch more. |
||
179 | if ($byte_index === $pool_length) |
||
180 | { |
||
181 | // No failures should be possible if |
||
182 | // the first get_random_bytes() call |
||
183 | // didn't return FALSE, but still ... |
||
184 | for ($i = 0; $i < 5; $i++) |
||
185 | { |
||
186 | if (($bytes = $security->get_random_bytes($pool_length)) === FALSE) |
||
187 | { |
||
188 | continue; |
||
189 | } |
||
190 | |||
191 | $byte_index = 0; |
||
192 | break; |
||
193 | } |
||
194 | |||
195 | if ($bytes === FALSE) |
||
196 | { |
||
197 | // Sadly, this means fallback to mt_rand() |
||
198 | $word = ''; |
||
199 | break; |
||
200 | } |
||
201 | } |
||
202 | |||
203 | continue; |
||
204 | } |
||
205 | |||
206 | $word .= $pool[$rand_index]; |
||
207 | $word_index++; |
||
208 | } |
||
209 | } |
||
210 | } |
||
211 | |||
212 | if (empty($word)) |
||
213 | { |
||
214 | for ($i = 0; $i < $word_length; $i++) |
||
215 | { |
||
216 | $word .= $pool[mt_rand(0, $rand_max)]; |
||
217 | } |
||
218 | } |
||
219 | elseif ( ! is_string($word)) |
||
220 | { |
||
221 | $word = (string) $word; |
||
222 | } |
||
223 | |||
224 | // ----------------------------------- |
||
225 | // Determine angle and position |
||
226 | // ----------------------------------- |
||
227 | $length = strlen($word); |
||
228 | $angle = ($length >= 6) ? mt_rand(-($length-6), ($length-6)) : 0; |
||
229 | $x_axis = mt_rand(6, (360/$length)-16); |
||
230 | $y_axis = ($angle >= 0) ? mt_rand($img_height, $img_width) : mt_rand(6, $img_height); |
||
231 | |||
232 | // Create image |
||
233 | // PHP.net recommends imagecreatetruecolor(), but it isn't always available |
||
234 | $im = function_exists('imagecreatetruecolor') |
||
235 | ? imagecreatetruecolor($img_width, $img_height) |
||
236 | : imagecreate($img_width, $img_height); |
||
237 | |||
238 | // ----------------------------------- |
||
239 | // Assign colors |
||
240 | // ---------------------------------- |
||
241 | |||
242 | is_array($colors) OR $colors = $defaults['colors']; |
||
243 | |||
244 | foreach (array_keys($defaults['colors']) as $key) |
||
245 | { |
||
246 | // Check for a possible missing value |
||
247 | is_array($colors[$key]) OR $colors[$key] = $defaults['colors'][$key]; |
||
248 | $colors[$key] = imagecolorallocate($im, $colors[$key][0], $colors[$key][1], $colors[$key][2]); |
||
249 | } |
||
250 | |||
251 | // Create the rectangle |
||
252 | ImageFilledRectangle($im, 0, 0, $img_width, $img_height, $colors['background']); |
||
253 | |||
254 | // ----------------------------------- |
||
255 | // Create the spiral pattern |
||
256 | // ----------------------------------- |
||
257 | $theta = 1; |
||
258 | $thetac = 7; |
||
259 | $radius = 16; |
||
260 | $circles = 20; |
||
261 | $points = 32; |
||
262 | |||
263 | for ($i = 0, $cp = ($circles * $points) - 1; $i < $cp; $i++) |
||
264 | { |
||
265 | $theta += $thetac; |
||
266 | $rad = $radius * ($i / $points); |
||
267 | $x = ($rad * cos($theta)) + $x_axis; |
||
268 | $y = ($rad * sin($theta)) + $y_axis; |
||
269 | $theta += $thetac; |
||
270 | $rad1 = $radius * (($i + 1) / $points); |
||
271 | $x1 = ($rad1 * cos($theta)) + $x_axis; |
||
272 | $y1 = ($rad1 * sin($theta)) + $y_axis; |
||
273 | imageline($im, $x, $y, $x1, $y1, $colors['grid']); |
||
274 | $theta -= $thetac; |
||
275 | } |
||
276 | |||
277 | // ----------------------------------- |
||
278 | // Write the text |
||
279 | // ----------------------------------- |
||
280 | |||
281 | $use_font = ($font_path !== '' && file_exists($font_path) && function_exists('imagettftext')); |
||
282 | if ($use_font === FALSE) |
||
283 | { |
||
284 | ($font_size > 5) && $font_size = 5; |
||
285 | $x = mt_rand(0, $img_width / ($length / 3)); |
||
286 | $y = 0; |
||
287 | } |
||
288 | else |
||
289 | { |
||
290 | ($font_size > 30) && $font_size = 30; |
||
291 | $x = mt_rand(0, $img_width / ($length / 1.5)); |
||
292 | $y = $font_size + 2; |
||
293 | } |
||
294 | |||
295 | for ($i = 0; $i < $length; $i++) |
||
296 | { |
||
297 | if ($use_font === FALSE) |
||
298 | { |
||
299 | $y = mt_rand(0 , $img_height / 2); |
||
300 | imagestring($im, $font_size, $x, $y, $word[$i], $colors['text']); |
||
301 | $x += ($font_size * 2); |
||
302 | } |
||
303 | else |
||
304 | { |
||
305 | $y = mt_rand($img_height / 2, $img_height - 3); |
||
306 | imagettftext($im, $font_size, $angle, $x, $y, $colors['text'], $font_path, $word[$i]); |
||
307 | $x += $font_size; |
||
308 | } |
||
309 | } |
||
310 | |||
311 | // Create the border |
||
312 | imagerectangle($im, 0, 0, $img_width - 1, $img_height - 1, $colors['border']); |
||
313 | |||
314 | // ----------------------------------- |
||
315 | // Generate the image |
||
316 | // ----------------------------------- |
||
317 | $img_url = rtrim($img_url, '/').'/'; |
||
318 | |||
319 | if (function_exists('imagejpeg')) |
||
320 | { |
||
321 | $img_filename = $now.'.jpg'; |
||
322 | imagejpeg($im, $img_path.$img_filename); |
||
323 | } |
||
324 | elseif (function_exists('imagepng')) |
||
325 | { |
||
326 | $img_filename = $now.'.png'; |
||
327 | imagepng($im, $img_path.$img_filename); |
||
328 | } |
||
329 | else |
||
330 | { |
||
331 | return FALSE; |
||
332 | } |
||
333 | |||
334 | $img = '<img '.($img_id === '' ? '' : 'id="'.$img_id.'"').' src="'.$img_url.$img_filename.'" style="width: '.$img_width.'; height: '.$img_height .'; border: 0;" alt=" " />'; |
||
335 | ImageDestroy($im); |
||
336 | |||
337 | return array('word' => $word, 'time' => $now, 'image' => $img, 'filename' => $img_filename); |
||
338 | } |
||
339 | } |
||
340 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.