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

lprice's avatar
Level 21

Empty fields in request URL.. how to filter them out?

When I build e.g. a search form for my user model with some fields (e.g. email, name, status, role) which submits to a controller which then queries the DB and return the result in a view, everything works fine. But the url also lists the fields which haven't been filled out. e.g.

http://foundation.com/user?email=&name=peter&activated=&newsletter=true&status=&role=5

What can one do to remove those empty parameters from the URL and only show the parameters that had values and that it looks like this:

http://foundation.com/user?name=peter&role=5

Thanks!

0 likes
16 replies
jekinney's avatar

As @Snapey mentioned use a post request with the Request class to get posted data from a form. This does two things in Laravel, keeps the url clean so users can't manipulate it or see the data and you can use the helpers like $request->has('email') etc to build your query with the information as needed.

lprice's avatar
Level 21

Hi, thanks for your replies, but doooonnn't "really" agree on it. :) @jlrdw you really don't need to stress on the actual url it is just an example with the role in it, so it can be anything.

First I'm using resourceful routes and controllers: http://laravel.com/docs/4.2/controllers#restful-resource-controllers. thus /user is a GET verb and is mapped to the index method of the respective controller. So doing a POST is not really what I want....

So to illustrate: when that URL is hit a page is returned with a table of all users and a search form on the side of the table. Now the user can fill in search criteria and hit the search button. That sends a GET request back to the same route and index method and the method can unpack the request to check for applicable search/filter values and apply it to the query.

Route:

resource( 'user', 'User\UserController'

Controller:

public function index( Request $request, User $user )
{
    //if email filter is set in the request apply it to the query
    if ( $request->has( 'email' ) ) {
        $userResult = $user->where( 'email', '=', $request->email );
    }

    //if name filter is set in the request apply it to the query
    if ( $request->has( 'name' ) ) {
        $userResult = $user->where( 'name', '=', $request->name);
    }

    return view( 'user.index' )->with( 'users', $userResult->get() );
}

As you can see I'm injecting the request so that I can access the request parameters and work with them.

URL that is produced when e.g. only 'name' is entered: http://foundation.com/user?email=&name=peter

It works like a charm, but if only I can get it to strip the empty "email=" out of the URL it would be cleaner.

@jekinney To hide the filters from the URL is also not optimal, because in a different scenario e.g. on front-end one actually would like to share a URL with its filters e.g. to another user, so that a similar view can be produced. Thus also in that scenario a POST will not be optimal.

I can probably create a stand-alone POST route and method which then calls back to the index method... but that is breaking the resouceful route pattern where a POST imply CREATE but like mentioned then you lose the ability to share the URL with filters, thus it is not really the solution yet. Hence I was wondering if there isn't a way to make the index method handle this elegantly.

@Snapey I found that also, but first wanted to avoid that as a last resort, because one can't assume that every project has e.g. jquery with it. I also found this method where you can configure the webserver... but also not sure if that is really elegant: http://stackoverflow.com/questions/5926673/how-can-i-remove-empty-fields-from-my-form-in-the-querystring

Also the concept of the filters in the url is nothing new, so first checking if I'm not missing anything: e.g. I'm sharing this URL with it's filter now with you: https://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=the+martian&rh=i%3Aaps%2Ck%3Athe+martian

Thanks!!!!

pmall's avatar

If you use POST I don't think empty fields are submitted.

Of course they are :)

@lprice Nobody care if there is empty values in your url. If your app works well with it then it is ok. Don't overthink.

A quick fix would be to use jquery to disable empty fields right before the form is submitted. But again, it is useless because nobody cares.

2 likes
lprice's avatar
Level 21

Hey @pmall

Yeah ... exactly! Ealier today I just decided.. hey screw it! it's working, and it's only Aesthetics. :) And often one can spend too much time on Aesthetics.

And yeah I do have JS to do the trick, here a snippet for anyone who wants to use it:

$('#'+$formId).submit(function() {
        $(this).find(":input").filter(function(){return !this.value;}).attr("disabled", "disabled");
});
// Un-disable form fields when page loads, in case they click back after submission or client side validation
$('#'+$formId).find(":input").prop("disabled", false);
gritter's avatar

I know it's an older discussion, but today I had the same problem. This is what I did: My search form uses a different route (not user.index, but let's say user.search). The controller method for user.search gets all search parameters, filters out the empty ones and redirects to user.index with the remaining (relevant) search parameters as GET params in the url -> nice and clean (sharable) url with only the neccessary information.

lprice's avatar
Level 21

@gritter yeah it is also a solution I was pondering about. And it was also that it's about having a clean sharable url.

My concern with the approach you followed and I pondered about, would be that I think you might be hitting the app/framework now twice every-time the url is opened?

But I'm not sure if it is really doing that... you might want to do a log entry in one of the general middleware and see if the middleware is hit twice? Would interest me if it is actually doing that, please let me know back.

If it is not doing that I think it is an more elegant solution. Can you post what your user.search methods looks like?

gritter's avatar

@lprice if I go directly to user.index (or go to the next page of the paginated list) it's 1 hit, but if I do a search which goes to user.search and then user.index it's 2 hits. For me this is ok, but if you are concerned about that, you have to search for another solution

lprice's avatar
Level 21

@gritter yeah it is what I thought would happen and that it will be 2 hits for 1 request. If it is a low traffic site you can probably live with it. Will respond back here when I can find a more elegant method.

gritter's avatar

@lprice stripping the empty parameters in a middleware should theoretically be more efficient (no need to instantiate controller twice etc.) I have tested it but don't see any measurable improvement (time in debugbar).

<?php

namespace App\Http\Middleware;

use Closure;

class StripEmptyParams {

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next) {
        $query = request()->query();
        $querycount = count($query);
        foreach ($query as $key => $value) {
            if ($value == '') {
                unset($query[$key]);
            }
        }
        if ($querycount > count($query)) {
            $path = url()->current() . (!empty($query) ? '/?' . http_build_query($query) : '');
            return redirect()->to($path);
        }
        return $next($request);
    }
}
1 like
gritter's avatar

@Snapey not a problem for me since my controller reacts only to params which are present in request and not empty, so a param not present (filtered out) in request for me is more or less the same as an empty param

Snapey's avatar

@gritter but say you did update($request->all()); then fields that are specified will be changed. Those database fields that were populated but now the user wants to clear, will be untouched.

gritter's avatar

@Snapey Sorry, no, I never said that. We're discussing submitting a SEARCH form, not an update form...

Please or to participate in this conversation.