Skip to content

Conversation

@Jacobs63
Copy link
Contributor

@Jacobs63 Jacobs63 commented Jun 12, 2025

When using the once helper and using object used variables in the callable, the spl_object_hash function is used.
This becomes an issue when using value objects, as each value object would very likely be unique, therefore trying to utilize the Onceable cache doesn't work, even if those value objects carry the same value inside.

Imagine a scenario, where we have a value object named PositiveInteger, which self-validates that the carried value is an integer of value higher than zero:

class PositiveInteger
{
    public function __construct(
        public readonly int $value,
    )
    {
        if ($value <= 0) {
            throw new \InvalidArgumentException('Value must be a positive integer.');
        }
    }
}

Now imagine we're trying to utilize the onceable helper for caching some database queries during the request/job:

    public function getTagFromId(PositiveInteger $id): ?string
    {
        return once(fn () => DB::table('xy')->where('id', $id->value)->soleValue('tag'));
    }

Calling the same method twice, passing a value object which carries the same value (and therefore returns the same result) would still make the callable execute twice, even though that would be undesired:

$id = new PositiveInteger(1);

// Query 1
$tag = $this->getTagFromId($id);

$id = new PositiveInteger(1);

// Query 2
$tag = $this->getTagFromId($id);

Instead now, we could tell our value object to specify it's hash, allowing the onceable helper to call a method on the used object dependency.

Now, we can do this instead:

class PositiveInteger implements ComputesOnceableHashInterface
{
    // ...

    public function computeOnceableHash()
    {
        return 'positive-integer' . ':' . $this->value;
    }
}

We've now effectively ensured that the database would only be called once.

@taylorotwell taylorotwell merged commit feccc98 into laravel:12.x Jun 12, 2025
60 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants