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

Ligonsker's avatar

Which of the following URL syntax is better for downloading files from the server?

Hello, Assuming a user can download certain files based on their names, which would be better to get it: path parameters or query parameters? i.e.:

  1. example.com/downloads/{file_name}
  2. example.com/downloads?file_name={file_name}

Which is better for this situation?

Thanks

0 likes
15 replies
tykus's avatar

Either. However, if the URL represents an individual document resource, then example.com/downloads/{file_name} would be consistent with your typical Laravel application's Resource routing.

1 like
Ligonsker's avatar

@tykus thanks! Just more information if that matters: the name is passed to the backend to instantiate a Laravel Excel object. Not directly the file name. For example there's a class Invoice.php then I'll use the query parameter to call it

Snapey's avatar

why does your app need to get involved at all?

1 like
Ligonsker's avatar

@Snapey (and @tykus) I'm using the name parameter to recognize the marching Laravel-Excel class for that file

For example if I have an Invoice.php class that is a Laravel-Excel class, then I'll get the name from the route (it's a download link with one of the options mentioned above).

So the route would either be example.com/downloads/invoice or example.com/downloads?file_name=invoice

Then in the controller I'll get the name into a variable and instantiate the Laravel Excel object:

$file_name = $request->input('file_name');
$class_name = "App\Exports\$file_name";
$obj = new $class_name();
martinbean's avatar

@Ligonsker I do hope you’re white-listing these class names, and not just blindly passing user-supplied input to PHP code 😬

1 like
Ligonsker's avatar

@martinbean haha these are predefined class names and not supplied by the user

@tykus nope just gave more information so maybe you would have more tips with this information but I think that not

martinbean's avatar

@Ligonsker You’re literally taking the input from the user…

$file_name = $request->input('file_name');

…creating a variable from it…

$class_name = "App\Exports$file_name";

…and then try to instantiate a class with that name:

$obj = new $class_name();

That’s blindly taking user input and then trying to execute it as PHP code.

1 like
Ligonsker's avatar

@Snapey thanks, why would you choose option 1? Just for educational purposes 😬

Snapey's avatar

@Ligonsker its tidier and not so obviously a parameter the user could try mucking about with

1 like
Snapey's avatar

haha these are predefined class names and not supplied by the user

if they are part of the URL then the user can change them to whatever they like - never trust user input.

2 likes
Ligonsker's avatar

@Snapey Ok correct, that's also what @martinbean said, I just didn't realize that it's not really an input. Also I am instantiating the class that must exist otherwise it would throw an error.

Would it then be enough to do validation as a alpha_num?

tykus's avatar

@Ligonsker you could simply make an array with a list of allowed classnames:

$file_name = $request->input('file_name');
$classname = "App\Exports\$file_name";
abort_unless(in_array($classname, [/* allowed class names */]), 400);
1 like
Ligonsker's avatar

@tykus sounds better, and I'll write a script that gets this array of classes from this specific namespace so I don't have to add them manually

Please or to participate in this conversation.