Every WordPress plugin eventually encounters deprecated PHP functions. The code that worked perfectly in PHP 5.6 has become a legacy burden in PHP 8.x. Yet many plugin developers ignore these warnings until users complain about broken functionality or hosting providers force upgrades.
WordPress plugin PHP deprecated functions migration isn't glamorous work—it won't add features or attract users. But it's critical maintenance that prevents future crashes, improves performance, and keeps your codebase compatible with modern hosting environments.
This guide covers identifying deprecated functions, understanding WordPress-specific deprecations, planning migration strategies, and testing after changes. WP HealthKit can scan your plugin to detect deprecated functions and compatibility issues, providing a roadmap for modernization.
Table of Contents
- Understanding PHP Deprecations
- Identifying Deprecated Functions in Your Plugin
- WordPress-Specific Function Deprecations
- Planning Your Migration Strategy
- Common PHP Deprecations and Solutions
- Automated Detection Tools
- Testing After Migration
- Frequently Asked Questions
Understanding PHP Deprecations
When PHP developers deprecate a function, they're saying: "This function still works, but we're warning that it will be removed in a future version. Plan to stop using it."
There are three levels of PHP function lifecycle:
Active: Function works, no warnings. Code using it runs normally.
Deprecated: Function works but generates deprecation warnings when used. PHP continues to execute the code, but the function will be removed in a future version. Users may see warnings in debug logs.
Removed: Function no longer exists. Code using it causes a fatal error and the site crashes.
WordPress plugin PHP deprecation follows a similar pattern, but WordPress-specific deprecations often have longer timelines. WordPress 5.x marked functions as deprecated that won't be removed until WordPress 7.x or later.
Here's the progression:
// PHP 5.6: Function works, no warnings
function old_function() {
// Code works normally
}
// PHP 7.0: Function deprecated (E_DEPRECATED)
function old_function() {
// Still works but triggers a deprecation notice
trigger_error('Use new_function() instead', E_DEPRECATED);
// Code executes anyway
}
// PHP 8.0+: Function removed (fatal error)
// Calling old_function() causes:
// Fatal error: Call to undefined function old_function()
Why deprecations matter:
- Hosting environments change: Most hosts have upgraded to PHP 8.0+
- Security: Old functions sometimes have security issues that won't be fixed
- Performance: Newer functions are often optimized
- Compatibility: Plugins using old functions can't be used with newer PHP versions
- Technical debt: Putting off migration makes future upgrades more expensive
The progression from deprecated to removed happens over years, giving you time to migrate. But if you ignore deprecation warnings long enough, you'll eventually have a crisis. A user upgrades to PHP 8.2, their hosting provider forces the upgrade, or they switch hosts and the new host runs PHP 8.1. Suddenly your plugin breaks catastrophically. Your plugin stops working entirely—not just with reduced functionality, but completely broken. Users complain. Your plugin rating drops. You scramble to fix it.
Identifying Deprecated Functions in Your Plugin
The first step is discovering what deprecated functions you're using. There are several approaches. You can't fix what you don't know about. Many plugins have deprecated code that the developers never discovered because they didn't have the right tools or didn't test against newer PHP versions. Some developers intentionally ignore deprecation warnings, assuming the function will work "forever." Others simply never test their code against development PHP versions where deprecation warnings are visible.
The key is choosing detection methods that work for your development process. If you're running tests in CI/CD, static analysis tools like PHPStan catch deprecations automatically. If you have a staging environment running PHP 8.x with debug logging enabled, runtime warnings appear in logs. Some approaches are proactive (finding deprecations before users encounter them), others are reactive (learning about them when errors appear in production).
PHP error logs approach:
Enable error reporting in your development environment:
// wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
// This creates /wp-content/debug.log
// Deprecated functions will be logged as warnings
Then run your plugin's features and check the debug log:
[18-Mar-2026 10:15:23 UTC] PHP Deprecated: Array access on objects is deprecated in /wp-content/plugins/my-plugin/includes/processor.php on line 234
[18-Mar-2026 10:15:45 UTC] PHP Deprecated: Implicitly marking parameter $foo as nullable is deprecated, the explicit nullable type must be used instead in /wp-content/plugins/my-plugin/src/class-handler.php on line 145
PHPStan static analysis:
PHPStan can detect deprecated function usage without running the code:
# Install PHPStan with WordPress rules
composer require --dev phpstan/phpstan phpstan/extension-installer szepeviktor/phpstan-wordpress
# Create phpstan.neon configuration
mkdir phpstan-configs
cat > phpstan.neon << 'EOF'
includes:
- extension.neon
parameters:
level: 8
paths:
- includes/
- src/
excludePaths:
- '*/tests/*'
ignoreErrors:
# Exclude vendor if included
- '#.*vendor.*#'
plugins:
- vendor/szepeviktor/phpstan-wordpress/extension.neon
EOF
# Run analysis
./vendor/bin/phpstan analyse
Output shows deprecated functions:
2 Call to deprecated method create_function()
/plugins/my-plugin/includes/callbacks.php:56
5 Call to deprecated function get_post_meta()
/plugins/my-plugin/src/post-handler.php:120
Grep-based search approach:
Search your codebase for known deprecated patterns:
# Find array access on objects
grep -r '\$object\[' includes/ src/
# Find ereg (completely removed in PHP 7.0)
grep -r 'ereg(' includes/
# Find mysql_ functions (removed in PHP 7.0)
grep -r 'mysql_' includes/
# Find split() (removed in PHP 7.0)
grep -r 'split(' includes/
# Find each() (removed in PHP 7.2)
grep -r '\beach(' includes/
# Find call_user_func_array without array check
grep -r 'call_user_func' includes/
WP HealthKit automated scanning:
WP HealthKit can analyze your plugin and identify:
- Deprecated PHP functions
- Deprecated WordPress functions
- Removed functions causing compatibility issues
- PHP 8.0+ incompatibilities
- Type declaration issues
The most comprehensive approach combines static analysis (PHPStan) with runtime testing (error logs) to catch both obvious deprecations and subtle compatibility issues.
WordPress-Specific Function Deprecations
Beyond PHP deprecations, WordPress itself deprecates functions. These are usually marked with _deprecated_function():
// WordPress deprecation example
function get_option_by_name($option_name) {
_deprecated_function(__FUNCTION__, '4.5.0', 'get_option()');
return get_option($option_name);
}
The deprecation notice tells you:
- Which function is deprecated
- When it was deprecated (WordPress version)
- What to use instead
Common WordPress deprecations:
// Deprecated in 5.1, use rest_send_cors_headers()
do_action('rest_pre_dispatch');
// Deprecated in 5.5, use wp_get_current_user()
get_currentuserinfo();
// Deprecated in 5.2, use wp_die() with args array
wp_die('Error', 'Title', array('response' => 403));
// Deprecated in 5.0, use apply_filters()
apply_filters_deprecated('filter_name', array($value));
// Deprecated in 4.9, use wp_remote_post()
wp_remote_request($url, array('method' => 'POST'));
// Deprecated in 5.7, use wp_list_categories()
wp_dropdown_categories();
Check the WordPress.org plugin handbook for a comprehensive list: https://developer.wordpress.org/plugins/
WordPress deprecations are typically documented with migration paths in the handbook. The handbook entry for each deprecated function explains what changed, why it was deprecated, and what you should use instead. Always consult the official documentation rather than guessing about replacements.
Look for deprecation notices in your debug.log:
[18-Mar-2026 10:15:23 UTC] PHP Deprecated: Plugin: 'my-plugin/my-plugin.php' is deprecated as of version 5.3.0! [Use register_block_type_args instead.](https://developer.wordpress.org/reference/functions/register_block_type_args/) in wp-includes/functions.php on line 4838
Planning Your Migration Strategy
Migrating deprecated code requires planning to avoid breaking existing functionality. Every function change carries risk—you might introduce a bug, change behavior in subtle ways, or create compatibility issues with integrations that depend on your plugin. Careful planning minimizes risk.
Start by inventorying all deprecated functions. Don't guess which ones are most important. Categorize by severity (critical functions vs. utility functions) and by effort (easy replacements vs. complex rewrites). Then prioritize—fix critical functions first, then utility functions, then the cleanup work. This way, if you run out of time or resources, you've at least fixed the most important issues.
Phase 1: Inventory and prioritize
// Create a migration checklist
/*
DEPRECATION MIGRATION CHECKLIST
================================
Priority 1 (Critical - breaks in PHP 8.0):
- [ ] Line 234: Array access on object $post (PHP 7.4)
- [ ] Line 456: mysql_* functions (PHP 7.0)
- [ ] Line 789: each() function (PHP 7.2)
Priority 2 (High - generates warnings):
- [ ] Line 123: get_currentuserinfo() deprecated in WP 5.5
- [ ] Line 345: wpautop() parameters changed in WP 5.5
- [ ] Line 567: do_action_ref_array() (use do_action with spread)
Priority 3 (Medium - forward compatibility):
- [ ] Line 678: Implicit nullable parameters (PHP 8.1)
- [ ] Line 890: Mixed type declarations (PHP 8.0)
Estimated effort:
- Priority 1: 4 hours
- Priority 2: 2 hours
- Priority 3: 1 hour
*/
Phase 2: Create a feature branch
git checkout -b migrate/php-deprecations
This isolates your changes so you can test thoroughly before merging.
Phase 3: Migrate incrementally
Don't change everything at once. Handle one deprecation category at a time:
# Commit 1: Replace all mysql_* functions
# Commit 2: Replace array access on objects
# Commit 3: Update WordPress function calls
# Commit 4: Update type declarations
This makes reviewing and debugging easier if something breaks.
Common PHP Deprecations and Solutions
Here are the most common deprecations and their solutions. These represent the patterns you'll encounter most frequently when modernizing legacy WordPress plugins. Understanding these patterns helps you recognize similar issues even when they appear in different contexts. Each solution demonstrates not just the replacement function but the reasoning behind why the old approach failed and why the new approach works better.
PHP 7.0: Removed Functions
The each(), ereg(), and mysql_* functions were completely removed in PHP 7.0. Code using them causes fatal errors immediately. These are high priority for migration because they make plugins completely non-functional on PHP 7.0+ servers.
Problem: Using each()
// Old code (PHP 5.x)
while ($item = each($array)) {
echo $item['value'];
}
Solution: Use foreach()
// New code (PHP 7.2+)
foreach ($array as $value) {
echo $value;
}
Problem: Using ereg() or eregi()
// Old code (PHP 5.x)
if (ereg('^[0-9]{3}-[0-9]{4}$', $phone)) {
// Valid phone
}
Solution: Use preg_match()
// New code (PHP 7.0+)
if (preg_match('/^[0-9]{3}-[0-9]{4}$/', $phone)) {
// Valid phone
}
Problem: Using mysql_* functions
// Old code (PHP 5.x)
$link = mysql_connect('localhost', 'user', 'pass');
mysql_select_db('db_name', $link);
$result = mysql_query('SELECT * FROM users', $link);
Solution: Use MySQLi or PDO
// New code (PHP 7.0+)
$link = mysqli_connect('localhost', 'user', 'pass', 'db_name');
$result = mysqli_query($link, 'SELECT * FROM users');
// Or use wpdb
global $wpdb;
$results = $wpdb->get_results('SELECT * FROM ' . $wpdb->users);
PHP 7.0: Deprecated Type Juggling
Problem: Assigning objects to array keys
// Old code
$key = new stdClass();
$key->id = 123;
$array[$key] = 'value'; // Object becomes array/string key
Solution: Extract scalar values
// New code
$key = 123;
$array[$key] = 'value';
// Or use arrays directly
$array['id_' . $object->id] = 'value';
PHP 7.0: Array Access on Non-Arrays
Problem: Array access on objects
// Old code
$post = get_post(123);
echo $post['post_title']; // $post is an object, not array
Solution: Use object property access
// New code
$post = get_post(123);
echo $post->post_title; // Correct object property access
PHP 7.4: Typed Properties
Problem: Implicit null typing
// PHP 7.3 (deprecated)
class Handler {
public $value; // Could be null implicitly
}
Solution: Explicit typing
// PHP 7.4+ (correct)
class Handler {
public ?string $value = null; // Explicitly nullable
public int $count = 0;
}
PHP 8.0: Named Arguments
Problem: Positional arguments with many parameters
// Old code (hard to read)
wp_schedule_event(time(), 'daily', 'my_hook', array($param1, $param2));
Solution: Use named arguments
// New code (PHP 8.0+, clearer)
wp_schedule_event(
time: time(),
recurrence: 'daily',
hook: 'my_hook',
args: array($param1, $param2)
);
WordPress: Deprecated Admin Functions
Problem: Using removed admin functions
// Deprecated in WP 5.5
get_currentuserinfo(); // Populates global $current_user
// Deprecated in WP 5.2
wp_die('Error', 'Title', array('response' => 403));
Solution: Use modern WordPress functions
// WP 5.5+
$current_user = wp_get_current_user();
echo $current_user->display_name;
// WP 5.2+
wp_die(
'Error message',
'Page title',
array(
'response' => 403,
'back_link' => true,
)
);
Practical Tip: WP HealthKit scans your plugin code to identify these deprecated patterns automatically. Rather than manually searching your entire codebase, let automated analysis find the issues for you.
Let WP HealthKit identify deprecated functions in your plugin.
Automated Detection Tools
Automated tools make deprecation detection efficient and comprehensive. Finding deprecations manually is tedious and error-prone. You might miss obscure functions, incorrectly identify what's deprecated versus what's fine, or waste hours searching when a tool could do it in seconds. Automated tools handle this work reliably.
Tools like PHPStan and Rector are specifically designed to catch modern PHP patterns and identify deprecated usage. They understand the nuances—they know which functions are removed in which PHP versions, which WordPress functions are deprecated in which WordPress versions, and how to find these patterns in complex codebases. They can analyze thousands of lines of code in seconds and provide precise line numbers of problematic code.
PHPStan with WordPress support:
# Install in your plugin directory
composer require --dev \
phpstan/phpstan \
szepeviktor/phpstan-wordpress
# Create configuration
cat > phpstan.neon << 'EOF'
includes:
- vendor/phpstan/phpstan/conf/config.level8.neon
- vendor/szepeviktor/phpstan-wordpress/extension.neon
parameters:
level: 8
paths:
- src/
- includes/
- my-plugin.php
excludePaths:
- '*/vendor/*'
- '*/tests/*'
EOF
# Run analysis
./vendor/bin/phpstan analyze
# Output shows all deprecations:
3 Call to deprecated function wp_get_post_terms()
PHP Mess Detector (PHPMD):
# Install PHPMD
composer require --dev phpmd/phpmd
# Analyze code
./vendor/bin/phpmd src,includes text cleancode,codesize,design,naming,unusedcode --extensions=php
Rector for automated refactoring:
Rector can automatically fix some deprecations:
# Install Rector
composer require --dev rector/rector rector/rector-wordpress
# Preview changes
./vendor/bin/rector process src --dry-run
# Apply changes
./vendor/bin/rector process src
Rector includes rules for WordPress deprecations:
// Automatically fixes these patterns
get_currentuserinfo() → wp_get_current_user()
create_function() → Use closure instead
wp_register_sidebar_widget() → register_widget()
Testing After Migration
Migration carries risks. Testing is essential to ensure nothing breaks.
Unit tests:
// tests/test-migration.php
class DeprecationMigrationTests extends WP_UnitTestCase {
public function test_post_object_access() {
$post = get_post(1);
// Should work with object notation
$this->assertNotEmpty($post->post_title);
$this->assertNotEmpty($post->post_content);
}
public function test_user_functions_work() {
wp_set_current_user(1);
// New function works
$user = wp_get_current_user();
$this->assertNotEmpty($user->display_name);
}
public function test_regex_migration() {
// Old ereg pattern
$this->assertTrue(
preg_match('/^[0-9]+$/', '12345')
);
// Verify it matches same strings as old code
$this->assertFalse(
preg_match('/^[0-9]+$/', 'abc123')
);
}
}
Functional tests:
Test actual user workflows with the new code:
# Test on PHP 7.4
php7.4 -S localhost:8000 &
# Run tests manually, verify features work
# Test on PHP 8.0
php8.0 -S localhost:8000 &
# Run tests again
# Test on PHP 8.1
php8.1 -S localhost:8000 &
# Run tests again
Automated test matrix:
Use GitHub Actions to test on multiple PHP versions:
# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['7.4', '8.0', '8.1', '8.2']
wordpress-version: ['6.0', '6.1', '6.2']
steps:
- uses: actions/checkout@v3
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
- run: composer install
- run: ./vendor/bin/phpunit
- run: ./vendor/bin/phpstan analyse
Regression testing:
Create a checklist of features to test manually. Regression testing means testing that old functionality still works after your changes. The risk is that you fixed one deprecated function but broke something that depends on it. By systematically testing core features, WordPress integration points, error handling, and performance, you gain confidence that the changes didn't introduce problems.
Automated tests (unit tests, integration tests) should verify that specific functions work correctly. But manual regression testing verifies that the plugin works from a user perspective. A test might pass technically but the feature might feel broken because of performance degradation or subtle behavior changes.
Feature Testing Checklist
==========================
Core Plugin Features:
- [ ] Plugin activates without errors
- [ ] Settings page loads and saves
- [ ] Main feature works (e.g., import functionality)
- [ ] Export functionality produces valid files
- [ ] API endpoints respond correctly
WordPress Integration:
- [ ] Hooks and filters work correctly
- [ ] Custom post types display
- [ ] Shortcodes render properly
- [ ] Admin menus appear
- [ ] Capabilities check works
Error Handling:
- [ ] No PHP warnings in debug.log
- [ ] No PHP notices in debug.log
- [ ] No jQuery deprecation warnings
- [ ] Graceful error messages shown
Performance:
- [ ] Page load times haven't regressed
- [ ] Database queries are reasonable
- [ ] Memory usage is acceptable
Additional Resources
Frequently Asked Questions
What if I find deprecated code I didn't write?
You inherited it from a previous developer. It's your responsibility now. Create a migration plan and schedule time to fix it. Modern hosting won't run your plugin if it uses removed functions. The longer you wait, the more painful it becomes. By the time PHP version X+2 is mainstream, fixing PHP version X deprecations becomes urgent. Users complain. Plugin ratings drop. You're forced to fix it quickly under pressure, leading to bugs.
The best approach is proactive maintenance. When you discover deprecated code, fix it as part of your regular development. Don't accumulate technical debt hoping someone else will handle it later. That "later" never comes until crisis hits.
Can I use a compatibility shim for deprecated functions?
Sometimes. You can create a polyfill for a deprecated function:
// If WordPress removed get_currentuserinfo(), polyfill it
if (!function_exists('get_currentuserinfo')) {
function get_currentuserinfo() {
global $current_user;
$current_user = wp_get_current_user();
}
}
But this just delays the problem. Better to migrate properly.
How much time should I allocate for deprecation migration?
Depends on plugin size and age:
- Small, modern plugin: 2-4 hours
- Medium plugin: 1-2 days
- Large legacy plugin: 1-2 weeks
Use automated detection (PHPStan, Rector) to reduce manual work. The time investment is worth it compared to the cost of a production incident where users can't use your plugin because it crashes on modern PHP versions. Prevention is far cheaper than emergency fixes. Additionally, the migration process teaches you about modern PHP patterns and best practices, improving your skills as a developer.
Should I create a major version bump for deprecation fixes?
Only if there are breaking changes for users. Deprecation migration is usually backward compatible and warrants a minor version bump (e.g., 2.0.0 → 2.1.0).
What if my WordPress version doesn't support the new syntax?
Use minimum WordPress version that supports it:
// WordPress 5.7+
if (function_exists('wp_new_function')) {
wp_new_function();
} else {
// Fallback for older WordPress
old_function();
}
But ideally, drop support for ancient WordPress versions.
Is it worth migrating if I'm thinking of sunsetting the plugin?
If you're planning to stop maintenance, maybe not. But if you want to keep it working, migration is essential. Deprecated code will eventually break.
Can I use both old and new syntax during transition?
Yes, temporarily. But don't leave both active indefinitely—it's confusing and unmaintainable. After testing, remove the old code completely.
Conclusion
WordPress plugin PHP deprecated functions migration isn't exciting, but it's essential maintenance. Ignoring deprecations guarantees that your plugin will eventually break when hosting environments upgrade to newer PHP versions. The question isn't whether you'll migrate, but when—before users complain or after they've already switched to competitors.
By systematically identifying deprecated code, planning migration carefully, testing thoroughly, and using automated tools, you can modernize your plugin without breaking functionality. The effort pays off in compatibility, performance, and maintainability.
Think of deprecation migration as preventive maintenance. You wouldn't wait for your car's engine to fail before changing the oil—you do it proactively. Same with deprecated code. Regular, proactive maintenance prevents emergencies. A few hours of work now saves days of crisis-mode debugging later.
The best plugins are modernized regularly. They track WordPress updates, PHP updates, and coding standard evolution. Their developers run static analysis regularly, fix warnings promptly, and test against newer environments. These plugins work reliably on modern hosting, perform better than legacy competitors, and attract users who appreciate quality and reliability.
WP HealthKit helps you identify deprecated functions and compatibility issues automatically. Rather than manually searching your codebase, get a comprehensive report of what needs migration. Our scanning service analyzes your entire plugin, identifies all deprecated functions, categorizes them by severity, and provides migration guidance. This transforms a potentially overwhelming task into a manageable, prioritized action list.
Upload your plugin to WP HealthKit for automated deprecation detection and migration guidance.
For more on WordPress plugin quality and modernization, check out our guides on PHP 8 compatibility for WordPress plugins and PHPStan static analysis for WordPress. Keeping your plugin modern and compatible is an ongoing process that pays dividends in user satisfaction and plugin longevity.