Function Documentation

WordPress Function Documentation Progress

Writing WordPress Widget Best Practices

Don’t Nest Functions

It appears to be a neat trick, but that is all it is. A hack that you should avoid and just because you can do it and it works does not give reason to do so. There are many programming practices that you can use in PHP, but must not. The only exception was, if you were the only one that is going to see it and it was an exercise of academics. Aside from that, the common widget practice of nesting functions inside of functions should be halted.

Example of Wrong Widget Form

function myplugin_widget_init()
{

    function myplugin_widget_display($args)
    {
        
    }

    function myplugin_widget_control()
    {
        
    }

    // Register myplugin_widget_display() and myplugin_widget_control()
}

The problems with this code are listed below.

  1. Class structure would be the most logical alternative.

    The simple containment of the functions is easily accomplished using a class container. I’m unsure what the appeal of this form, but if the need to contain the three functions, than a class should have been used instead.

    I have an theory, that the first one to use this pattern knew what he/she was doing and thought it would be cool and didn’t realize that everyone else would use it as an example. Everyone else that came after noticed that it worked (mysteriously) and decided that it was easier than learning OOP. However, this theory is unproven, so whatever the reason, a class would have been a better and wiser choice.

  2. Prevents Opcode Caching optimization.

    PHP will not compile the two functions contained in myplugin_widget_init() until that function is called. By halting the compile process, some one using an Opcode Cache will not receive the boost. Furthermore, PHP will not know in most cases whether it will need to continue to cache the two functions, so at the best case the functions will be cached after the function is called and at the worst case, it will have to compile the two functions with each process.

  3. Causes fatal duplicated function definitions.

    In the event that myplugin_widget_init() is called twice, it will cause PHP to try to compile the contained functions twice. This will fail, because PHP already compiled the functions when the function was called the first time. The reason you won’t have a third call is that the second call will bring PHP and WordPress crashing down.

Widget Best Practice: Using the Object Pattern

class myplugin_widget
{
    function init()
    {
        // Register myplugin_widget::display() and myplugin_widget::control()
    }

    function display()
    {
        // Echo content
    }

    function control()
    {
        // Echo administration control
    }
}

I like keeping functionality contained together. Some plugins choose to dump all functionality into the same object, I would advise against this, but if it is easier for you, then just use functions instead until you learn OOP better.

Widget Best Practice: Using Functions

function myplugin_widget_init()
{
    // Register myplugin_widget::display() and myplugin_widget::control()
}

function myplugin_widget_display()
{
    // Echo content
}

function myplugin_widget_control()
{
    // Echo administration control
}

This code is far nicer looking and contained and has none of the disadvantages listed above.

About these ads

February 4, 2008 - Posted by | Writing Plugins Series | , ,

1 Comment »

  1. Nice article. One thing though is when I first read it I thought you were recommending the last example (using functions) vs. using the object pattern. IOW, by scanning it I almost thought you were recommending again objects. My bad, but most people scan on the web.

    Maybe if you headings were “Preferred Widget Best Practice: Using the Object Pattern” and “Alternate Widget Best Practice: Using Functions” it would have been a tad clearer for those who scan vs. read.

    Comment by Mike Schinkel | October 26, 2008 | Reply


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: