I'm new to Wordpress development (and php in general) so I'm confused about the execution of functions in my plugin's php file. I've seen multiple guides that show to create a register_activation_hook function, that is executed when the plugin is activated. However, after the activation hook function, there is always an add_action('init') call that adds a bunch of options to the database.

So my question is: when Wordpress evaluates my plugin's php file, and finds the register_activation_hook call, why does it not execute the add_action('init') call until after the plugin is activated? If Wordpress evaluates my plugin's php file, and there is a function call to add_action('init') in the file, it seems like that function call would execute when the page is evaluated, because it's not inside a control structure.

I know Wordpress is evaluating this file before it's activated, because it knows my plugin name, and author, and all that before it's activated. So if it's evaluating the file, why is it not executing the add_action('init') call?

Does my question make sense? Can anyone help me to understand why things are working this way?

Here's an example of what I'm talking about:

register_activation_hook(__FILE__, 'halloween_store_install');

function halloween_store_install() {
    $hween_options_arr = array(
        'currency_sign' => '$'

    //save our default option values
    update_option( 'halloween_options', $hween_options_arr );

add_action( 'init', 'halloween_store_init' ); // <-- why is this not executed until my plugin is activated?

function halloween_store_init(){
    $labels = array(
        'name' => __( 'Products', 'halloween-plugin' ),
        'singular_name' => __( 'Product', 'halloween-plugin' ),
        'add_new' => __( 'Add New', 'halloween-plugin' ),
        'add_new_item' => __( 'Add New Product', 'halloween-plugin' ),
        'edit_item' => __( 'Edit Product', 'halloween-plugin' ),
        'new_item' => __( 'New Product', 'halloween-plugin' ),
        'all_items' => __( 'All Products', 'halloween-plugin' ),
        'view_item' => __( 'View Product', 'halloween-plugin' ),
        'search_items' => __( 'Search Products', 'halloween-plugin' ),
        'not_found' => __( 'No products found', 'halloween-plugin' ),
        'not_found_in_trash' => __( 'No products found in Trash', 'halloween-plugin' ),
        'menu_name' => __( 'Products', 'halloween-plugin' )

    $args = array(
        'labels' => $labels,
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true,
        'show_ui_menu' => true,
        'query_var' => true,
        'rewrite' => true,
        'capability_type' => 'post',
        'has_archive' => true,
        'hierarchical' => false,
        'menu_position' => null,
        'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' )

    register_post_type( 'halloween-products', $args);
  • 1
    Please read this answer, a separate answer is in my opinion not necessary, is redundant. As small hint, if you will work with the plugin "Debug Objects" you can see the stacktrace, the hooks in the order, there is fired.
    – bueltge
    Commented Aug 29, 2016 at 13:17
  • @bueltge while that flow chart is helpful, it only illustrated when entire files are executed. Since this add_action('init') call is in the same file as my plugin name and the register_activation_hook call, why is it not getting called when the rest of the file is being evaluated? Commented Aug 29, 2016 at 13:36
  • You have two functions and you fired this different, on two different hooks. The order is in advice of the core, how runs the hooks in the core. Also you should fire your plugin on a hook, like plugins_loaded and not automatically via the include the file.
    – bueltge
    Commented Aug 29, 2016 at 13:44
  • If I understand your question correctly, you want to know why the add_action function is not run while being in the same file as register_activation_hook. Because nothing is run at the include level in WP, everything depends on the hook sequence. So basically it is evaluated when PHP reads that file, but it will be executed when the hook is called. This makes it possible to build plugins and call functions conditionally and also respect a certain sequence logic in the application.
    – bynicolas
    Commented Aug 29, 2016 at 14:12
  • If we didn't have that, we'd get a bunch of errors because some functions would be called before the the application would be loaded and depending variables and constant not defined yet. Basically, add_action, add_filter and register_activation_hook (and others) are PHP's call_user_func but with some added context so it's easier to understand what is being called and when. Hope this makes more sense to you
    – bynicolas
    Commented Aug 29, 2016 at 14:18

1 Answer 1


WordPress is an application and everything that is run within that application is called by hooks.

Then 2 main hook functions are add_action and add_filter, but as you saw, register_activation_hook and register_deactivation_hook are other functions that are used in the context of activation and deactivation.

There exist more hook defining functions, like functions that will hook time sensitive actions (pseudo cron) like wp_schedule_event for instance.

The codex offers a good list of available action hooks (ordered by their generaly called sequence) to be used with add_actions and filters to be used with add_filter.

I am not aware of such a list for all hooks defining functions.

Like I said in my comment, most of these functions are simply intelligent wrappers for PHP's call_user_func functions that give context to these hooks.

So when a plugin or theme is installed, it won't automatically run even though their files would technically be read (at least the main files are).

In the main file of a plugin or theme, you will find a comment section defining the parameter of the plugin/theme, such as theme name, author, version, etc.

In themes, the style.css file would be read and would contain something similar to this

 Theme Name: Twenty Thirteen
 Theme URI: http://wordpress.org/themes/twentythirteen
 Author: the WordPress team
 Author URI: http://wordpress.org/
 Description: The 2013 theme for WordPress takes us back to the blog, featuring a full range of post formats, each displayed beautifully in their own unique way. Design details abound, starting with a vibrant color scheme and matching header images, beautiful typography and icons, and a flexible layout that looks great on any device, big or small.
 Version: 1.0
 License: GNU General Public License v2 or later
 License URI: http://www.gnu.org/licenses/gpl-2.0.html
 Tags: black, brown, orange, tan, white, yellow, light, one-column, two-columns, right-sidebar, flexible-width, custom-header, custom-menu, editor-style, featured-images, microformats, post-formats, rtl-language-support, sticky-post, translation-ready
 Text Domain: twentythirteen

 This theme, like WordPress, is licensed under the GPL.
 Use it to make something cool, have fun, and share what you've learned with others.

Similarly, in a plugin's main PHP file, you would find a comment section containing something similar to this

 Plugin Name: My Toolset
 Plugin URI:  http://URI_Of_Page_Describing_Plugin_and_Updates
 Description: This describes my plugin in a short sentence
 Version:     1.5
 Author:      John Smith
 Author URI:  http://URI_Of_The_Plugin_Author
 License:     GPL2
 License URI: https://www.gnu.org/licenses/gpl-2.0.html
 Domain Path: /languages
 Text Domain: my-toolset

Finally, once a theme/plugin is activated, then it will go on loading the rest of it's files following WP's hook loading sequence and load everything that the developers hooked to these action hooks or filters.

And in those developer's created functions, all the magic happens for that particular plugin or theme.

A pretty comprehensive and worth reading explanation of WP load sequence was made by userabuser here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.