5

I have a problem when updating a variable with return system_settings_form($form) - Basically, I store a variable as an integer, but when I press Save configuration, it works very well except that it saves the variable as a string, not an integer.

Here's my function:

function my_module_settings() {
  $form['my_variable'] = array(
    '#type' => 'select',
    '#title' => t('My module variable'),
    '#description' => t('Update my module variable.'),
    '#options' => array(
       1 => t('Set it to 1'),
       2 => t('Set it to 2'),
       3 => t('Set it to 3'),
    ),
    '#default_value' => variable_get('my_variable', 3)
  );
  return system_settings_form($form);
}

So, if I select "Set it to 2" in the select list and hit save, I'll be getting number 2 surrounded by quotes ("2"). I've confirmed with PHP gettype that there's indeed a change of data type.

I wonder if it's related to the select list or something foolish I'm doing? I've tried using a checkbox instead and data type is correctly updated as an integer.

I've been scratching my head without finding a correct solution. Any idea what's going on?

2
  • Strange. variable_set serializes the value and serializing should not change its type (string or integer). How did you check the type of the saved value ?
    – AKS
    Jan 12, 2013 at 2:04
  • I used the gettype() PHP function and noticed it returned an integer first, then a string after I clicked Save Configuration.
    – vanz
    Jan 12, 2013 at 17:12

3 Answers 3

7

It probably has to do with how php handles POST values.

That is just generating a form element, which when the form is saved will get sent to the server as a string. Here's an attempt at phpfiddle to show you what's going on: http://phpfiddle.org/main/code/dmk-npy.

Basically you're either going to have to intercept the form submit and cast the variable to (int) there, or you'll need to cast it to an int when you're pulling the variable out.

Edit: Though I have no idea why your checkbox would be saving it as an integer.

2

As @Cthos said in his answer, you are not doing anything wrong. That is caused by how PHP handles POST values.

For a checkbox form element, that doesn't happen because the HTML output for that form element is similar to the following one.

<input type="checkbox" checked="checked" class="form-checkbox" />

It's then the form API that associates the numeric value to the checkbox. (See #return_value.)

The fact a number is changed to a string should not make any difference for the code you write, if you don't use === as operator for comparing the value associated with a form element. Even switch would consider '1', and 1 as equivalent; you can check that with the following code.

$value = '1';

switch ($value) {
  case 1:
    print "Number one!";
    break;

  case 2:
    print "Number two!";
    break;
}
3
  • Thanks, I'm not too worried about the code working or not since it does work fine, but I'm more concerned about how PHP is handling data type in general and possible performance concerns if integers are cast in strings, not for my particular example, but in general.
    – vanz
    Jan 12, 2013 at 12:51
  • 1
    Casting is a very cheap operation in php, and it happens all the time (it is a loosely typed language after all). So you don't need to worry about that.
    – Cthos
    Jan 12, 2013 at 15:54
  • It does make a difference in D8 where there is a schema for config.
    – AdamS
    Feb 10, 2017 at 18:06
1

The short story is, unless doing strict type checking, the string vs int data type generally doesn't matter all that much in PHP.

When a string is evaluated in a numeric context, the resulting value and type are determined as follows.

If the string does not contain any of the characters '.', 'e', or 'E' and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer. In all other cases it will be evaluated as a float.

Source: http://php.net/manual/en/language.types.string.php#language.types.string.conversion

As you probably know, if really needed, you can cast as an int with:

$foo = (int)$bar;

However, for most intents and purposes, you can just use your string as an int, yay PHP ;)

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.