One thing that should be avoided even more than global state (e.g. global variables/public static properties in classes) is local static vars and similar instances of hidden local state, especially when used for caching. It looks like a very good idea when writing it, and is absolute nightmare when debugging/testing, because it creates hidden un-clearable state which could be in any random configuration when you get to it.
Topic on Talk:Best practices for extensions
There is an other document in the works at User:DKinzler (WMF)/Software Design Practices that covers exactly this concern very well, I find.
I've made the point about global state explicit in this edit.