Conditions | 11 |
Paths | 37 |
Total Lines | 89 |
Code Lines | 38 |
Lines | 0 |
Ratio | 0 % |
Changes | 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 |
||
214 | public static function trimWhitespace($string, array $options = []) |
||
215 | { |
||
216 | if (!is_string($string)) { |
||
217 | return ''; |
||
218 | } |
||
219 | |||
220 | $o = array_merge( |
||
221 | [ |
||
222 | 'leading' => true, |
||
223 | 'inside' => true, |
||
224 | 'blankLines' => 0, |
||
225 | 'tabWidth' => 4, |
||
226 | ], |
||
227 | $options |
||
228 | ); |
||
229 | |||
230 | // Looking for spaces *and* tab characters is way too costly |
||
231 | // (running times go x4 or x10) so we forcefully replace tab characters |
||
232 | // with spaces, but make it configurable. |
||
233 | $tabw = $o['tabWidth']; |
||
234 | |||
235 | if (!is_int($tabw) || $tabw < 1 || $tabw > 8) { |
||
236 | $tabw = 4; |
||
237 | } |
||
238 | |||
239 | // Replacement patterns should be applied in a specific order |
||
240 | $patterns = []; |
||
241 | |||
242 | // Trim leading whitespace first (if active). In typical scenarios, |
||
243 | // especially for indented HTML, this will remove of the target whitespace |
||
244 | // and it turns out to be really quick. |
||
245 | if ($o['leading']) { |
||
246 | $patterns[] = ['/^ {2,}/m', '']; |
||
247 | } |
||
248 | |||
249 | // Always trim at the end. Warning: this seems to be the costlier |
||
250 | // operation, perhaps because looking ahead is harder? |
||
251 | $patterns[] = ['/ +$/m', '']; |
||
252 | |||
253 | // Collapse space sequences inside lines (excluding leading/trailing) |
||
254 | if ($o['inside']) { |
||
255 | // No leading spaces? We can avoid a very costly condition! |
||
256 | // Using a look-behind (or similar solutions) seems to make the whole |
||
257 | // function go 2x-4x slower (PHP7) or up to 10x slower (PHP 5.6), |
||
258 | // except on very big strings where whatever perf penalty was incurred |
||
259 | // seems to be more limited (or at least not exponential). |
||
260 | $spaces = ($o['leading'] ? ' ' : '(?<=\b) ') . '{2,}'; |
||
261 | $patterns[] = ['/' . $spaces . '/', ' ']; |
||
262 | } |
||
263 | |||
264 | // Remove empty lines |
||
265 | if (is_int($l = $o['blankLines']) && $l >= 0) { |
||
266 | // We need blank lines to be truly empty; if trimStart is disabled |
||
267 | // we have to fall back to this slightly more costly regex. |
||
268 | if (!$o['leading']) { |
||
269 | $patterns[] = ['/^ +$/m', '']; |
||
270 | } |
||
271 | |||
272 | // Not using '\R' because it's too slow, so we must do it by hand |
||
273 | // and replace CRLF before touching any LF. |
||
274 | $patterns[] = [ |
||
275 | '/(\r\n){' . ($l + 2) . ',}/m', |
||
276 | str_repeat("\r\n", $l + 1) |
||
277 | ]; |
||
278 | |||
279 | $patterns[] = [ |
||
280 | '/\n{' . ($l + 2) . ',}/m', |
||
281 | str_repeat("\n", $l + 1) |
||
282 | ]; |
||
283 | } |
||
284 | |||
285 | // Doing the replacement in one go without storing intermediary |
||
286 | // values helps a bit for big strings (around 20 percent quicker). |
||
287 | return preg_replace( |
||
288 | array_map( |
||
289 | function ($x) { |
||
290 | return $x[0]; |
||
291 | }, |
||
292 | $patterns |
||
293 | ), |
||
294 | array_map( |
||
295 | function ($x) { |
||
296 | return $x[1]; |
||
297 | }, |
||
298 | $patterns |
||
299 | ), |
||
300 | str_replace("\t", str_repeat(' ', $tabw), $string) |
||
301 | ); |
||
302 | } |
||
303 | |||
318 |