You can shove them in a struct... but that's kind of just putting lipstick on a pig. It doesn't change how much stuff you're passing, just how you're passing it.
If there's a clear line between parts of the function that need different subsets of data, you can split it into multiple functions. But it doesn't look like that would particularly help in the case of the above example.
If a function needs a bit of data, then you have to pass it. *shrug*
No. It doesn't even have *pargs. Besides, that wouldn't do anything about passing too many arguments, it would just make it more difficult to tell what arguments are being passed.
As a rule of thumb, if a function takes too many arguments you should consider:
Is the function doing too much? If so, perhaps you could split the logic in several, smaller functions instead
Group the arguments into structs in a way that feels logically consistent
If the function is for creating a resource and inserting it in the database, consider splitting the logic for building the resource from the insertion in the database by receiving an instance of the object or a builder instead (This is a variant of point 1)
In your example case, I would certainly go with #3.
4 parameters isn't really a lot. But if you're finding that there's several functions which take the same group of parameters for similar reasons, it's probably a good idea to put them together in a struct.
Well, if you have a bunch o attributes you a have bunch of attributes, no way around it.
This might be an indication of your tables being to big, but maybe they aren't, sometimes you just have to do the straight forward thing.
In this particular case though, I think its a good idea to create a struct with these parameters, it also adds some other advantages like being able to add behavior to the struct so you can transform it, or validate it.