In the documentation for #value, the Drupal 7 documentation contains the following note:

Note that as of Drupal 6, you can also simply store arbitrary variables in $form['#foo'] instead, as long as '#foo' does not conflict with any other internal property of the Form API.

Is that still possible, in Drupal 8?

I looked at the documentation for the Value class, but the note given for Drupal 7 is not present.

I know Drupal adds $form['#token'] to forms, but I take it is a special case Drupal handles in a particular way.

  • Yes, but I am not sure if it is the intended behavior. I had a core patch with a pretty spectacular example of a failure that shows this: drupal.org/node/2500525#comment-10652210 – mpdonadio Feb 23 '16 at 18:32
  • Yes, seems that you can use (see test_form_id function here api.drupal.org/api/drupal/…), but seems not too safe to use, because you can break something. – Vagner Feb 23 '16 at 18:45
  • @Vagner That is using '#type' => 'value', not any custom attribute. – kiamlaluno Feb 24 '16 at 4:48
  • @MPD I checked that patch, but I didn't see anything similar to $form['#foo'] being used. – kiamlaluno Feb 24 '16 at 4:50

See FormCache::setCache(). The whole $form is put in the cache, anything that's in there is stored and fetched again.

That said, I would definitely advise against using it. The recommended and standard way to store something is $form_state->get()/set().

Also be aware that while this still works when the form is cached, Drupal 8 only caches form/form_state once an actual form submission happens. Usually that means only for ajax requests and in case of form validation errors (although I don't 100% know how it behaves then).

That means you can not put something in $form['#whatever'] or $form_state->set('whatever, ...) on the first form build and expect it to stay there.

| improve this answer | |
  • There are two sentences that seem a contradiction: The recommended and standard way to store something is $form_state->get()/set(). you can not put something in $form['#whatever'] or $form_state->set('whatever, ...) on the first form build and expect it to stay there. – kiamlaluno Feb 24 '16 at 17:22
  • What I wrote might not be clear, but no, they are not. Note how the second says first form build. It's perfectly valid to use either of them for example as part of an ajax submit button that temporarily stores some values that you can then use again in buildForm() to display additional elements. But you can't for example generate some value in buildForm() and then rely on it. Because on the first form submission, buildForm() will be called again, your value will be gone and will be regenerated. – Berdir Feb 24 '16 at 19:22
  • If I set a value in hook_form_alter() with $form_state->set(), am I sure I get it in the validation/submission handler I add with hook_form_alter(), with $form_state->get()? – kiamlaluno Mar 13 '16 at 16:49
  • Yes, but maybe not the value that you think you'd get. Lets say you have a snippet that assigns a random value to the key "random_value". You only set it if it's not already present. Your form also has an ajax element. The form is initially displayed, you generate ABC. This value is not stored and thrown away. You trigger the ajax request, which causes it to build the whole form a second time. Now you generate XYZ. Then in your validation callback, you see XYZ. This form state is now stored. Then you submit the form properly (or trigger another ajax event) and this time, you still have XYZ. – Berdir Mar 13 '16 at 17:04

You can use a new key if you need, just be sure if that key is not being used by another module.

| improve this answer | |
  • 1
    Any source for that? Or code sample to show it really works? – Mołot Feb 23 '16 at 23:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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