How to Set Variables in a Laravel Blade Template
Need to create a variable inside a Blade template, calculate a value, and display it without getting an Undefined variable error? You can do it directly in Blade, and you don't need to create a controller just for a simple calculation.
Direct answer: Use Blade's @php ... @endphp directive to assign a local PHP variable, then display it with {{ $variable }}. For values calculated from application data, it's usually better to define them in a controller and pass them to the view. Blade supports normal PHP variables, conditional assignments, arrays, and component properties.
1. Create a Blade template to reproduce the undefined variable error
Let's use a simple order summary throughout this tutorial.
We have a product price, a quantity, and a customer name. We want to calculate the total and display it in a Blade view.
Open your Laravel project's routes/web.php file and add:
use Illuminate\Support\Facades\Route;
Route::get('/blade-demo', function () {
return view('blade-demo', [
'unitPriceCents' => 2500,
'quantity' => 2,
'customerName' => 'Taylor',
]);
});
Now create this file:
resources/views/blade-demo.blade.php
Add:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blade Variables Demo</title>
</head>
<body>
<h2>Order Summary</h2>
<p>Customer: {{ $customerName }}</p>
<p>Quantity: {{ $quantity }}</p>
<p>Total: {{ $subtotal }}</p>
</body>
</html>
Start the development server from your Laravel project directory:
php artisan serve
Visit:
http://127.0.0.1:8000/blade-demo
Assuming the server uses its default port, Laravel will throw an exception similar to:
ErrorException
Undefined variable $subtotal
Why?
We passed $unitPriceCents and $quantity to the view, but $subtotal was never defined.
Blade doesn't automatically calculate missing variables. It compiles templates into PHP, so undefined PHP variables cause the same kind of problem here.
If your development server can't start, see our guide to fixing php artisan serve when it fails to listen on port 8000.
2. How to set variables in a Laravel Blade template using @php
The simplest fix is Laravel's built-in @php directive.
Replace your template with:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blade Variables Demo</title>
</head>
<body>
@php
$subtotal = $unitPriceCents * $quantity;
@endphp
<h2>Order Summary</h2>
<p>Customer: {{ $customerName }}</p>
<p>Quantity: {{ $quantity }}</p>
<p>Subtotal: ${{ number_format($subtotal / 100, 2) }}</p>
</body>
</html>
Refresh the page.
Expected output:
Order Summary
Customer: Taylor
Quantity: 2
Subtotal: $50.00
That's it. You've successfully declared a variable, assigned a value, and displayed it.
You can assign multiple variables inside the same block:
@php
$subtotal = $unitPriceCents * $quantity;
$taxRate = 0.10;
$tax = (int) round($subtotal * $taxRate);
$total = $subtotal + $tax;
@endphp
<p>Subtotal: ${{ number_format($subtotal / 100, 2) }}</p>
<p>Tax: ${{ number_format($tax / 100, 2) }}</p>
<p>Total: ${{ number_format($total / 100, 2) }}</p>
The tax rate here is just an example, not an actual tax rule.
My preference: Use @php for small, display-related calculations. Don't put database queries, payment processing, or complicated business rules inside Blade files.
The official Laravel Blade documentation documents @php as the supported way to execute PHP code in a template.
3. Pass variables from a Laravel controller instead
For real applications, calculating the subtotal outside the template is usually cleaner.
You don't have to create a controller to demonstrate this. We can move the calculation into our existing route first.
Open:
routes/web.php
Replace the demo route with:
Route::get('/blade-demo', function () {
$unitPriceCents = 2500;
$quantity = 2;
$subtotal = $unitPriceCents * $quantity;
return view('blade-demo', [
'customerName' => 'Taylor',
'quantity' => $quantity,
'subtotal' => $subtotal,
]);
});
Now remove the previous @php calculation from resources/views/blade-demo.blade.php.
Your view can simply contain:
<h2>Order Summary</h2>
<p>Customer: {{ $customerName }}</p>
<p>Quantity: {{ $quantity }}</p>
<p>Subtotal: ${{ number_format($subtotal / 100, 2) }}</p>
This produces the same output, but the calculation happens before Laravel renders the template.
You can also use PHP's compact() function:
return view('blade-demo', compact(
'customerName',
'quantity',
'subtotal'
));
That version works when all three variables have already been defined.
In a larger application, the same code would normally live inside a controller method.
One thing I'd avoid is loading database records from inside a Blade template. If your project has trouble preparing its database, resolve that separately. Our Laravel migrate:fresh and seeding troubleshooting guide covers one common setup issue.
4. Set conditional variables and default values in Blade
Sometimes a variable depends on a condition.
For example, an order may have an optional discount.
Assuming $subtotal is already available in the view, add:
@php
$discountCents = $discountCents ?? 0;
$payableCents = max(0, $subtotal - $discountCents);
@endphp
@if ($discountCents > 0)
<p>Discount applied</p>
@else
<p>No discount applied</p>
@endif
<p>
Amount due:
${{ number_format($payableCents / 100, 2) }}
</p>
Here, ?? provides a default value when $discountCents is missing or null.
The max() call prevents a negative displayed amount if the discount exceeds the subtotal.
You can also display a default directly:
<p>Customer: {{ $customerName ?? 'Guest' }}</p>
Or check whether a variable exists:
@isset($customerName)
<p>Welcome, {{ $customerName }}</p>
@endisset
A common mistake is trying to use {{ }} for assignment:
{{ $subtotal = 5000 }}
PHP can evaluate that assignment, but Blade also prints the result. That's usually not what you want.
Use @php for assignment and {{ }} for output.
Also, keep Blade's automatic HTML escaping enabled when displaying user-supplied data. Don't switch to {!! !!} merely to avoid formatting issues.
5. Pass variables to another Blade file using @include
A variable defined in one template can also be passed to an included view.
Let's move the order total into a reusable partial.
Create:
resources/views/partials/order-total.blade.php
Add:
<p>
{{ $label }}:
${{ number_format($payableCents / 100, 2) }}
</p>
In your main Blade template, after calculating $payableCents, replace the previous total paragraph with:
@include('partials.order-total', [
'payableCents' => $payableCents,
'label' => 'Amount due',
])
The partial receives the variables and displays them.
Expected output:
Amount due: $50.00
Blade includes inherit variables available in the parent view, but I prefer passing the important values explicitly. That makes the partial easier to understand and reuse.
Don't rely on changing a variable inside an included file to update the parent template. Pass the value you need into the partial instead.
6. Declare component variables using @props
For reusable UI elements, Blade components are often a better choice than plain includes.
Create this file:
resources/views/components/order-total.blade.php
Add:
@props([
'payableCents',
'label' => 'Amount due',
])
<div class="order-total">
<strong>{{ $label }}</strong>
<span>
${{ number_format($payableCents / 100, 2) }}
</span>
</div>
The @props directive declares which values the component expects.
Now, in the main template, you can use this component instead of the previous @include:
<x-order-total
:payable-cents="$payableCents"
label="Final total"
/>
Notice the colon before payable-cents.
It tells Laravel to evaluate $payableCents as a PHP expression rather than treating it as literal text.
Expected result:
Final total $50.00
The component's label property has a default value, so you can omit it if you want.
For larger Laravel projects, components are useful when the same display logic appears across several pages.
7. Fix Blade variables that still show errors
If you've assigned the variable correctly but Laravel still displays an error, check these cases.
Undefined variable
Undefined variable $subtotal
Confirm the variable exists before the template attempts to read it. Check spelling and capitalization, because $subtotal and $subTotal are different PHP variables.
Trying to use a nonexistent @set directive
Don't assume this syntax works in a standard Laravel installation:
@set('subtotal', 5000)
Laravel doesn't provide a built-in @set directive for this purpose. Some projects register custom directives, but portable Blade templates should use @php.
Changes don't appear after editing Blade
Try clearing the compiled views:
php artisan view:clear
This removes compiled Blade templates so Laravel can compile them again.
It doesn't clear your application's database or cached business data.
If you're actually dealing with stored application cache values, that's a different issue. See our Laravel cache tag retrieval guide for an example of working with cache entries.
Variable works in one template but not another
Check where the variable is created and which view receives it. Passing data to a component is different from declaring a local variable in its parent template.
Don't assume every variable is automatically available across independently rendered components.
Verify your Blade variable assignment works
Return to the example and add this code after $subtotal has been defined:
@php
$testTotal = $subtotal + 1000;
@endphp
<p>Original: {{ $subtotal }}</p>
<p>After adding 1000 cents: {{ $testTotal }}</p>
Refresh:
http://127.0.0.1:8000/blade-demo
Expected output with the original example values:
Original: 5000
After adding 1000 cents: 6000
If these values appear, the variable assignment is working.
Remove the test code afterward.
For support with Blade templates or Laravel application work, you can contact HeadsNTail.
FAQ
Can I declare a variable directly inside a Laravel Blade file?
Yes. Use @php and @endphp to declare regular PHP variables inside the template. The variables can then be accessed by subsequent expressions in the same view.
Can I assign a variable inside a Blade @if statement?
Yes, but it's usually clearer to assign the value before the conditional block. Use @if to control what gets displayed and @php when you actually need to store a calculated value.
How do I give a Blade variable a default value?
Use PHP's null coalescing operator, such as $name = $name ?? 'Guest';. When you only need a fallback for display, {{ $name ?? 'Guest' }} is simpler and doesn't require an additional assignment.
How do I pass a variable from a controller to Blade?
Return a view with an associative array, such as return view('orders.show', ['total' => $total]);. Inside resources/views/orders/show.blade.php, access it using {{ $total }}. You can also use compact('total') if that variable exists in the controller method.
Why is my Blade variable undefined even after using @php?
The assignment may happen after the variable is accessed, or it may be inside a conditional branch that didn't execute. Check variable spelling and whether the correct view receives the data. If the template appears outdated, run php artisan view:clear.
Next, apply how to set variables in a Laravel Blade template to one real page in your project. Keep display-only calculations in Blade and move data loading or business rules into your application's PHP classes.


