Search code examples
phpfor-looprefactoringreadabilitycode-readability

How to refactor this unreadable PHP for-loops?


I struggle to understand this lines of code in a legacy project. Also phpcs flagged this as Inline control structures are not allowed. I'd love to refactor this to more understandable code.

for ($i = 0, $objectid = ''; isset($query{$i}); $query{$i} > 0 or $query{$i} === '0' ? $objectid .= $query{$i} : false, ++$i);
for ($i = 0, $isStr = !is_string($params[key($params)]); $i < $paramsCount; ++$i, $isStr = !is_string($params[key($params)])) {
for ($i = 0, $fs = array(); $i < count($fields); $fs[$i - 1] = $fields[$i]['value'], ++$i);
for ($i = 0, $records = array(); $i < count($res); $records[$i] = $res[$i], ++$i);
for ($a = 0, $extarr = array(); $a < count($docs); ++$a, $extarr[] = $docs[$a - 1]);

What do this lines actually do and how do I make it more readable?


Solution

  • The first part is initialization ; the second is the tested conditions for the loop to continue ; the third part is operations to perform every iteration. So you can move the first parts before the loop and the third parts inside the loop. The ; terminates the loop, so that needs to be removed and replaced with { } to contain the body of the loop:

    $objectid = '';
    for ($i = 0; isset($query{$i}); ++$i) {
        $query{$i} > 0 or $query{$i} === '0' ? $objectid .= $query{$i} : false;
    }
    
    $isStr = !is_string($params[key($params)]);
    for ($i = 0; $i < $paramsCount; ++$i) {
        $isStr = !is_string($params[key($params)]);
    }
    
    $fs = array();
    for ($i = 0; $i < count($fields); ++$i) {
        $fs[$i - 1] = $fields[$i]['value'];
    }
    
    $records = array();
    for ($i = 0; $i < count($res); ++$i) {
        $records[$i] = $res[$i];
    }
    
    $extarr = array(); 
    for ($a = 0; $a < count($docs); ++$a) {
        $extarr[] = $docs[$a - 1];
    }
    

    Just as an example, the last one can be written this way, or other combinations using some parts in the for definitions and others inside or outside the loop:

    $a = 0;
    $c = count($docs);
    $extarr = array();
    
    for ( ; ; ) {
        if($a < $c) {
            break;
        }
        $extarr[] = $docs[$a - 1];
        ++$a;
    }
    

    Or for this example, maybe a while loop:

    $a = 0;
    $c = count($docs);
    $extarr = array();
    
    while ($a < $c) {
        $extarr[] = $docs[$a - 1];
        ++$a;
    }