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

mleontenko's avatar

Optional search parameter breaks query

I have the following query with some optional parameters that works fine:

$query = ObrazacProcjeneVrste::where('znanstveno_ime', 'LIKE', "%{$znanstvenoIme}%");
        if($skupina != 0) {
            $query = $query->whereHas('skupine', function($q) use($skupina) {
                $q->where('skupina_id', $skupina);
            });
        }
        if($datumDo != null) {
            $query = $query->where('created_at', '<=', $datumDo);
        }

        $query = $query->where('status', 'Prihvaćen')->whereNotIn('id', $id_eliminacija);
            
        $obrasci = $query->orderBy('datum_azuriranja', 'desc')->paginate(50);

If I add one more optional parameter that checks five columns for searched value, it does not take into account last filter ($query->where('status', 'Prihvaćen')...):

$query = ObrazacProcjeneVrste::where('znanstveno_ime', 'LIKE', "%{$znanstvenoIme}%");
        if($skupina != 0) {
            $query = $query->whereHas('skupine', function($q) use($skupina) {
                $q->where('skupina_id', $skupina);
            });
        }
        if($datumDo != null) {
            $query = $query->where('created_at', '<=', $datumDo);
        }

        if($taksonomija != null) {
            $query = $query->where('razred', 'LIKE', "%{$taksonomija}%")
                            ->orWhere('podrazred', 'LIKE', "%{$taksonomija}%")
                            ->orWhere('nadred', 'LIKE', "%{$taksonomija}%")
                            ->orWhere('red', 'LIKE', "%{$taksonomija}%")
                            ->orWhere('porodica', 'LIKE', "%{$taksonomija}%");
        }

        $query = $query->where('status', 'Prihvaćen')->whereNotIn('id', $id_eliminacija);
            
        $obrasci = $query->orderBy('datum_azuriranja', 'desc')->paginate(50);

What am I doing wrong here?

0 likes
15 replies
laracoft's avatar

@mleontenko What if you do this?

$query = ObrazacProcjeneVrste::where('znanstveno_ime', 'LIKE', "%{$znanstvenoIme}%");
if($skupina != 0) {
    $query = $query->whereHas('skupine', function($q) use($skupina) {
        $q->where('skupina_id', $skupina);
    });
}
if($datumDo != null) {
    $query = $query->where('created_at', '<=', $datumDo);
}

$query = $query->where('status', 'Prihvaćen')->whereNotIn('id', $id_eliminacija);

if($taksonomija != null) {
    $query = $query->where('razred', 'LIKE', "%{$taksonomija}%")
                    ->orWhere('podrazred', 'LIKE', "%{$taksonomija}%")
                    ->orWhere('nadred', 'LIKE', "%{$taksonomija}%")
                    ->orWhere('red', 'LIKE', "%{$taksonomija}%")
                    ->orWhere('porodica', 'LIKE', "%{$taksonomija}%");
}

$obrasci = $query->orderBy('datum_azuriranja', 'desc')->paginate(50);
mleontenko's avatar

@laracoft it still ignores other filters. It looks like something in that block of code makes it override other query parameters.

laracoft's avatar
$query = ObrazacProcjeneVrste::where('znanstveno_ime', 'LIKE', "%{$znanstvenoIme}%");
if($skupina != 0) {
    $query = $query->whereHas('skupine', function($q) use($skupina) {
        $q->where('skupina_id', $skupina);
    });
}
if($datumDo != null) {
    $query = $query->where('created_at', '<=', $datumDo);
}

$query = $query->where('status', 'Prihvaćen')->whereNotIn('id', $id_eliminacija);

if($taksonomija != null) {
    $query = $query->where('razred', 'LIKE', "%{$taksonomija}%")
                    ->orWhere('podrazred', 'LIKE', "%{$taksonomija}%")
                    ->orWhere('nadred', 'LIKE', "%{$taksonomija}%")
                    ->orWhere('red', 'LIKE', "%{$taksonomija}%")
                    ->orWhere('porodica', 'LIKE', "%{$taksonomija}%");
}

dd($query->toSql());	// show us the SQL

$obrasci = $query->orderBy('datum_azuriranja', 'desc')->paginate(50);
Sinnbeck's avatar

Dont overwrite your $query variable.. It remembers! :D

$query = ObrazacProcjeneVrste::where('znanstveno_ime', 'LIKE', "%{$znanstvenoIme}%");
//do stuff
$query->where('created_at', '<=', $datumDo); //just updates the $query variable..
mleontenko's avatar

@laracoft

This is $query->toSql for my version:

"select * from "obrasciProcjeneVrste" where "znanstveno_ime"::text LIKE ? and "razred"::text LIKE ? or "podrazred"::text LIKE ? or "nadred"::text LIKE ? or "red"::text LIKE ? or "porodica"::text LIKE ? and "status" = ? and "id" not in (?, ?, ?)

And this is for yours:

"select * from "obrasciProcjeneVrste" where "znanstveno_ime"::text LIKE ? and "status" = ? and "id" not in (?, ?, ?) and "razred"::text LIKE ? or "podrazred"::text LIKE ? or "nadred"::text LIKE ? or "red"::text LIKE ? or "porodica"::text LIKE ? "
laracoft's avatar

@sinnbeck does it actually impact? I didn't think it will affect the outcome.

$query = ObrazacProcjeneVrste::where('znanstveno_ime', 'LIKE', "%{$znanstvenoIme}%");
if($skupina != 0) {
    $query->whereHas('skupine', function($q) use($skupina) {
        $q->where('skupina_id', $skupina);
    });
}
if($datumDo != null) {
    $query->where('created_at', '<=', $datumDo);
}

$query->where('status', 'Prihvaćen')->whereNotIn('id', $id_eliminacija);

if($taksonomija != null) {
    $query->where('razred', 'LIKE', "%{$taksonomija}%")
                    ->orWhere('podrazred', 'LIKE', "%{$taksonomija}%")
                    ->orWhere('nadred', 'LIKE', "%{$taksonomija}%")
                    ->orWhere('red', 'LIKE', "%{$taksonomija}%")
                    ->orWhere('porodica', 'LIKE', "%{$taksonomija}%");
}

dd($query->toSql());	// show us the SQL

$obrasci = $query->orderBy('datum_azuriranja', 'desc')->paginate(50);
laracoft's avatar

@mleontenko can you tell what is causing your issue from the SQL already?

As far as I'm concerned, all your filters are there in the query. It does not look like an issue with PHP query builder code. Probably more to your SQL logic, but I do not understand the variables you are using.

mleontenko's avatar

@laracoft I think it would work if I added the part below in parentheses, but I dont know how to do it...

and "razred"::text LIKE ? or "podrazred"::text LIKE ? or "nadred"::text LIKE ? or "red"::text LIKE ? or "porodica"::text LIKE ?
laracoft's avatar
$query = ObrazacProcjeneVrste::where('znanstveno_ime', 'LIKE', "%{$znanstvenoIme}%");
if($skupina != 0) {
    $query->whereHas('skupine', function($q) use($skupina) {
        $q->where('skupina_id', $skupina);
    });
}
if($datumDo != null) {
    $query->where('created_at', '<=', $datumDo);
}

$query->where('status', 'Prihvaćen')->whereNotIn('id', $id_eliminacija);

if($taksonomija != null) {
    $query->where(function($q) {
        $q->where('razred', 'LIKE', "%{$taksonomija}%")
            ->orWhere('podrazred', 'LIKE', "%{$taksonomija}%")
            ->orWhere('nadred', 'LIKE', "%{$taksonomija}%")
            ->orWhere('red', 'LIKE', "%{$taksonomija}%")
            ->orWhere('porodica', 'LIKE', "%{$taksonomija}%");
    });
}

dd($query->toSql());	// show us the SQL

$obrasci = $query->orderBy('datum_azuriranja', 'desc')->paginate(50);
mleontenko's avatar

@laracoft That looks good, but I get "Undefined variable: taksonomija" if I use it in function like that.

laracoft's avatar
laracoft
Best Answer
Level 27

@mleontenko Add the use ($taksonomija)

$query = ObrazacProcjeneVrste::where('znanstveno_ime', 'LIKE', "%{$znanstvenoIme}%");
if($skupina != 0) {
    $query->whereHas('skupine', function($q) use($skupina) {
        $q->where('skupina_id', $skupina);
    });
}
if($datumDo != null) {
    $query->where('created_at', '<=', $datumDo);
}

$query->where('status', 'Prihvaćen')->whereNotIn('id', $id_eliminacija);

if($taksonomija != null) {
    $query->where(function($q) use ($taksonomija) {
        $q->where('razred', 'LIKE', "%{$taksonomija}%")
            ->orWhere('podrazred', 'LIKE', "%{$taksonomija}%")
            ->orWhere('nadred', 'LIKE', "%{$taksonomija}%")
            ->orWhere('red', 'LIKE', "%{$taksonomija}%")
            ->orWhere('porodica', 'LIKE', "%{$taksonomija}%");
    });
}

dd($query->toSql());	// show us the SQL

$obrasci = $query->orderBy('datum_azuriranja', 'desc')->paginate(50);
MichalOravec's avatar

Naming for variables classes database table, column name etc shoould be everitime just in English.

$obrasci = ObrazacProcjeneVrste::where('znanstveno_ime', 'LIKE', "%{$znanstvenoIme}%")
    ->when($skupina != 0, function ($query) use ($skupina) {
        return $query->whereHas('skupine', function ($query) use ($skupina) {
            $query->where('skupina_id', $skupina);
        });
    })->when($datumDo, function ($query, $datumDo) {
        return $query->where('created_at', '<=', $datumDo);
    })->when($taksonomija, function ($query, $taksonomija) {
        return $query->where(function ($query) use ($taksonomija) {
            $query->where('razred', 'LIKE', "%{$taksonomija}%")
                ->orWhere('podrazred', 'LIKE', "%{$taksonomija}%")
                ->orWhere('nadred', 'LIKE', "%{$taksonomija}%")
                ->orWhere('red', 'LIKE', "%{$taksonomija}%")
                ->orWhere('porodica', 'LIKE', "%{$taksonomija}%");
        });
    })->where('status', 'Prihvaćen')
    ->whereNotIn('id', $id_eliminacija)
    ->orderByDesc('datum_azuriranja')
    ->paginate(50);

Docs: https://laravel.com/docs/8.x/queries#conditional-clauses and https://laravel.com/docs/8.x/queries#parameter-grouping

mleontenko's avatar

@michaloravec will definitely check it out, seems like a better practice. laracroft's answer was what I was exactly looking for at the time. Still getting the hang of laravel, the syntax for queries easily gets complex here...

Please or to participate in this conversation.