views:

117

answers:

4

I have to process about 20 POST-parameters, and I am not sure where to do that.

I could define each as an argument of the method on the model, and pass them from the controller when the method is called. This would result in quite a bit of work and make the function call less readable, due to the number of arguments.

Or I could call the method on the model, and just directly access the parameters.

Passing the parameters as arguments would give me more control over which parameters the function accesses, and the documentation would more self-explanatory. But if new parameters were added later on, they would have to be added to the end of the method call, as not to break every existing call. I imagine that this would become quite confusing if it happens a few times, as the arguments can't be logically grouped.

If I access the parameter in the model, no parameters have to be passed from the controller to the model, making the method call terser. But I have no control over the parameters that are accessed, as they can easily and without restrictions be added or removed. This would require greater discipline from the other developers, and I dislike to depend on that, because sooner or later someone is bound to "just (add|change|fix) this real quick".

I'm not sure which way to go. I tend to just do it all in the model, as this is faster to write, seems easier to maintain (no argument chaos) and conceptually fits better into my view of a model. On the other hand, I'm not sure my view of a model is correct, and if it will end in chaos if I depend on the other developers to always update the documentation after each change.

So, what should I do?

+1  A: 

Well, why can't you just accept an (associative) array as a parameter in that method of the model, and then pass it the whole $_POST array? At least in my opinion, it wouldn't break encapsulation.

EDIT: And if you don't like using associative arrays for that, you can also use so-called "Plain Old Objects" (objects which are only used to carry data, like structs in C). For example, if this involved saving a submitted registration form:

class UserData
{
    protected $name;
    protected $username;
    protected $password;

    public function getName() { /* <...> */ }
    public function setName() { /* <...> */ }
    /* other accessors go here */
}

class UserController extends Controller
{
    public function register()
    {
        $userData = UserData::create()
            ->setName($_POST['name'])
            ->setUsername($_POST['username'])
            ->setPassword($_POST['password']);
        Users::add($userData);
    }
}

This would allow you to use strict typing in Users::add and also make the process of documentation easier.

Ignas R
I added another solution to my answer as a response to this comment by the author: "The question is indeed similar, but I dislike passing associative arrays <...>"
Ignas R
As I answered to daff, I'd definitely favor passing objects to associative arrays, I'll keep your example in mind.
Thomas
A: 

I answered a similar question a while ago. Imho you should pass them e.g. as already proposed as an associative array (and make all the security checks before). In that way you can easily reuse your clases.

Daff
The question is indeed similar, but I dislike passing associative arrays. For documentation and restriction purpose they are basically useless, because I can't (or only with immense effort) document or restrict their content. They become a vessel for anything I want to throw in there.In this case, the verification is done in the controller, and if it fails, the method on the model will never be called. So passing an associative array holds no benefit to directly accessing $_POST.
Thomas
Well but it is a basic language structure of PHP, so why not using it. On the other hand if you have a proper OO design you would never have to process 20 parameters in one function call.
Daff
The problem I see with arrays is their "looseness", every developer can add or remove fields, and no one would notice. Classes are better, as they define how the data is structured. But in this case I'll follow karim79, as we don't change the values in the POST-Array.
Thomas
Well I understand and agree, I just don't like the Getter and Setter lunacy in an untyped language. Maybe you can find something in between e.g. with the PHP magic getters and setters and an array of allowed values.
Daff
A: 

Controller. Because request data and model manipulation is not the same thing. Putting request data-based logic in model will thus be required for all other possible requests, and thats bad

Artjom Kurapov
I don't think accessing parameters counts as logic. Validation etc. is already done the controller. Additionally, this method only makes sense for this one case, so there are no plans to reuse it for another request.
Thomas
+1  A: 

I've struggled with this same issue, and the solution I came up with is flexible, keeps my code reusable, and is tolerant of changes to the front-end: I like using setters. Of course, having a setter for every single value is a pain, so grouping data in logical ways helps:

$user = new User();
$user->setName($_POST['lastName'],$_POST['firstName']);
$user->setAddress($_POST['address1'],$_POST['address2'],$_POST['city'],$_POST['state'],$_POST['zip']);

You get the point. Once saved to object variables, you can then use these values in all of your object's methods.

Making your models reliant on superglobals is so inflexible. It also makes unit testing a pain.

Lucas Oman
This is an interesting suggestion. Sadly, in this case, I can't contextually group any parameters, so I'd have to have a setter for every parameter, and thus karim79 solution makes things easier.But I'll keep this in mind for other cases.
Thomas