I have come across quite an odd problem when using the update_option function, and I am sure that I've tried everything I can think of to get it working, but unfortunately it isn't.

I'm using AJAX to submit a form (using the popular method described here) in the backend, on a custom options page. Everything is working, except for the update_option part. I just don't understand, is there an issue with using that function in an AJAX function callback?

    public function vmAddApp() {
        parse_str( stripslashes( $_POST[ 'data' ] ), $data );
        $nonce = $_POST[ 'nonce' ];
        $app_info = $data[ 'vm_fbconnect' ];
        $option = get_option( 'vm_fbconnect', array() );

        $appId = $data[ 'vm_fbconnect' ][ 'appId' ];
        $secret = $data[ 'vm_fbconnect' ][ 'secret' ];

        $app_response = wp_remote_get( 'https://graph.facebook.com/' . $appId );
        $response_body = json_decode( $app_response[ 'body' ] );
        $app_name = $response_body->name;

        $new_app = array(
            'name' => $app_name,
            'id' => $appId,
            'secret' => $secret
        $option[ 'apps' ][] = $new_app;
        $data = update_option( 'vm_fbconnect', $option );

        // UPDATE:
        // If I put either:
        // $data = $option;  // <- this returns the option correctly, see below
        // or
        // $data = get_option( 'vm_fbconnect', array() );  // <- this returns 'Array' as a string
        // But regardless, both SAVE 'Array' as the option's value..

        header( "content-type: application/json" );
        $response = array( 'data' => $data );
        echo json_encode( $response ); // <- this is how I'm getting the response in the JS console

Edit 1: Debugging (I updated the code above, see comments)

This is what I get when I return the modified option from inside the function:

enter image description here

This is what I get when I use get_option again.


After the option has been saved and I am done with the form, sometimes I will go right into the page currently displayed and do die( var_dump( get_option( 'vm_fbconnect', array() ) ); and it says just string(5) 'Array'.

Also, I'm always careful to reset the option before trying each time, and careful to make sure I commented out the delete_option function when trying again! :)

  • 1
    have you tried doing a var_export or similar on the $option before it is updated to see if it's not happening before the update_option? Commented Jun 16, 2012 at 17:02
  • Yes, it is an array before it is run through update_option, I have narrowed it down to that exact function.
    – Jared
    Commented Jun 16, 2012 at 17:55

2 Answers 2


It sounds like your array isn't being serialized before updating the option for whatever reason. Perhaps due to ajax or just your particular situation.

Try this:

// ...

$option[ 'apps' ][] = $new_app;

if( ! is_serialized( $option ) )
    $option = maybe_serialize( $option );

$data = update_option( 'vm_fbconnect', $option );

// ...
  • Thanks for your input. If I add that, then $data returns false and the option doesn't update at all.
    – Jared
    Commented Jun 16, 2012 at 17:35
  • @Jared - ah, ok. What if you tried type casting $option in your update call like this: $data = update_option( 'vm_fbconnect', (array) $option );? Commented Jun 16, 2012 at 19:12
  • I did that as well, it gives me the Array string saved to the option. One thing I did notice though, if I echo $data = get_option( 'vm_fbconnect', array() ); right after I update it, and console.log that, it returns the correct values.. I wonder if the headers or something have to do with it?
    – Jared
    Commented Jun 16, 2012 at 19:21
  • I take that back, I just tried it again, and even getting the option afterwards is just the string Array.
    – Jared
    Commented Jun 16, 2012 at 19:25
  • @Jared - how are you checking the value of the saved option? Commented Jun 16, 2012 at 19:37

Turns out, my question didn't even have to do with AJAX, it had to do with the function used to validate the settings that was supplied with register_setting.

The problem with it was that it wasn't going deep enough into the array to even save the values. I needed to modify it to look like so:

    public function settingsValidate( $todo ) {
        $option = get_option( 'vm_fbconnect', array() );

        if( !empty( $todo ) && is_array( $todo ) ) {
            foreach( $todo as $name => $value ) {
                if( is_array( $value ) ) {
                    foreach( $value as $nam => $val ) {
                        if( is_array( $val ) ) {
                            foreach( $val as $n => $v ) {
                                $option[ $name ][ $nam ][ $n ] = wp_filter_nohtml_kses( $v );
                        } else {
                            $option[ $name ][ $nam ] = wp_filter_nohtml_kses( $val );
                } else {
                    $option[ $name ] = wp_filter_nohtml_kses( $value );

        return $option;

I know there's a better way to do this, will edit sometime later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.