1
\$\begingroup\$

I'm currently creating a utility that is heavily AJAX orientated. I have a page called ajax.php which is handling all POST requests. It switches by the provided command, checks all the arguments exist then passes it off to the relevant class e.g.

case 'addperson':
    $name = $_POST['name'] ?? die('{"result":0, "data":"name not provided"}');
    $email = $_POST['email'] ?? die('{"result":0, "data":"email not provided"}');

    try {
        (new Person(new DB()))->addPerson($name, $email);
    }
    catch (Exception $e) {
        exit("{\"result\":0, \"data\":\"{$e->getMessage()}\"}");
    }
    exit('{"result":1}');

This works fine but was wondering how people generally go about handling big lists of $_POST arguments. Would you do the above, potentially have 20 lines of $arg = $_POST['arg'] or perhaps something like,

foreach (['name', 'state'] AS $arg) {
  $$arg = $_POST[$arg] ?? die("{\"result\":0, \"data\":\"$arg not provided\"}");
}

The other option is to not check it exists at all.

list($a, $b, $c) = [$_POST['a'], $_POST['b'], $_POST['c']];

Since I'm the only one working on this project, i can ensure i always provide the necessary data but this just seems bad and may create future issues (especially if I get a few helpers!)

Finally, what do you think about having the ajax.php confirm all arguments have been provided (not validated) rather than just checking for the command and passing off the $_POST array to a class which will then confirm all arguments have been provided?

\$\endgroup\$

3 Answers 3

2
\$\begingroup\$

To answer the specific question: if you know the arguments in advance (as you should), you can loop over them and add them to an arguments-array instead.

Always, ALWAYS, validate input. Not just to check that it is there but also that it confirms to expectations.

\$\endgroup\$
1
  • \$\begingroup\$ There is definitely validation, I just do it in the class. The idea in my head was ajax should only confirm the parameter was passed but not validate the data itself. The reason being i might later call the class via something else (CLI, cronjob etc) \$\endgroup\$
    – Lokicat
    Commented Jun 8, 2016 at 6:30
1
\$\begingroup\$

Instead of handling the different kind of actions inside case statements, I suggest to move the handling logic to specialized functions, for example:

case 'addperson':
    handleAddPerson();

This implies NO to the idea of having a list of all the possible parameter names such as name and email and copying them to local variables. No, each handling method should encapsulate their requirements.

And yes, that will mean you will have multiple lines in the form of $arg = $_POST['arg'], and that's fine. However, the error handling logic of a missing parameter should not be repeated on each line, it should be moved to a helper method, and used in this fashion:

$name = validatedArg('name');

Here's a rough outline of one way of working with forms (inspired by the Shango framework). A Form class defines the list of fields and their types, with an isValid method that checks each field and returns a boolean, while storing cleaned values and the details of validation errors. When isValid returned false, you call a getErrors method to get the stored details of what went wrong, and inform the user. Using this approach in your example, you would have a specialized AddUserForm, inheriting the common validation behavior in Form, and defining the required fields and their specialized validation logic if any. This is one good way of working with forms.

\$\endgroup\$
1
  • \$\begingroup\$ I was previously considering having, for example, a personHandler() and personController kind of setup where Handler would validate all data being and then provide to the controller for actual processing. Handler would expect an array of $options which could be the $_POST or standard array provided by CLI... might be the way I go down this road! \$\endgroup\$
    – Lokicat
    Commented Jun 9, 2016 at 22:11
0
\$\begingroup\$

I would be thinking about moving away from a form-encoded post query string paradigm and into the paradigm of passing application data around using JSON. This would allow you to easily pass array or objects data structures between front-end and backend. You could then more simply do something like saturate a specific class of the object being passed with all validation for data being passed licing within the class definition.

\$\endgroup\$
1
  • \$\begingroup\$ So send data from client <-> server as a single JSON object via a form string? I'm not sure if this will change much as I still will have to validate all data being parsed anyways. Am I missing something? \$\endgroup\$
    – Lokicat
    Commented Jun 9, 2016 at 22:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.