3

I'm working out this odd bug in Wordpress, and I don't know how wordpress works, but I ran around for an hour trying to isolate the problem and see where the root of the issue comes from.

Turns out the problem is that the thing isn't updating because $_POST does not have the data that is being requested.

At the top of the file that I'm accessing from the browser, before any other code, I did the following:

echo file_get_contents("php://input");
print_r($_POST); exit();

I see that wordpress uses $_POST as a catch-all global and writes to it as well. I thought maybe wordpress kicks the data out somewhere but I couldn't find that. This is at the top of the file anyways, before anything else happens at all.. I don't think it's even possible for the variables to be modified before that

The output from that is

widget-text%5B3%5D%5Btitle%5D=Test&widget-text%5B3%5D%5Btext%5D=THISISATEST&sidebar=sidebar-1&sidebar-1_position=1&sidebar-2_position=&sidebar-3_position=&sidebar-4_position=&sidebar-5_position=&savewidget=Save+Widget&widget-id=text-3&id_base=text&multi_number=3&_wpnonce=36852083b6&_wp_http_referer=%2Fwp-admin%2Fwidgets.php%3Fmessage%3D0%26editwidget%3Dtext-3%26sidebar%3Dsidebar-1%26key%3D0
Array
(
    [widget-text] => Array
        (
            [3] => Array
                (
                    [title] => Test
                )

        )

    [sidebar] => sidebar-1
    [sidebar-1_position] => 1
    [sidebar-2_position] => 
    [sidebar-3_position] => 
    [sidebar-4_position] => 
    [sidebar-5_position] => 
    [savewidget] => Save Widget
    [widget-id] => text-3
    [id_base] => text
    [multi_number] => 3
    [_wpnonce] => 36852083b6
    [_wp_http_referer] => /wp-admin/widgets.php?message=0&editwidget=text-3&sidebar=sidebar-1&key=0
)

url_decoded:

widget-text[3][title]=Test&widget-text[3][text]=THISISATEST&sidebar=sidebar-1&sidebar-1_position=1&sidebar-2_position=&sidebar-3_position=&sidebar-4_position=&sidebar-5_position=&savewidget=Save Widget&widget-id=text-3&id_base=text&multi_number=3&_wpnonce=36852083b6&_wp_http_referer=/wp-admin/widgets.php?message=0&editwidget=text-3&sidebar=sidebar-1&key=0Array

Note how in the raw data, widget-text[3][text]=THISISATEST exists. But $_POST['widget-text']['3']['text'] is undefined.

I looked through phpinfo and can't find any relevant settings. I am on PHP Version 5.3.8, Apache 2, I'm running suse on AWS.

Does anyone have any ideas on how to make $_POST parse the raw data correctly?

Kavi Siegel
  • 2,964
  • 2
  • 24
  • 33
  • 1
    @ÁlvaroG.Vicario: In `$_POST`, `widget-text[3][text]` is missing, but it's in the raw `php://input` data. – gen_Eric Feb 05 '13 at 15:32
  • Ah, sorry, the array has two keys and one of them is gone. – Álvaro González Feb 05 '13 at 15:35
  • That's right. PHP seems to kick out any third level array key, I did try editing the form with inspector to see if it's just they key "text" which php dislikes and no matter what, it didn't work – Kavi Siegel Feb 05 '13 at 15:51
  • I don't know Wordpress that well, but if it works like Drupal's Forms API, you'll have written code elsewhere that defines what fields the form expects, and unexpected fields will be stripped from the input. So my guess is that the Wordpress core is stripping the field from $_POST before your code gets to see it. – SDC Feb 05 '13 at 15:52
  • @SDC is it possible for that to happen when the code is at the top of the file, though? No other code is run before this. The URL in the browser is the file I'm in and I don't think there's any include magic going on – Kavi Siegel Feb 05 '13 at 15:53
  • I don't know; I can't see your system and I don't know WP. In a regular PHP environment it shouldn't happen, and I saw the WP elements in the post data so that was my guess. It is possible for there to be some include magic, but if you're sure there isn't any, and nothing else is being run, then my guess will probably turn out to be wrong. It's worth investigating though, because I can't think of any other reason why PHP would do this. I've used multi-level arrays on my forms plenty of times without issue. – SDC Feb 05 '13 at 15:57
  • To confirm no include magic is going on, check your php.ini and .htaccess files for something like `auto_prepend_file = /path/to/config.php` – SDC Feb 05 '13 at 15:59
  • 1
    Did one better - placed this in the effected file just to make sure there's nothing I could miss `var_dump(get_cfg_var('auto_prepend_file'));` and it == empty string. `phpinfo()` from there confirms there's no include magic going on – Kavi Siegel Feb 05 '13 at 16:05

2 Answers2

1

This is indeed weird. Could be a bug in PHP or issue with configuration/extension.

  1. Try changing configuration variables max_input_nesting_level, max_input_vars, max_input_time. If you're unsure about values just try default ones. Check the PHP documentation page to look up default values and their meaning.

  2. If you're running suhosin extension, try disabling it and see if it helps. Also all suhosin.post.* configuration keys look interesting.

  3. Googling reveals similar problems: one, two.

  4. Try accessing it through $_REQUEST - $_REQUEST['widget-text']['3']['text']

Anyway, after some googling it seems like this happens in PHP 5.3.8. So upgrading may be another option.

Community
  • 1
  • 1
galymzhan
  • 5,505
  • 2
  • 29
  • 45
1

Yup, just do:

parse_str( urldecode( file_get_contents("php://input") ), $result );

var_dump( $result );
Kokos
  • 11
  • 1