Fatal error: Cannot unset string offsets in form.inc on line 322

The code around line 322:

  if (isset($form['#token'])) {
    if ($form['#token'] === FALSE || $user->uid == 0 || $form['#programmed']) {
      unset($form['#token']);
    }

The unset is wrapped in an isset which means the unset should only happen when there is something to unset. A dump shows $form is a string. Weird. PHP 5 seems to have an error where it tries to treat strings as arrays instead of highlighting the error. Perhaps function drupal_prepare_form($form_id, &$form) could start by checking if $form is an array and producing a meaningful error message.

petermoulding.com/web_architect

Comments

ChrisKennedy’s picture

Please describe the action that is giving this error.

peterx’s picture

I was changing menus in a module. Switching to Drupal 5.0 and adding more menu entries. I occasionally received the error message and not always on the same line. When I added diagnostics to forms.inc, I found I was passing $form as a string instead of an array. On one occasion it was because I passed $form through a theme function. On other occasions the error was so obscure that I reverted code to an earlier version and started again, wasting a lot of time.

The error would be obvious in PHP 4 but is not obvious in PHP 5. In PHP 4, the error would occur on almost the first line of drupal_prepare_form() and the message would tell you that $form is a string instead of an array. In PHP 5 the error occurs after some successful processing of $form as a string instead of an array.

I do not call drupal_prepare_form() anywhere in my code which results in a long process to find which part of my code calls something that calls drupal_prepare_form(). Just the act of documenting this error will help other people fix their problems instead of blaming drupal_prepare_form(). Will the regular drupal.org site search find this entry? Should I post something that points to this error so that it appears in the search?

peterx’s picture

I tested the site search and it finds this entry. That means other people with the same error can find this report and work out what is happening.

It is PHP 5 treating a string as an array instead of reporting the real error. You have a string going into a form function where you should have an array.

ebob-1’s picture

I reproduced the error with this:

function mymodule_menu($may_cache) {
    if ($may_cache) {
        $items = array(
            'path' => 'admin/settings/mymodule',
            'title' => t('mymodule Settings'),
            'description' => t('mymodule description.'),
            'callback' => 'drupal_get_form',
            'callback arguments' => array('mymodule_admin_settings'),
            'access' => user_access('administer site configuration')
        );
    }
    else {
        $items = array();
    }
    
    return $items;
}

The crucial mistake I made was setting $items instead of $items[].

heine’s picture

Status: Active » Closed (won't fix)

GIGO principle.

rod.murphy’s picture

I also got this php error message, but in my case, it was because I was calling drupal_get_form() twice. The first time, the $form array would be converted to a string, then it was called again with $form as a string rather that an array.

It was called twice, because I called drupal_get_form() in my hook_menu() function and then again in the form function that it drupal_get_form() calls. Simple and careless mistake, but took me a while to track down.

mpruitt’s picture

I had the same error. Turned out it was the way I was calling the function:

Original Code:

$items[] = array('path' => 'my_store/status',
      'title' => t('Inactive Stores'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array('my_store_display'),
      'type' => MENU_LOCAL_TASK,
      'weight' => 3,
      'access' => user_access('delete a store'),
    );

Edited Code:

$items[] = array('path' => 'my_store/status',
      'title' => t('Inactive Stores'),
      'callback' => 'my_store_display',
      //'callback arguments' => array('my_store_display'),
      'type' => MENU_LOCAL_TASK,
      'weight' => 3,
      'access' => user_access('delete a store'),
    );
OptimusPrime23’s picture

This happens when you have a function declaration with an argument and a value is assigned to the same inside the function.

for example:

function test($nid)
{
$nid=arg(1);
}
houmem’s picture

Issue summary: View changes

that appear when the code in the $schema variable is false, for me at least