tags:

views:

453

answers:

4

I'm developing a php based CMS, and I'm currently re-writing it into a state that is usable for customers. (My first version was internal only; and a somewhat kludgy mess :P)

In my first version, I had a function called HandlePostBack() which checked for the existance of a significant number of $_POST variables - the submit button from each possible form. If it was set, then the appropriate command would be executed.

I'm wondering if there is a better way? I could migrate to a switch, and look for a single $_POST variable included in each form, and then execute the command. A minimum of code would be nice, so I can extend the system quickly and easily.

+1  A: 

I would try to do it differently. Why do you need a central point for all your posts? This is really bad practice.

Don't try to improve over it, try rethinking the whole idea of having a central point and get rid of it.

Marius Burz
+2  A: 

It seems to me your form system could use a bit of a reworking. Why not represent each form as a class, and make the HandlePostBack function a method? Then you could detect the form that's been submitted and handle it.

class ProfileForm extends Form {
    private $form_items = array(
        new FormItem('name', 'datatype', 'other_parameters'),
        new FormItem('another_name', 'datatype', 'other_parameters'),
        ...
    );

    public function render() {
        ...
    }

    public function handlePostData() {
        ...
    }
}

If you use a standard format for your submit button IDs (something like <form_name>_submit, you can do something like this on submission:

foreach ($_POST as $key => $value) {
    if (substr($key, strlen($key) - 7) == '_submit') {
        $className = ucfirst(substr($key, 0, strlen($key) - 7)) . 'Form';
        $form = new $className();
        $form->handlePostBack();
    }
}
Samir Talwar
This is exactly what I was looking for. There are also some other interested ideas here, too.
EvilChookie
A: 

In similar cases I usually use hidden input 'form_action', so I can use different submit-buttons to provide different actions (like 'add', 'edit', 'delete' etc...)

<input type="submit" onclick="assignAction(this.form, 'myItem_delete');"...>

Then on the server side i can split action by "_" and use 1-st part as form class identifier (i.e. for simple switch, or reflection...), and the second part says what method of form class should handle the postback data. In common code is like this

$handler = explode('_', $_POST['form_action']);
$className = $handler[0]; // not secure, but simple enough for example
if (class_exists($className))
{
   $form = new $className();
   $method = $handler[1]; // again too simple
   if (method_exists($form, $method))
   {
      $form->$method($_POST, $other_params...);
   }
}

Sure, the example is too simple. But it's common idea works fine, as for me.

Jet
The general idea of having a hidden "action" element is pretty common, but your method seems to unnecessarily rely on javascript being available and enabled
Frank Farmer
Why not just use the button name? Use <input type="submit name="class_delete" value="Delete" /> in the HTML and then just check: if (isset($_POST['class_delete']) { new Class()->delete($_POST, $other_params); }
Samir Talwar
Why not? You can use it if you like it. But i prefer to create onClick handlers for buttons. In complex projects it's often nessecary do perform some additional tasks before submitting. But that's my preference...
Jet
A: 

One way to do this sort of thing is to route your requests to classes and if the $_SERVER['REQUEST_METHOD'] == 'POST' then call the post() method on that class. This would mean that the action on your form would map directly to some class which had a post method.

// routed from URL: /users
class Users implements Resource
{
    public function post() 
    {
        // do your post here
    }

    public function get()
    {
        // do it for GET requests too
    }
}

While this is essentially the same thing as what you were doing before, it can let you organize your code a little better in that you can deal with requests in a generic way:

$resource = $resourceFactory->getResource($url);
$method = strtolower($_SERVER['REQUEST_METHOD']);
$response = $resource->$method(); // eg: $resource->post();
$response->respond();

Have a look at the recess framework which takes this idea a long way.

rojoca