register_uninstall_hook() vs uninstall.php – which one is better way to handle plugin uninstallation script?

The benefit of uninstall.php, and the reason that it was introduced, is that it allows you to isolate your uninstallation code from the rest of your plugin’s code. This means that your entire plugin doesn’t have to be loaded when it is uninstalled. That minimizes the chance that your plugin will inadvertently run code during uninstallation that is only intended to be run when the plugin is active. However, in general, you shouldn’t be running arbitrary code in your plugin files anyway, most everything should only run if triggered by a hook.

From the docs included in the original commit:

The plugin should not run arbitrary code outside of functions, when
registering the uninstall hook. In order to run using the hook, the
plugin will have to be included, which means that any code laying
outside of a function will be run during the uninstall process. The
plugin should not hinder the uninstall process.

If the plugin can
not be written without running code within the plugin, then the plugin
should create a file named ‘uninstall.php’ in the base plugin
folder…

TL;DR: Your plugin should really be structured in such a way that it doesn’t have to use unisntall.php, but using it anyway adds extra protection against accidentally running things during uninstall.

Of course, in some cases you may need to load parts of your plugin in order to uninstall it properly anyway. But if you are using uninstall.php, including those files will be a conscious decision that you make, so it is harder to mistakenly load some file of your plugin that runs arbitrary code.

The only time that I would use the register_uninstall_hook() method would be in a very simple, single-file plugin, where all of the code was encapsulated into a single class.


Note that uninstall_plugin() will run the pre_uninstall_plugin and uninstall_{$plugin_file} [edit: uninstall_{$plugin_file} will only run if register_uninstall_hook() is used] action hook regardless of which method you use. (See ticket #34569.)

Leave a Comment