Creating a WordPress form with a PHP script and default header

Firstly, never send the browser directly to a PHP file in your theme or plugin. It’s a security hole and leads to a very fragile setup. For example:

  • The file will work even if the theme is deactivated and will work for all sites on an install, not just those it’s enabled for
  • The file will need to reach up and bootstrap WordPress, leading to long-winded include paths that are fragile, and nonstandard contexts which can confuse plugins
  • Creating the form on the frontend becomes a lot more complex as you need to specify the path of the form handler file, and it gets more complex if you have server-side validation that needs to know what went wrong to display the form again

So instead:

  • For AJAX, use register_rest_route and the REST API to create custom endpoints that accept the data you need
  • For form handling, use the page you’re already on. You don’t need a special form handler page; you just need to check if the form was submitted and act accordingly

For example:

<form method="post">
    <input type="hidden" name="doing_form" value="yes"/>
</form>

Then on the init hook:

add_action( 'init', function() {
    if ( empty( $_POST['doing_form'] ) ){
        return; // We didn't submit the form
    }
    // We did! Do the form handling
    ...
}

Finally, for storing your contact forms in a MySQL table, I would advise against this. Use a custom post type instead. It’ll give you an administrator interface, you can use WP_Query instead of raw SQL, and you can import and export. You can even display them on the frontend if you really wanted to with a URL, archive, and templates all provided automatically by WordPress.

That’s how popular contact form plugins that already do what you’re trying to do implement it, e.g.:

  • Ninja Forms
  • Contact Form 7
  • Gravity Forms
  • Jetpack Contact Forms
  • 100’s more

Leave a Comment