DEV Community

Cover image for 12 Must-Know Laravel Tips from July 2025
Laravel Daily tips
Laravel Daily tips

Posted on

12 Must-Know Laravel Tips from July 2025

This blog curates 12 practical Laravel and PHP tips shared by the developer community on X (formerly Twitter) in July 2025. From avoiding ambiguous column errors in Eloquent scopes to new features like whereValueBetween() and secure password generation with Str::password(), these insights can help improve your day-to-day Laravel development. Each tip is explained with a use-case example, making this blog a valuable resource for Laravel developers of all levels.

Every month, the Laravel community on Twitter (or X) shares a ton of useful tips and tricks. This post gathers some of the best insights from July, covering everything from Eloquent to Carbon and API responses. Let's dive into 12 tips that can make you a more efficient Laravel developer

1. Eloquent Scopes with getTable() for Ambiguous Columns

When you're working with database tables that have columns with the same name (like is_displayed), you might run into an "ambiguous column" SQL error during joins. A simple way to avoid this is to prefix the column name with the table name.

Instead of writing:

public function scopeIsDisplayed(Builder $query): void
{
    $query->where('is_displayed', 1);
}
Enter fullscreen mode Exit fullscreen mode

Do this:

public function scopeIsDisplayed(Builder $query): void
{
    $query->where($this->getTable() . '.is_displayed', 1);
}
Enter fullscreen mode Exit fullscreen mode

The $this->getTable() method dynamically gets the current model's table name, ensuring the query is explicit and error-free. An alternative method is qualifyColumn(), but getTable() is often considered more readable.

2. Carbon's is... Methods

The Carbon library, a standard part of Laravel, has an extensive list of helpful methods for comparing dates. Instead of manually checking if a date is today, tomorrow, or a weekday, you can use Carbon's built-in is... methods.

A few examples:

  • $date->isToday()
  • $date->isTomorrow()
  • $date->isYesterday()
  • $date->isWeekend()
  • $date->isWeekday()
  • $date->isSameDay($otherDate)

Before writing your own date comparison logic, check the Carbon documentation, it likely has a method for what you need.

3. Response Macros for Consistent APIs

You can create consistent API responses across your application using Response Macros. While a base controller or a trait is a common approach, macros offer a clean way to standardize responses directly in a service provider.

First, define a macro in your AppServiceProvider (or a dedicated service provider):

// app/Providers/ResponseMacroServiceProvider.php
public function boot(): void
{
    Response::macro('apiSuccess', function (
        string $message = 'Success',
        int $statusCode = 200,
        array $data = []
    ) {
        return response()->json([
            'success' => true,
            'message' => $message,
            'data' => $data,
        ], $statusCode);
    });
}
Enter fullscreen mode Exit fullscreen mode

Then, you can use this macro in any of your controllers:

return response()->apiSuccess('User created successfully.');
Enter fullscreen mode Exit fullscreen mode

This centralizes your response logic, making it easy to maintain a consistent API.

4. in_array_keys Validation Rule

Laravel 12.29 introduced a new validation rule: in_array_keys. This is useful for validating that a value exists as a key within a given array.

For example, if you have an array of permissions and you want to ensure the selected_permission is one of the valid keys:

 

$request->validate([
    'permissions' => ['required', 'array'],
    'selected_permission' => ['required', 'string', 'in_array_keys:permissions'],
]);
Enter fullscreen mode Exit fullscreen mode

This is a more concise way to handle this common validation scenario.

5. isset() with Multiple Parameters

Did you know that PHP's isset() function can accept multiple parameters? This is a handy and often overlooked feature.

The function will return true only if all the provided variables are set and not null.

if (isset($data, $meta, $items)) {
    // This code will only execute if all three variables are set.
}
Enter fullscreen mode Exit fullscreen mode

This can simplify your conditional checks and make your code more readable by avoiding nested if statements or multiple && checks.

6. Exception Methods for Granular Error Messages

Sometimes, a single exception class can handle multiple types of errors. You can define different methods within a custom exception class to provide specific error messages.

// In a custom exception class
class PaymentException extends Exception
{
    public static function cardExpired(): self
    {
        return new self('The credit card has expired.');
    }

    public static function insufficientFunds(): self
    {
        return new self('There are insufficient funds to complete the payment.');
    }
}

// In your controller
throw PaymentException::cardExpired();
Enter fullscreen mode Exit fullscreen mode

While you can also create separate exception classes for each scenario, this method allows you to group related exceptions under a single class.

7. The whereBetween() Query Builder Shortcut

Laravel 12.21 introduced a small but powerful syntactic sugar to the query builder: whereBetween(). This method simplifies queries where you need to check if a value falls between two other values.

Instead of this:

$query->where('value', '>=', $from)
      ->where('value', '<=', $to);
Enter fullscreen mode Exit fullscreen mode

You can write this:

 

$query->whereBetween('value', [$from, $to]);
Enter fullscreen mode Exit fullscreen mode

 

This makes your queries more concise and easier to read.

8. Str::password() for Secure Passwords 

When you need to generate a secure random password, the Str::password() helper is the ideal tool. It gives you fine-grained control over the generated string.

use Illuminate\Support\Str;

$password = Str::password(
    length: 12,
    letters: true,
    numbers: true,
    symbols: true,
    spaces: false,
);
Enter fullscreen mode Exit fullscreen mode

You can specify the length and whether the password should include letters, numbers, symbols, or spaces. This is a much better alternative to Str::random() for generating passwords.

9. Database-Backed Notifications

Laravel's notification system is incredibly flexible. While it's commonly used for emails, you can also store notifications directly in your database. This is perfect for creating in-app notification systems (like the alerts you see on many websites).

You can use methods like:

  • $user->unreadNotifications(): Retrieves all unread notifications.
  • $notification->markAsRead(): Marks a specific notification as read.
  • $user->markAsRead(): Marks all notifications for a user as read.

You can even send a notification to multiple channels at once (e.g., both email and the database) by specifying them in your notification class's via() method.

10. Nested Database Transactions

Laravel allows you to nest database transactions, and the framework will scope them to the outermost transaction. This means if a nested transaction fails, the entire chain of transactions will be rolled back.

 

DB::transaction(function () {
    // This is the outer transaction
    $user = User::create(...);

    DB::transaction(function () {
        // This is a nested transaction
        $profile = $user->profile()->create(...);

        if (!$profile) {
            // Throwing an exception here will roll back both transactions
            throw new Exception('Profile creation failed.');
        }
    });
});
Enter fullscreen mode Exit fullscreen mode

This can be useful if you have reusable actions that need to operate within their own transaction but also need to be called from a larger, overarching transaction.

11. Custom Validation Message Attributes

The default Laravel validation messages often include the word "field," as in "The name field is required." You can make these messages more user-friendly by simply removing the word "field" from the validation file.

Simply update your lang/en/validation.php file to change:

 

'required' => 'The :attribute field is required.',
Enter fullscreen mode Exit fullscreen mode

to:

'required' => 'The :attribute is required.',
Enter fullscreen mode Exit fullscreen mode

Now, your error message will read "The name is required," which is clearer and less technical for the end-user.

12. Grouping Tests in Pest with describe

If you use the Pest testing framework, you can use the describe() function to group related tests. This is not only for organization but also for sharing setup and teardown logic.

describe('User creation', function () {
    beforeEach(function () {
        // This runs before each test in this group
        $this->actingAs(User::factory()->create());
    });

    it('can create a user', function () {
        // ... test logic
    });

    it('validates user data', function () {
        // ... test logic
    });
});
Enter fullscreen mode Exit fullscreen mode

This feature, introduced in Pest v0.2.9, makes your tests more organized and maintainable, especially for complex features.

Have you learned anything new from this list? Which of these tips will you be adding to your own Laravel projects? Let us know in the comments!

 

🚀 Want more powerful Laravel tips like this?
Join my newsletter and stay ahead with exclusive insights 👉 LaravelDailyTips.com 💡

Top comments (0)