Learn to manage plugin updates effectively by tracking version numbers, implementing dbDelta for schema changes, and running one-time migration scripts.
Previously in this course, we built a robust Model Layer for Data to abstract our database interactions. Now that our plugin is growing, we need a reliable way to evolve our database structure as we add features.
Software is never finished. When you release a new version of your plugin, you often need to change the database schema or reorganize existing data. Unlike Laravel migrations which are highly structured, WordPress requires us to manually manage the plugin version and trigger the necessary updates.
The first step in managing updates is knowing which version of your plugin is currently installed. WordPress stores the plugin version in the header of your main plugin file, but that doesn't help your code know if it needs to run an update.
We store the "installed version" in the wp_options table. This allows us to compare the version in our code against the version saved in the database.
PHP#6A9955">// Inside your main plugin class or activation/upgrade handler public function check_for_updates() { $installed_version = get_option('my_kb_plugin_version', '0.0.0'); $current_version = '1.1.0'; if (version_compare($installed_version, $current_version, '<')) { $this->run_upgrades($installed_version); update_option('my_kb_plugin_version', $current_version); } }
When you need to add a column or create a new table, you shouldn't run raw CREATE TABLE queries directly. Instead, use dbDelta(). This function parses your SQL and compares it against the existing database schema, only applying the necessary changes.
It is strict about formatting:
PRIMARY KEY definition.BIGINT or NOT NULL.PHPfunction my_kb_update_schema() { global $wpdb; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); $table_name = $wpdb->prefix . 'kb_articles'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, title varchar(255) NOT NULL, content text NOT NULL, version_added varchar(10) DEFAULT '1.0.0', PRIMARY KEY(id) ) $charset_collate;"; dbDelta($sql); }
Sometimes a schema change isn't enough; you might need to move data from a legacy format to a new structure. We handle this by checking the installed version and executing specific migration methods.
PHPprivate function run_upgrades($installed_version) { #6A9955">// If the user is upgrading from a version older than 1.1.0 if (version_compare($installed_version, '1.1.0', '<')) { #6A9955">// Run migration logic: e.g., move data from post_meta to custom table global $wpdb; $wpdb->query("UPDATE {$wpdb->prefix}kb_articles SET version_added = '1.1.0'"); } }
check_for_updates() method that compares your plugin's current version constant against an option in wp_options.admin_init action so it runs when an administrator visits the dashboard.run_upgrades() method that adds a new column to your Knowledge Base table using dbDelta.dbDelta formatting: If you don't use the exact spacing requirements (like two spaces before PRIMARY KEY), dbDelta will fail silently or recreate tables unnecessarily.version_compare to ensure your migration logic only runs once during the upgrade process.require_once: dbDelta is defined in wp-admin/includes/upgrade.php, which is not loaded by default on the frontend. You must include it manually.Managing updates is a foundational skill for any professional WordPress plugin architecture. By versioning your database changes, you ensure that your users have a seamless transition between plugin releases without losing their data.
Up next: Internationalization (i18n) — preparing your plugin for global audiences.
Master the WordPress event-driven architecture. Learn the difference between actions and filters and how to implement callbacks to build robust plugins.
Handling Plugin Updates
Plugin Security Best Practices
Composer for Dependencies
Theme Integration Hooks
Managing Assets with Gulp/Webpack
Documentation Standards
Plugin Deployment Strategy
Advanced MVC: Dependency Injection
Handling Large Datasets
Error Handling and Logging