Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why shortcode @php() interfere with @php and @endphp

I am looking for a reason why in blade files (Laravel) code with mixed @php() and @php ... @endphp fails, and works fine with consistent usage of those codes across the file. I've just learned that the hard way but can't find the reason.

Fails:

@php($foo = 'foo')
<h1>{{ $foo }}</h1>
@php
    $bar = $foo . 'bar';
@endphp
@for($i = 1; $i<10; $i++)
    <h2><b>{{ $i }}<b/>{{ $bar }}</h2>
@endfor

Works fine:

@php($foo = 'foo')
<h1>{{ $foo }}</h1>
@php($bar = $foo . 'bar');
@for($i = 1; $i<10; $i++)
    <h2><b>{{ $i }}<b/>{{ $bar }}</h2>
@endfor

Also works fine:

@php
    $foo = 'foo';
@endphp
<h1>{{ $foo }}</h1>
@php
    $bar = $foo . 'bar';
@endphp
@for($i = 1; $i<10; $i++)
    <h2><b>{{ $i }}<b/>{{ $bar }}</h2>
@endfor

An error

Example

like image 291
MacEncrypted Avatar asked Jul 23 '26 12:07

MacEncrypted


1 Answers

The issue in my view is the order of operations when processing @php blocks.

The relevant source code will first store uncompiled blocks before it actually compiles anything. Uncompiled blocks seem to be @php ... @endphp and @verbatim ... @endverbatim blocks. The code for @php is:

   protected function storePhpBlocks($value)
    {
        return preg_replace_callback('/(?<!@)@php(.*?)@endphp/s', function ($matches) {
            return $this->storeRawBlock("<?php{$matches[1]}?>");
        }, $value);
    }

So in your code block, the process of trying to store code between a @php ... @endphp everything between @php($foo = 'foo') and @endphp will be matched (which includes the 2nd @php tag) which will result in broken PHP code being stored.

Reading the docs I can see that while the syntax @php ... @endphp is documented, the alternative syntax @php(...) is not which makes me think that while the blade compiler implementation supports this syntax, it has not been documented (or not documented anymore) because it is problematic.

like image 171
apokryfos Avatar answered Jul 26 '26 03:07

apokryfos