What's best practice when working with the language[und]? I'm starting to use this form to access data in my module. (See comment #1.)

$node-&gt;field_test[$node-&gt;language][0]['value']


I thought that looked like a pretty good solution, but further down that same question I found this:


  Don't assume that 'und' is for fields of entities without language, it is also for fields that are not translatable, and without the entity translation module that is all fields. Moreover, there are differences in this between the various 7.x versions of Drupal.
  Better to use the field_get_items() function which will sort out for you under what language code the data is stored.


And now I don't know if what I'm using could break something down the road.
I find that using the Entity API module is a great help and also makes code more readable. The above code will not always work, since the language of the node and the language of the field can be different.

With the entity API module, and its wrapper, you can use the following code:

 $node_wrapper = entity_metadata_wrapper('node', $node);
 $field_val = $node_wrapper-&gt;field_test-&gt;value();


This should be bullet proof. One thing about using the entity module is that if you try to access a field that doesn't exist, you will get a nasty error and an exception thrown instead of a notice and wrong behavior.

To avoid this, you could do try/catch like this

try {
  $field_val = $node_wrapper-&gt;field_doesnt_exist-&gt;value();
} catch (EntityMetadataWrapperException $e) {
  $field_val = 'default/fallback value';
}


Or you can use isset() which EntityMetadataWrapper handles internally:

$field_val = 'default/fallback value';
if (isset($node_wrapper-&gt;field_doesnt_exist)) {
  $field_val = $node_wrapper-&gt;field_doesnt_exist-&gt;value();
}