A few PHP design basics for people who have forgotten them.
== Lazy load everything ==
The hottest hotspot is always initialisation. Initialisation runs on every
single request. Every extension adds its own initialisation overhead, and
there may be many extensions. Therefore, it is critical that
initialisation is heavily optimised.
So if you're writing an extension, don't do anything at initialisation
time (either file scope or $wgExtensionFunctions) except setting globals
to literals.
Don't initialise data that you think you might need. Wait until you're
asked for it and load it then. Cache it if necessary. Think in terms of a
pull model, not a push model.
Loading large amounts of code is slow and memory hungry, especially on
installations without an opcode cache. So lazy-load your code, by putting
everything into autoloaded classes. Use static member functions for hooks.
== Global variables are evil ==
In MediaWiki, global variables should be used for configuration, and
nothing else. There are some legacy object globals defined in old code,
and you might have to use them from time to time, but don't go adding more
of them. And don't reference any global variable unless you have to.
If you do need to use a legacy global variable such as $wgUser, just put
the global statement where it's needed. Don't pull the object out of the
global namespace and pass it from function to function unless there's a
concrete need for that versatility.
Passing global objects from function to function is not a reasonable
substitute for direct reference to a global variable. When the revolution
comes, you will know it.
== Objects are hashtables ==
Member variables can be added and removed dynamically. It is your
fundamental right as a PHP programmer to do this, nobody will ever take it
away from you.
You can test for existence with isset($this->var), delete a variable with
unset($this->var), reference variables with dynamic names using
$this->$name, and even convert to and from the array type, (array)$obj.
It is nice from a self-documentation standpoint to put var declarations at
the top of your classes. But understand that a var declaration takes up
time and space when the object is initialised. If you leave it out, that
overhead can be deferred, and maybe skipped altogether.
But the most important part of this paradigm is that extensions can create
custom member variables in core objects.
Say if you're writing a hook and you need to cache some data. You could
put it in a global variable or static member variable, but the trouble is,
unless you're very careful, you lose versatility in the hook caller.
Most hooks have an object as their first parameter. This object is a great
place to put your extension data relating to that object. When the caller
is done with the object, it will go out of scope and your data will be
deleted. And your code will implicitly be versatile enough to support any
number of objects present in the system at any given time.
Prefix your custom member variables with the name of your extension, to
avoid conflicts.