tags:

views:

507

answers:

2

I have been using PHP for a while now and I have always wondered how to represent a single form to handle updates and inserts into a database. At the present, I am using 2 seperate forms to do this and they both have basically the same information and textboxes, etc. I know there is a better way of handling this but I'm not sure what that is.

I have tried to use a single form in the past but the html mixed with the php looks terrible and is really hard to maintain. I am after "clean" and neat.

Can someone please put me on the right track.

One of the things that I have to use are POST values if the user submits the form and the validation didn't pass, the refresh should not wipe out the already entered values.

+5  A: 

You could use a single form, with a hidden field for id. If this field is set - then you should update the $_POST['id'] record with the rest of the form. If the field is not set (that is, it has value=""), you should insert the form data to a new record.

You'll set the id field according to the action, for example /data/edit/1 will set the id field to , and /data/new` will not set value to it.

For example, your view could be

<form action="/data/edit/1">
<input type="hidden" value="<?php echo $data->id; ?>" />
<input type="text" value="<?php echo $data->name; ?>" />
</form>

In case of a new record, call your view with the following data

$data->id = '';
$data->name = '';

In case of a known record, simply init the $data object with the data

$data->id = $record_id;
$data->name = $record_name;
Elazar Leibovich
Hi Elazar, thanks for the help. Is there an example or can you provide a link so that I can see exactly what you mean? It makes sense but I can't picture it. I don't see that your suggestion is much different than how I was doing it in the first place.
Don't forget to check that the current user owns that ID
Antony Carthy
Why even have an id field if the action for the edit contains the id anyway?
rojoca
@rojoca: No need to have an id, but it's nicer IMHO to always have the id, and mark a new one as "id = ''", than to put an if inside the form that would decide whether or not to put an id field.
Elazar Leibovich
@Elazar: There is no [if] in the form because there is no id field. The id is in the action /data/edit/1 if it's an edit. Also if you have the id in the URL and you also submit the id through the form you have to validate the id twice. If your id is in the URL then your routing code can validate and authenticate the request before it starts processing the post data.
rojoca
@rojoca: Your design means you wouldn't submit the form always to the same url. So instead of putting the id in a field, you'll put it in the url. This is also possible, but I don't see any great advantage either ways. (In my design +1 for constant URL to send data to, your design +1 for authentication). I'm not sure why is it so good that the routing code will handle authentication though.
Elazar Leibovich
+1  A: 

This is how I would probably do it without using any other frameworks/libraries etc. It is basically what Elazar Leibovich said.

  <?php
    //id is zero or a record id depending on whether updating or inserting
    //an existing record could be edited using edit.php?id=10
    //if the id GET parameter is omitted a new record will be created
    $id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
    $error = '';

    if ($id) {
        //this array would be in the same format as the one below
        $record = fetchRecordFromDb($id);    
    } else {
        $record = array( 'field1' => 'default value', 'field2' => 'some other default' );    
    }

    //allow POST data to override what is already in the form
    foreach ($record as $key => $value) {
        if (isset($_POST[$key])) {
            $record[$key] = $_POST[$key];
        }
    }

    if (isset($_POST['submit'])) {
        if (!validateForm()) {
            $error = 'Some form error';
        } else {
            if ($id) {
                updateRecord($id, $record);
            } else {
                insertRecord($record);
            }

            //ok, redirect somewhere else
            header('Location: http://somewhere');
            exit();
        }
    }

    ?>

    <form method="post">
       <?php echo $error; ?>
       <input type="hidden" name="id" value="<?php echo $id; ?>">
       <input type="text" name="field1" value="<?php echo htmlspecialchars($record['field1']); ?>"><br />
       <input type="text" name="field2" value="<?php echo htmlspecialchars($record['field2']); ?>"><br />
       <input type="submit" name="submit">
    </form>
Tom Haigh