Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

untymage's avatar

Modify query within a variable

How can i modify a variable when it have query builder ? i mean:

$post =  Post::where('id', 1);

if(myCondition){
    $post->first();
}

if(anotherCondition){
    $post->where('body', 'example');
}

dd($post);

$post always return query builder instance, How can i avoid this :

$post =  Post::where('id', 1);

if(myCondition){
   $post =  $post->first();
}

if(anotherCondition){
    $post = $post->where('body', 'example')->first();
}

dd($post);

How to avoid re-assing variable to itself ?

More info https://laracasts.com/discuss/channels/laravel/modify-query-within-a-variable?page=1#reply=679127

0 likes
19 replies
untymage's avatar

I edited my post, I just wanted to know how can avoid re-assign variable to it self on condition (just like transform on the collection)

fylzero's avatar

@untymage You can't call first() before finishing the query. first() calls get(). It should be the last step in your query.

Also, if you first condition is not met and the second one is, you are not calling get() or first().

Something like this maybe...

$post = Post::where('id', 1);

if(anotherCondition){
    $post = $post->where('body', 'example');
}

$post->first();

dd($post);
1 like
untymage's avatar

How to avoid re-assign variable to it self in the conditions ? imagine i have 10 condition so i have to assign $post each to it self

Tray2's avatar

This line will always give you an instance of the query class

$post = $post->where('body', 'example');

Since you don't execute it with a first or get.

untymage's avatar

I edited my post, I just wanted to know how can avoid re-assign variable to it self on condition (just like transform on the collection)

Snapey's avatar

In the first line you are creating a Builder object

Then through subsequent lines, you are applying additional constraints to the query Builder object

Finally you use the object to execute the query.

You are not re-assigning anything with @fylzero example.

forrestedw's avatar

This will always return a single Post model (assuming the query finds a match):

$post =  Post::where('id', 1);

if(myCondition){
    $post->first();
} else if(anotherCondition){
    $post->where('body', 'example')->first();
} else {
    // default behaviour (I can't guess what that would be)
}

dd($post);
fylzero's avatar

@untymage I'm just stabbing in the dark because your question isn't clear.

If you don't want the initial value to be a QueryBuilder instance then don't define it as such.

$post = null;

If you don't want where('id', 1) to be the default but want it to be QueryBuilder, just start off as a query...

$post = Post::query();

if (condition) {
    $post = $post->where('id', 1);
}
untymage's avatar

@fylzero thanks man, Sorry if i wasn't clear, i'll try my best this time look at this :

$post = Post::query();

if (condition) {
    $post = $post->where('id', 1);
}

if (condition) {
    $post = $post->where('id', 2);
}

if (condition) {
    $post = $post->where('id', 3);
}

if (condition) {
    $post = $post->where('id', 4);
}

10 another conditions...

As you can see every time we have to assign $post to it self i mean this part:

$post = $post-> ...

So just imagine if i had 20 condition every time i have to do that... So i just wanted to know is it possible to avoid that ? for example in the laravel collection we can do this without re-assinging collection to itself:

$collection = collect($data);

if (condition) {
    $collection->transform(...); No need to assign $collection = $collection->...
}

if (condition) {
    $collection->transform(...); No need to assign $collection = $collection->...
}

the transform modify the collection so we dont have to assign variable just like this $collection = $collection->... every time

Tray2's avatar

You can always build the conditions into an array and then send it into the where clause.

Something like this

$searchCondition = 'Lupin';

$criterias = [];

if($searchCondition == 'Lupin') {
	array_merge($criterias, ['title' => $searchCondition]);
}

$result = Book::where($criterias)->get();

That way you can add multiple conditions.

Or make it even simpler pass the array in

$searchCondition = ['title' => 'Lupin', 'pages' => '100'];

$result = Book::where($searchCondition)->get();

fylzero's avatar

@untymage When I started writing these type of queries I also thought it was strange but you have to do it that way or you won't be "concatenating" the Query Builder query. That's kind of how I think of it now. You're assigning a variable and you can't just chain to that assigned variable when using conditionals. This is how you stack the blocks forward. If that makes sense.

ankush981's avatar

you can use like this:-

$post = Post::when($condition, function($q){ $q->where('id', $condition); })->when($condition, function($q){ $q->where('id', $condition); })->get('id', 'name', 'etc');

1 like

Please or to participate in this conversation.