The documentation for field_read_instance() currently says "Generally, you should use field_info_instance() instead" but doesn't really explain when "generally" is.
I've always thought you should only call field_read_instance() if you need to load a deleted or inactive field (since those won't be returned by field_info_instance()) but perhaps there are other situations too...
In addition, the API documentation example for field_update_instance() says to load the instance with field_info_instance() before saving, but @jhodgdon noticed that pretty much everywhere in core (e.g. Field UI module) actually uses field_read_instance() to load it before saving (see #2054189: 'definition' key does not exist in the array returned by field_info_instance(). Update docs.).
My basic understanding/guess is that it rarely does actually matter which you use, and that field_info_instance() is preferred whenever possible but nothing terrible happens if you use field_read_instance(). But we should clarify this and fix it in the docs.
Comments
Comment #1
jhodgdonYeah, could we clarify why we have two functions and what the difference is? I have no idea.
Comment #2
jay.chen commentedAs you can see the implementations, field_info_instance() first try to retrieve data from the cache table.
If not found, then it will call the function field_read_instance() to retrieve data directly from joining the field_config_instance and field_config tables.
So I think the difference is that field_info_instance() will read cache and it should be running faster.
The "generally" means you want retrieve data without cache.
Comment #3
jhodgdonI'm still not sure that field_info_instance() and field_read_instance() return the same information. Do they? It seems like field_info_instance() is returning a lot of extra information besides what field_read_instance() returns.
Also, it looks like if you do field_info_instance() for any field on a given bundle, it reads *all* the information for all fields on that bundle, using the getBundleInstances() method on the cache object.
So if you only needed what field_read_instance() would give you, and you only need it for one field on one bundle, I am not certain that it would be necessarily more efficient than field_info_instance()?
Comment #4
ey commentedI've briefly tested both functions and they resulted exactly the same output. I can list the steps I've done to test both function on one of my projects, so that if someone interested can double-check.
Add a field to basic page content type, or any other custom content type.
I've used drush to make it easier:
The output was the same.
I've checked the output through
diffcommand on my linux machine like that:Result is nothing, so there is no difference.
The documentation of
field_read_instance()says:So, it is already cleared why field_info_instance() should be 'generally' used instead of 'field_read_instance()', since the former provides caching while the latter does not.
Comment #5
joachim commented> allows other modules the opportunity to append additional formatters, widgets, and other information.
What about this bit? I'm struggling to think what this actually refers to, as formatters and widgets and so on are defined in Field info hooks and so should already be around.
Comment #6
zuernbernhard commentedThere is another interesting Point, if you use field_info_instance for an intance that doesn't exist any more you get an Error like:
Illegal offset type field.info.class.inc:378 [warning]
Illegal offset type in isset or empty field.info.class.inc:352
If you use field_read_instance for an instance that doesn't exist any more you don't get this error.
I came across this issue because we use Kraftwagen-Manifests during deployment to remove field_instances that are not used any more (cannot do it with Features). And as soon as the Kraftwage Manifest ist executed twice for the same field_instance we got we these Warnings in the drush console.