Detect change in site_url and home_url

Option 1 – save a backup of site_url and home_url

If you want to detect whenever the site_url or home_url changes (settings page, wp-config.php, functions.php,…) the only way to get it would be to save some extra options on the database with those urls so that whenever the site is opened you would check if they had changed:

function check_siteurl_changes() {
    $home_url = home_url();
    $saved_home_url = get_option('saved_home_url');
    $site_url = site_url();
    $saved_site_url = get_option('saved_site_url');


    if( $saved_home_url !== $home_url || $saved_site_url !== $site_url ) {
        update_option( 'saved_home_url', $home_url );
        update_option( 'saved_site_url', $site_url );
        // do something
    }
}
add_action( 'init', 'check_siteurl_changes' );

Option 2 – use pre_update_option_(option_name) filter (doesn’t cover all use cases)

You could use pre_update_option_(option_name) filter hook. This filter is applied before saving a certain option to the database. This would only detect if you change those urls on settings page or with update_option().

To also detect if you add WP_HOME and WP_SITEURL to wp-config.php you would need to check if those constants are defined and compare them directly with database.

However, you wouldn’t be able to detect if you change urls directly on the database, or if you use update_option (on functions.php) with a higher priority than your function.

function check_siteurl_changes( $new_value, $old_value ) {
    if( $new_value != $old_value ) {
        // do something
    }
    return $new_value;
}

// check if changed on settings page
add_filter( 'pre_update_option_siteurl', 'check_siteurl_changes', 1, 2 );
add_filter( 'pre_update_option_home', 'check_siteurl_changes', 1, 2 );

function myplugin_init() {
    global $wpdb;

    // check if changed on wp-config with WP_HOME and WP_SITEURL constants but this would be triggered everytime while the constant is defined on wp-config
    if ( defined('WP_HOME') && '' != WP_HOME ) {
        $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'home' ) );
        $home = $row->option_value;
        check_siteurl_changes( WP_HOME, $home );
    }

    if ( defined('WP_SITEURL') && '' != WP_SITEURL ) {
        $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'siteurl' ) );
        $siteurl = $row->option_value;
        check_siteurl_changes( WP_SITEURL, $siteurl );
    }
}

add_action( 'init', 'myplugin_init' );