Warning: array_keys() expects parameter 1 to be ar

2020-04-16 01:42发布

问题:

I am getting the following warnings:

Warning: array_keys() expects parameter 1 to be array, object given in /home/inin3486/public_html/wordpress/wp-content/themes/classiera/inc/colors.php on line 7

And

Warning: max(): When only one parameter is given, it must be an array in /home/inin3486/public_html/wordpress/wp-content/themes/classiera/inc/colors.php on line 7

This is what we currently have showing in CPanel:

<?php 

function classiera_wpcss_loaded() {

    // Return the lowest priority number from all the functions that hook into wp_head
    global $wp_filter;
    $lowest_priority = max(array_keys($wp_filter['wp_head']));

    add_action('wp_head', 'classiera_wpcss_head', $lowest_priority);

    $arr = $wp_filter['wp_head'];

}
add_action('wp_head', "classiera_wpcss_loaded");

How can I resolve this?

回答1:

You are getting the warning because $wp_filter['wp_head'] is an object, i.e. an instance of WP_Hook. The PHP construct array_keys needs the variable to be an array data type.

WordPress 4.7 changed the hooks. Now, each event's value in $wp_filter is an instance of WP_Hook.

The array of callbacks is located in the public property callbacks, which you can access like this:

$wp_filter['wp_head']->callbacks;

Problems with your code

Beyond accessing the public property, your code has 2 fundamental problems:

  1. The new callback you are adding, i.e. for classiera_wpcss_head, will not work (more in a moment to explain).
  2. max will get you the highest priority number and not the lowest.

New Callback Won't Work - It's too Late in the Request Cycle

The event wp_head has already sorted all of the registered callbacks and is in the process of calling each of them. Your callback is at a priority of 10. The lowest one has already been processed and will not run.

What do I mean by that?

add_action('wp_head', 'classiera_wpcss_head', $lowest_priority);

The above code will not run. Why? Timing. The function that adds this callback is being called at priority 10. It's too late to add another callback to this event, i.e. to wp_head.

What can you do instead?

I assume you want classiera_wpcss_head to run first. Right? That's why you are looking for the lowest priority number. Instead, just register your callback with a priority of 0 to make sure it's the first (or one of the first) ones.

Disclaimer: You cannot guarantee your callback will run before any others that are registered to priority 0. Why? All callbacks are adding to their priority based upon when the add_action runs. In other words, if another add_action( 'wp_head', 'some_callback', 0 ); runs before yours, yours will occur after that one.

max gets you the highest priority number

The PHP construct max is getting you the highest priority number and not the lowest. Instead, you'd want to use min.

However, you don't even have to do that as the first element in the array is the lowest priority number. Why?

When do_action( 'wp_head' ); fires (runs), it sorts all of the callbacks lowest to highest by the priority number. Then it loops through each of them and calls them in order one-by-one.

Let's fix your code

Let's fix the timing issue in your code.

  1. Remove the code you showed above as it's not necessary.
  2. Add the callback at the root per below.

If you want the callback to fire as early as possible, do this:

add_action( 'wp_head', 'classiera_wpcss_head', 0 );
/**
 * Description.
 *
 * @since 1.0.0
 */
function classiera_wpcss_head() {
    // your code here
}

Put this code at the root of the file, i.e. not wrapped in the function classiera_wpcss_loaded.

If you meant to put it as the last one (maximum priority number), then you can set it to say a 9999.



回答2:

Simply change the code from line 1 to 14:

function wpcrown_wpcss_loaded() {

    // Return the lowest priority number from all the functions that hook into wp_head
    global $wp_filter;
    //$lowest_priority = max(array_keys($wp_filter['wp_head'])); (I made this comment)

    add_action('wp_head', 'wpcrown_wpcss_head', $lowest_priority + 1);

    $arr = $wp_filter['wp_head'];}

add_action('wp_head', "wpcrown_wpcss_loaded",$lowest_priority);