Back to Snippets

Sanitize and Validate Form Input

PHP Security April 6, 2026

Complete form handling pattern — nonce verification, input sanitization, validation with error messages, and secure redirect. Production-ready.

Snippet Stats

Lines 44
Characters 1,782
Read 2 mins
php • 44 lines
/**
 * Process a contact form submission securely.
 */
add_action( 'admin_post_contact_form', 'handle_contact_form' );
add_action( 'admin_post_nopriv_contact_form', 'handle_contact_form' );

function handle_contact_form(): void {
    // 1. Verify nonce.
    if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce(
        sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ),
        'contact_form_action'
    ) ) {
        wp_die( esc_html__( 'Security check failed.', 'theme-domain' ) );
    }

    // 2. Sanitize each field.
    $name    = isset( $_POST['name'] )    ? sanitize_text_field( wp_unslash( $_POST['name'] ) )    : '';
    $email   = isset( $_POST['email'] )   ? sanitize_email( wp_unslash( $_POST['email'] ) )        : '';
    $message = isset( $_POST['message'] ) ? sanitize_textarea_field( wp_unslash( $_POST['message'] ) ) : '';

    // 3. Validate required fields.
    $errors = array();
    if ( empty( $name ) )               { $errors[] = __( 'Name is required.', 'theme-domain' ); }
    if ( ! is_email( $email ) )          { $errors[] = __( 'Valid email is required.', 'theme-domain' ); }
    if ( strlen( $message ) < 10 )       { $errors[] = __( 'Message must be at least 10 characters.', 'theme-domain' ); }

    if ( ! empty( $errors ) ) {
        // Store errors in transient and redirect back.
        set_transient( 'contact_form_errors_' . wp_get_session_token(), $errors, 60 );
        wp_safe_redirect( wp_get_referer() );
        exit;
    }

    // 4. Process (e.g., send email).
    wp_mail(
        get_option( 'admin_email' ),
        sprintf( '[Contact] Message from %s', $name ),
        $message,
        array( 'Reply-To: ' . $email )
    );

    wp_safe_redirect( add_query_arg( 'contact', 'success', wp_get_referer() ) );
    exit;
}

Found an issue with this snippet? Help us improve by reporting it. Report it →

Related Snippets

View all
JavaScript
This React higher order component handles authentication and authorization by checking user credentials before rendering the wrapped component. It uti...

React Higher Order Component For Authentication And Authorization In Large Scale Applications

JavaScript
This React higher-order component handles authentication and authorization by wrapping the provided component with authentication checks, ensuring onl...

React Higher Order Component For Role Based Authentication And Authorization

PHP
This snippet provides a custom WordPress plugin that utilizes hooks to modify the user registration process, allowing for additional validation and cu...

WordPress Custom Plugin Hooks For User Registration