Skip to content
Advertisement

Laravel URL Filtering with GET

I am building a simple Laravel routing to display an array when someone goes to http://127.0.0.1:8000/planets

But I need to make a filter to check the array on what request has been send on the URL. For example: http://127.0.0.1:8000/planets?planet=mars

I need to make sure that if a GET parameter is present, you filter the array based on whether the planet name is in it. This way we can filter the results of the page a little faster.

The code I currently have Web.php:

<?php

use IlluminateSupportFacadesRoute;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/


Route::get('/planets', function () {
    
    $planets = [
        [
            'name' => 'Mars',
            'description' => 'Mars is the fourth planet from the Sun and the second-smallest planet in the Solar System, being larger than only Mercury.'
        ],
        [
            'name' => 'Venus',
            'description' => 'Venus is the second planet from the Sun. It is named after the Roman goddess of love and beauty.'
        ],
        [
            'name' => 'Earth',
            'description' => 'Our home planet is the third planet from the Sun, and the only place we know of so far thats inhabited by living things.'
        ]
    ];
    
    return view('welcome', ['planets'=>$planets]);
});

And my welcome blade:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Laravel</title>
        <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">

        <style>
            html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}[hidden]{display:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}a{color:inherit;text-decoration:inherit}svg,video{display:block;vertical-align:middle}video{max-width:100%;height:auto}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-t{border-top-width:1px}.flex{display:flex}.grid{display:grid}.hidden{display:none}.items-center{align-items:center}.justify-center{justify-content:center}.font-semibold{font-weight:600}.h-5{height:1.25rem}.h-8{height:2rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.leading-7{line-height:1.75rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-4{margin-top:1rem}.ml-4{margin-left:1rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-6xl{max-width:72rem}.min-h-screen{min-height:100vh}.overflow-hidden{overflow:hidden}.p-6{padding:1.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-8{padding-top:2rem}.fixed{position:fixed}.relative{position:relative}.top-0{top:0}.right-0{right:0}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.text-center{text-align:center}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.w-5{width:1.25rem}.w-8{width:2rem}.w-auto{width:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm:rounded-lg{border-radius:.5rem}.sm:block{display:block}.sm:items-center{align-items:center}.sm:justify-start{justify-content:flex-start}.sm:justify-between{justify-content:space-between}.sm:h-20{height:5rem}.sm:ml-0{margin-left:0}.sm:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm:pt-0{padding-top:0}.sm:text-left{text-align:left}.sm:text-right{text-align:right}}@media (min-width:768px){.md:border-t-0{border-top-width:0}.md:border-l{border-left-width:1px}.md:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg:px-8{padding-left:2rem;padding-right:2rem}}@media (prefers-color-scheme:dark){.dark:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.dark:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.dark:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.dark:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.dark:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.dark:text-gray-500{--tw-text-opacity:1;color:#6b7280;color:rgba(107,114,128,var(--tw-text-opacity))}}
        </style>

        <style>
            body {
                font-family: 'Nunito', sans-serif;
                font-weight: bolder;
            }
        </style>
    </head>
    <body class="antialiased">

@foreach ($planets as $planet)
    <ul>
        <li>{{$planet['name']}}</li>
        <p>{{$planet['description']}}</p>
    </ul>
@endforeach
    
    </body>
</html>

Advertisement

Answer

The Laravel IlluminateHttpRequest object has a query method on it that allows you access to query string parameters.

$request->query('param');

So for your scenario and given the URL example.com/planets?names=mars,earth, you would grab the planet names as follows:

$names = $request->query('names');

That would result in the $names variable having the string value mars,earth.

From here you want to use explode to separate out the individual names:

$names = explode(',', $request->query('names');

This time $names is an array with two elements, mars and earth.

Then you can use the whereIn method available on Laravel Collections to filter your planets to just those found in the $names array.

$planets = collect($planets)
    ->whereIn('name', array_map(fn($name) => strtolower($name), $names))
    ->all();

Note that for the above to work I have done two things.

  1. I made all the planet names in your $planets array lower case
  2. I use array_map to convert the query parameter values to lower case for comparing with the $planets array

This should mitigate casing issues (so people typing mars, MARS or other variations) should be captured correctly.

Put it all together and you should have something like the following:

use IlluminateHttpRequest;
use IlluminateSupportFacadesRoute;

Route::get('/planets', function (Request $request) {

    $planets = [
        [
            'name' => 'mars',
            'description' => 'Mars is the fourth planet from the Sun and the second-smallest planet in the Solar System, being larger than only Mercury.'
        ],
        [
            'name' => 'venus',
            'description' => 'Venus is the second planet from the Sun. It is named after the Roman goddess of love and beauty.'
        ],
        [
            'name' => 'earth',
            'description' => 'Our home planet is the third planet from the Sun, and the only place we know of so far thats inhabited by living things.'
        ]
    ];

    if ($request->query('names')) {
        $names = explode(',', $request->query('names'));
        $planets = collect($planets)->whereIn('name', array_map(fn($name) => strtolower($name), $names))->all();
    }

    return view('welcome', compact('planets'));
});
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement