All rules

Sheath rule

blade-no-php-tag

Prefer Blade's @php directive over raw PHP tags.
Package
Core
Category
Blade
Default severity
warning by default
Auto-fix
Manual fix

#Why

In ordinary Blade templates, raw PHP tags and @php behave identically. Using @php keeps PHP blocks consistent with the rest of Blade's syntax.

Livewire single-file components are an exception. Their leading raw PHP block defines the anonymous component class and is not reported.

Volt components are also an exception. Their standard PHP blocks define the component and do not become rendered markup. Mounted Volt templates are recognized through the application's Volt configuration. Class-based and functional Volt declarations can also identify a Volt template during standalone linting.

#Examples

#Bad

<!-- Raw PHP opening tags -->
<?php
$total = $items->sum('price');
?>
<!-- Short echo tag (mixing syntaxes) -->
<?= $user->name ?>
<!-- Inline PHP -->
<p><?php echo $message; ?></p>
<!-- PHP at start of file -->
<?php $active = true; ?>
<div class="<?php echo $active ? 'active' : ''; ?>">

#Good

<!-- Use @php directive -->
@php
$total = $items->sum('price');
@endphp
<!-- Use Blade echo syntax -->
{{ $user->name }}
<!-- Use Blade conditionals -->
<p>{{ $message }}</p>
<!-- Inline @php for simple assignments -->
@php($active = true)
<div class="{{ $active ? 'active' : '' }}">

#Livewire single-file component

<?php
use Livewire\Component;
new class extends Component
{
public string $name = '';
};
?>
<div>{{ $name }}</div>

#Functional Volt component

<?php
use function Livewire\Volt\{state};
state(['count' => 0]);
$increment = fn () => $this->count++;
?>
<div>
<span>{{ $count }}</span>
<button type="button" wire:click="increment">Increment</button>
</div>

#Class-based Volt component

<?php
use Livewire\Volt\Component;
new class extends Component
{
public int $count = 0;
};
?>
<div>{{ $count }}</div>

#@php Syntax Options

<!-- Block syntax -->
@php
$name = 'John';
$greeting = "Hello, {$name}!";
@endphp
<!-- Inline syntax (single expression) -->
@php($count = 5)
@php($items = collect([1, 2, 3]))

#Notes

  • Both <?php and <?= are reported outside the Livewire and Volt exceptions.
  • A leading <?php ... ?> class preamble is allowed only when its top-level anonymous class extends Livewire\Component, directly or through an import alias. A special filename, wire:* attributes, or an import by itself is not enough to identify a Livewire single-file component.
  • Raw PHP later in a Livewire component's view is still reported.
  • In a mounted Volt template, every standard <?php ... ?> block is accepted, including multiple blocks and template-first definitions.
  • <?= ... ?> remains a violation in Volt templates because short echo tags become rendered output.
  • When the mounted Volt configuration is unavailable, a Livewire\Volt\Component anonymous class, a Livewire\Volt function import, or a fully qualified Volt API call must identify the file before the exception applies.
  • Outside that Livewire preamble, this is a syntax choice rather than a runtime behavior change.
  • On a file you are not ready to convert, an inline suppression is narrower than turning the rule off.

#Related Rules