404 Error from WordPress Form Submit with an input named 'name'
Form with name="name" causes 404 in WordPress
While I haven't tracked down the source of the problem within WordPress itself, I was having some trouble with a form on a custom template on a WordPress site.
I had made my form, was hitting submit then promptly seeing a 404 page.
Confusing? I'll say, especially considering the form was submitting to itself.
So I took a look at my code, commented out the redirects I had, through error_log
around a little trying to track down where the execution broke. Nothing. No err's,
no warnings.
So I did what any developer does, I googled a few keywords checking for 404 errors on submitting a form, and then eventually ended up on this support forum where member ianstapleton noted that changing the input name caused the form submission to work again.
It's a bit of a strange fix, but it makes sense when you consider the code inside of Wordpress Core. Here's the snippet that is causing the slightly unexpected behavior:
wp-includes/query.php (WordPress Version 3.7.1) 2337 if ( '' != $q['name'] ) { 2338 $q['name'] = sanitize_title_for_query( $q['name'] ); 2339 $where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'"; 2340 } elseif ( '' != $q['pagename'] ) { 2341 if ( isset($this->queried_object_id) ) {
The $q
variable is the query variables which are retrieved like this:
wp-includes/class-wp.php (WordPress Version 3.7.1) 2142 $q = &$this->query_vars; 2143 2144 // Fill again in case pre_get_posts unset some vars. 2145 $q = $this->fill_query_vars($q);
In other words, the $_POST
and $_GET
variables seem to be merged into a single
query_vars
propertie and then used from there. wp_parse_args
is used during
part of the merging (from a brief look into the fill_query_vars
function) and
so we end up looking for a post with the name of whatever we submitted in the form.
Which is, not what we wanted to do. You could use it to create a custom search
form for looking for exact matches on post names, but that'd be a little silly.
Regardless, I wonder if this is the intended behavior of WordPress or just a result of lots of code making the assumptions that no user will ever try to use
<input type="text" name="name" />