DEV Community

Prathamesh Patil
Prathamesh Patil

Posted on

foreach vs forelse

ForElse is a ForEach loop, but with extra handling for empty input(s)

Below example shoes both loops with the same list of Users as Input


@foreach ($users as $user)
    <p>This is user {{ $user->id }}</p>
@endforeach

@forelse ($users as $user)
    <li>{{ $user->name }}</li>
@empty
    <p>No users</p>
@endforelse

Enter fullscreen mode Exit fullscreen mode

Now if we compare this to the source code for the Laravel Framework to see how the loops are compiled (all Blades constructs are compiled into HTML when being rendered by PHP on the web page):

 /**
     * Compile the for-each statements into valid PHP.
     *
     * @param  string  $expression
     * @return string
     */
    protected function compileForeach($expression)
    {
        preg_match('/\( *(.*) +as *(.*)\)$/is', $expression, $matches);

        $iteratee = trim($matches[1]);

        $iteration = trim($matches[2]);

        $initLoop = "\$__currentLoopData = {$iteratee}; \$__env->addLoop(\$__currentLoopData);";

        $iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getLastLoop();';

        return "<?php {$initLoop} foreach(\$__currentLoopData as {$iteration}): {$iterateLoop} ?>";
    }


   /**
     * Compile the for-else statements into valid PHP.
     *
     * @param  string  $expression
     * @return string
     */
    protected function compileForelse($expression)
    {
        $empty = '$__empty_'.++$this->forElseCounter;

        preg_match('/\( *(.*) +as *(.*)\)$/is', $expression, $matches);

        $iteratee = trim($matches[1]);

        $iteration = trim($matches[2]);

        $initLoop = "\$__currentLoopData = {$iteratee}; \$__env->addLoop(\$__currentLoopData);";

        $iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getLastLoop();';

        return "<?php {$empty} = true; {$initLoop} foreach(\$__currentLoopData as {$iteration}): {$iterateLoop} {$empty} = false; ?>";
    }

Enter fullscreen mode Exit fullscreen mode

Essentially, the ForElse loop has a built-in code and compile check for an empty input, in which case it optionally outputs an alternate display template for the empty input.

I would imagine you can use a ForEach loop in every case that you might use a ForElse loop, adding that you include and empty checks that ForElse might catch for you.

Latest comments (0)