2

So I was passing an array of objects through an action today, no biggy, and things were working fine. Until I was iterating over one of the arguments to a callback and started getting errors. The only difference was that the passed array to the do_action call only had a single object in it.

Confused by this, I simply didn't call the action unless the array had a count of over 1 (the action is caching something FYI).

Looking into the function definition I found this on line 411 of wp-includes/plugin.php

if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)

which is what was causing my array of a single object to become just an object. To me this is really weird, if I pass an array to an action then I expect an array on other side. I'm using WordPress 3.7.1 and am wondering if anyone knows why do_action has this behavior? A ticket or a link to something in the wordpress repository would work as an answer for me.

EDIT: Request for code and actions:

I create an action within my code like so:

add_action('hs_cache_merchants', array('HoneyCache', 'cacheMerchants'), 10, 1);

It is called like so within a method that retrieves data from the database, where $merchants is an array of objects.:

do_action('hs_cache_merchants', $merchants);

And then my callback registered with the add_Action:

public static function cacheMerchants($merchants){
    if(!is_array($merchants)){ /* WordPress will convert an array of a single object to just the object. */
        $merchants = array($merchants);
    }

    set_transient(HoneyMerchant::CACHE_CURRENT_MERCHANTS_KEY, $merchants, HoneyMerchant::CACHE_CURRENT_TIME);
}

If I modify my prototype to be

public static function cacheMerchants(Array $merchants){

then I will get the error:

 PHP Catchable fatal error:  Argument 1 passed to HoneyCache::cacheMerchants() must be an array, object given

I used print_r in the function that calls do_action and noted an array with a single object in it, this only happens if the array has 1 item in it, since that's part of what that if in the core checks.

2
  • Which action were you using? And post your code, so we can see what you are doing.
    – s_ha_dum
    Apr 17, 2014 at 22:49
  • @s_ha_dum updated question with code. It's a custom action. Apr 18, 2014 at 11:15

1 Answer 1

1

I don't know if you solved this, I just had same problem,

Second argument in do_action has special check if it is array with only one object, In that case they use reference to object in array instead of array with object. I believe they use this method to pass and preserve reference through function with variable arguments.

I used do_action_ref_array() to avoid this.

1
  • Thanks for the hint!
    – Johnny97
    Sep 29, 2021 at 9:13

Your Answer

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

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