$_POST empty on submit (same code, same form submits normally on local server)

My code was checked and seems OK so maybe the problem lies in the htaccess file whose content on my online server is:

SetEnv PHP_VER 5_4
Options -Indexes
ErrorDocument 404 /index.php
RewriteEngine on 
RewriteCond %{HTTP_HOST} !^www.example.fr$
RewriteRule ^(.*)   http://www.example.fr/$1  [QSA,L,R=301] 

Any reason why this htaccess would prevent forms from submitting correctly on my site?

Just in case here’s my code:

<form id='contact_form_mmt' action='<?php echo bloginfo("wpurl"); ?>/contact' method='post'>
  <input type="text" name="contact_nom" placeholder="Votre nom *" data-validation='length' data-validation-length="min3" data-validation-error-msg='<?php echo $text_too_short_or_empty; ?>'>  
  <input type="text" name="contact_prenom" placeholder="Votre prénom *" data-validation='length' data-validation-length="min3" data-validation-error-msg='<?php echo $text_too_short_or_empty; ?>'>
  <input type="text" name="contact_mail" placeholder="Votre mail *" data-validation='email' data-validation-length="min3" data-validation-error-msg='<?php echo $email_valid; ?>'>
  <select name="contact_destinataire">
    <option value="[email protected]|Information générales">Information générales</option>
    <option value="[email protected]|Problèmes liés au site">Problèmes liés au site</option>
  </select>
  <textarea name="contact_message" placeholder="Message *"data-validation='length' data-validation-length="min3" data-validation-error-msg='<?php echo $text_too_short_or_empty; ?>'></textarea>  
  <input type="hidden" name="sub" value="1">  
  <input type="submit" value="envoyer">
</form>

PHP (I know the syntax is ugly, I’ll improve that):

if ( isset($_POST['sub']) ) $sub = $_POST['sub']; else $sub = ''; 
if ( isset($_POST['contact_nom']) ) $contact_nom = $_POST['contact_nom']; else $contact_nom = ''; 
if ( isset($_POST['contact_prenom']) ) $contact_prenom = $_POST['contact_prenom' ]; else $contact_prenom = ''; 
if ( isset($_POST['contact_mail']) ) $contact_mail = $_POST['contact_mail']; else $contact_mail=""; 
if ( isset($_POST['contact_sujet']) ) $contact_sujet = $_POST['contact_sujet']; else $contact_sujet=""; 
if ( isset($_POST['contact_destinataire']) ) $contact_destinataire = $_POST['contact_destinataire']; else $contact_destinataire=""; 
if ( isset($_POST['contact_message']) ) $contact_message = $_POST['contact_message']; else $contact_message=""; 

3 Answers
3

The best way to deal with Form Posts in WordPress is to use a special endpoint, /wp-admin/admin-post.php.

POST data can be messed up, both by the WP Query call, and by any redirects that happen.

So you set up your form with this action:

<form action="<?= admin_url('admin-post.php') ?>" method="post">
<input type="hidden" name="action" value="special_action">
<?php wp_nonce_field('special_action_nonce', 'special_action_nonce'); ?>

Then you can handle the form by adding an action to your theme or plugin:

add_action('admin_post_nopriv_special_action', ['My\Plugins\FormController', 'specialAction']);
add_action('admin_post_special_action', ['My\Plugins\FormController', 'specialAction']);

Note that WordPress constructs a special action, based on the action value in the form, admin_post_no_priv_special_action (if you’re logged out) and admin_post_special_action (if you’re logged in). You can point these in different locations.

These action endpoints will always have access to POST, and will never trigger a redirect (which is often what WordPress does for pretty routes… it often routes: site.com/about to site.com/?pageName=about).

Once you’ve handled the form as you want, you can do a wp_redirect() to get to where you need it to be. This is also helpful because an accidental page refresh will not re-send the form.

Much lengthier doco can be found here:
https://www.sitepoint.com/handling-post-requests-the-wordpress-way/

Leave a Comment