Drupal - How to get a list of all the selected values for a field programmatically?
Because fields can have multiple values both of the methods you describe will return an array. Each of those array items will itself be an array, of all the possible columns for the field. In the case of text fields the only column you really need to worry about is the value
column.
Assuming your particular field does not accept multiple values, or it does and you only want the first value, the following should work:
$items = field_get_items('node', $node, 'field_countries', $node->language);
$item = array_shift($items);
$value = $item['value'];
or
$value = $node->field_countries[$node->language][0]['value'];
field_get_items()
is the solution that is typically recommended. However, there are some caveats.
It is important to check if the field is empty. In this case field_get_items() returns false (which sucks).
$items = field_get_items('node', $node, 'field_countries', $node->language);
if (!empty($items)) {
$item = reset($items);
return $item['value'];
}
else {
return NULL;
}
I think you can generally be sure that if an item exists, it will be in the zero [0] index. And isset() is a very robust thing. So the following works as well:
$items = field_get_items('node', $node, 'field_countries', $node->language);
return isset($items[0]['value']) ? $items[0]['value'] : NULL;
For some field types, the value is not in $item['value'] but in $item['tid'] or something else.
In the usual case (I can't think of an exception atm), the value will be the first thing in the $item array. So the following will also work, but this is more by coincidence than by design. So personally I would not count on it.
(If $items is a (non-empty) array, then we can safely (*) assume that every $item will be an array too, and not something else.)
$items = field_get_items('node', $node, 'field_countries', $node->language);
return isset($items[0]) ? reset($items[0]) : NULL;
The return value of field_get_items() is by-value, so it is generally ok to modify the $items array. This means you can use array_shift().
$items = field_get_items('node', $node, 'field_countries', $node->language);
return !empty($items) ? array_shift(array_shift($items)) : NULL;
(*) Most of the assumptions we make here are not based on language-level guarantees, but just on how Drupal generally works.
Btw the following trick can be helpful sometimes, but it is not a complete solution of the original question:
$items = field_get_items(..) ?: array();
This guarantees that $items is always an array. But for snippets above this does not really help us.