Here are some random thoughts on this:
Question #1
How much money did we send to grandma?
For 100 page loads, we sent her 100 x $1 = $100.
Here we actually mean 100 x do_action( 'init' )
calls.
It didn’t matter that we added it twice with:
add_action( 'init','send_money_to_grandma' );
add_action( 'init','send_money_to_grandma' );
because the callbacks and priorities (default 10) are identical.
We can check how the add_action
is just a wrapper for add_filter
that constructs the global $wp_filter
array:
function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
global $wp_filter, $merged_filters;
$idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);
$wp_filter[$tag][$priority][$idx] = array(
'function' => $function_to_add,
'accepted_args' => $accepted_args
);
unset( $merged_filters[ $tag ] );
return true;
}
If we did however change the priority:
add_action( 'init','send_money_to_grandma', 9 );
add_action( 'init','send_money_to_grandma', 10 );
then we would send her 2 x $1 per page load or $200 for 100 page loads.
Same if the callbacks where different:
add_action( 'init','send_money_to_grandma_1_dollar' );
add_action( 'init','send_money_to_grandma_also_1_dollar' );
Question #2
If we want to make sure we only send grandma $1
If we only want to send it once per page load, then this should do it:
add_action( 'init','send_money_to_grandma' );
because the init
hook is only fired once. We might have other hooks that fires up many times per page load.
Let’s call:
add_action( 'someaction ','send_money_to_grandma' );
but what happens if someaction
fires 10 times per page load?
We could adjust the send_money_to_grandma()
function with
function send_money_to_grandma()
{
if( ! did_action( 'someaction' ) )
internetofThings("send grandma","$1");
}
or use a static variable as a counter:
function send_money_to_grandma()
{
static $counter = 0;
if( 0 === $counter++ )
internetofThings("send grandma","$1");
}
If we only want to run it once (ever!), then we might register an option in the wp_options
table via the Options API:
function send_money_to_grandma()
{
if( 'no' === get_option( 'sent_grandma_money', 'no' ) )
{
update_option( 'sent_grandma_money', 'yes' );
internetofThings( "send grandma","$1" );
}
}
If we want to send her money once every day, then we can use the Transient API
function send_money_to_grandma()
{
if ( false === get_transient( 'sent_grandma_money' ) ) )
{
internetofThings( "send grandma","$1" );
set_transient( 'sent_grandma_money', 'yes', DAY_IN_SECONDS );
}
}
or even use the wp-cron.
Note that you might have ajax calls. as well.
There are ways to check for those, e.g. with DOING_AJAX
There might also be redirections, that could interrupt the flow.
Then we might want to restrict to the backend only, is_admin()
or not: ! is_admin()
.
Question #3
Is this something that plugin developers worry about?
yes this is important.
If we want to make our grandma very happy we would do:
add_action( 'all','send_money_to_grandma' );
but this would be very bad for performance … and our wallet 😉