4
\$\begingroup\$

I've seen few ways of processing forms with PHP. Whenever I am working with a form, I typically have two files: one for displaying the information (e.g. form.php) and the other for processing information (e.g. process_form.php). The latter uses sessions and simply redirects to the appropriate page depending on if the information submitted has been validated correctly or not. Below is a simple example of how I normally do things.

Form.php

<form name="form" action="process_form.php" method="POST">

  <? $field = 'name'; ?>
  <label for="<?= $field ?>">What is your name?</label>
  <input type="text" id="<?= $field ?>" name="<?= $field ?>" 
    value="<?= !isset($_SESSION['form'][$field]) ? $_SESSION['form'][$field] : '' ?>" maxlength="60" />
  <? if (!isset($_SESSION['errors'][$field])) { ?>
  <label class="error" for="<?= $field ?>"><?= $_SESSION['errors'][$field] ?></label>
  <? } ?>

  <? $field = 'age'; ?>
  <label for="<?= $field ?>">What is your age?</label>
  <input type="text" id="<?= $field ?>" name="<?= $field ?>" 
    value="<?= isset($_SESSION['form'][$field]) ? $_SESSION['form'][$field] : '' ?>" maxlength="2" />
  <? if (isset($_SESSION['errors'][$field])) { ?>
    <label class="error" for="<?= $field ?>"><?= $_SESSION['errors'][$field] ?></label>
  <? } ?>

  <? $field = 'email'; ?>
  <label for="<?= $field ?>">What is your email?</label>
  <input type="text" id="<?= $field ?>" name="<?= $field ?>" 
    value="<?= isset($_SESSION['form'][$field]) ? $_SESSION['form'][$field] : '' ?>" maxlength="100" />
  <? if (isset($_SESSION['errors'][$field])) { ?>
    <label class="error" for="<?= $field ?>"><?= $_SESSION['errors'][$field] ?></label>
  <? } ?>

  <input type="submit" value="Submit Your Information" />           
  <input type="hidden" name="hid_submit" value="1" />

</form>
<? 
if (isset($_SESSION['form'])) unset($_SESSION['form']);
if (isset($_SESSION['errors'])) unset($_SESSION['errors']);
?>

Process_form.php

$redirect_page = 'form.php';

$form   = array();
$errors = array();

if ($_SERVER['REQUEST_METHOD'] == 'POST') {

    $hid_submit = isset($_POST['hid_submit']) ? $_POST['hid_submit'] : NULL;

    if ($hid_submit) {

        $form['name'] = isset($_POST['name']) ? trim($_POST['name']) : '';
        $form['age'] = isset($_POST['age']) ? trim($_POST['age']) : '';
        $form['email'] = isset($_POST['email']) ? trim($_POST['email']) : '';

        // validate fields
        if (!valid($form['name'], 'name')) $errors['name'] = 'Please enter a valid name.';
        if (!valid($form['age'], 'age')) $errors['age'] = 'Please enter a valid age.';
        if (!valid($form['email'], 'email')) $errors['email'] = 'Please enter a valid email.';

        if (count($errors)) {
            $_SESSION['form']   = $form;
            $_SESSION['errors'] = $errors;
        } else {
            $redirect_page = 'another_page.php';
        }   
    }
}

redirect($redirect_page);

I find the following approach has worked well in most situations, however I am always looking for better ways to improve.

\$\endgroup\$
3
\$\begingroup\$

That method is fine, and is the one I use. As for a better way? I don't know, seems just fine to me. However, there are some other things that could be improved with this script, and that may be why you feel there might be a better way.

For one, that's some really messy HTML... I would try and separate your PHP from your HTML as much as possible. This is a little harder to do when not using MVC, but can still be accomplished by abstracting your larger bits of code. Also, you are using PHP short tags, but then not using PHP template syntax, this seems counter productive. The purpose of the short tags is to make your code cleaner and make it non-PHP user friendly. Of course, I'm not endorsing PHP short tags, I think you should avoid them, as you are not always guaranteed to have a server that will support them. Lastly, your code is pretty repetitive, the best thing for repetitive stuff like this is loops. For example, here's a sample of how my version of this form would look.

<?php
$fields = array(
    'name',
    'age',
    //etc...
);
?>

<?php foreach( $fields AS $field ) : ?>

<?php $value = isset( $_SESSION[ 'form' ] [ $field ] ) ? $_SESSION[ 'form' ] [ $field ] : ''; ?>

<label for="<?php echo $field; ?>">What is your <?php echo $field; ?>?</label>
<input type="text" name="<?php echo $field; ?>" value="<?php echo $value; ?>" maxlength="60" />

<?php if( ! isset( $_SESSION[ 'errors' ] [ $field ] ) ) : ?>

<label class="error" for="<?php echo $field; ?>"><?php echo $_SESSION[ 'errors' ] [ $field ]; ?></label>

<?php endif; ?>

<?php endforeach; ?>

Of course, even this seems really messy to me, though I can't think of much more, besides using MVC, to do to this to make it cleaner. Also, notice I removed the "id" attribute from your input tag. When your tag has a name, it doesn't need an id, you can just call it with the name. Example:

alert( document.form.name.value );//may not work, dont think "form" is valid name

Take a look at PHP's filter_input() function. Its available as long as your PHP version is >= 5.2. It also has some validation flags if you're interested.

$form[ 'name' ] = filter_input( INPUT_POST, 'name', FILTER_SANITIZE_STRING );

Keep in mind the "Don't Repeat Yourself" (DRY) principle. There are a lot of violations of it here. I demonstrated how to avoid it with your form above, you can do something similar for the processing script.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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