挂钩优先级是否有限制?


9

当我希望过滤器或操作挂钩覆盖所有其他过滤器时,我将其分配为的优先级999。但是,最近我看到有些人使用极限值作为优先级,例如20000,甚至99999

除了使用如此高的优先级是荒谬的事实,它们是否真的有效?挂钩优先级是否有限制?如果超过限制会怎样?使用极端优先级时是否存在性能差异?

更新: @harke表明堆栈溢出的数量由限制PHP_INT_MAX


您是否没有链接到谈论此问题的@hakre的答案?它应该是Q的一部分,并且还要遵循他的建议,我怀疑他很认真地知道一两件事……
brasofilo 2013年

您指的是什么答案?
2013年

Answers:


13

没有限制,也没有性能损失。要了解原因,您需要了解所有挂钩如何存储在WP生态系统中。

首先,您需要了解所有挂钩的存储位置以及它们的存储方式。所有过滤器和wp_filter动作的挂钩都存储在名为的全局变量中,是的,动作挂钩也存储在此变量中。此变量是关联的数组,其中key是操作或过滤器的名称,而value是另一个关联数组。例如,让我们看一下“ init”操作,在此阶段,我们将看到以下结构:

$wp_filter = array(
    'init' => array(...),
);

此子数组具有数字键和值作为数组。数字键是我们的优先事项。与数字键关联的数组包含优先级相同的钩子列表。因此,如果我们调用add_action( 'init', 'wpse8170_my_first_init', 20 ),然后调用add_action( 'init', 'wpse8170_my_second_init', 20 ),最后调用add_action( 'init', 'wpse8170_my_third_init', 10 ),我们的示例将如下所示:

$wp_filter = array(
    'init' => array(
        20 => array(
            'wpse8170_my_first_init' => array(
                'accepted_args' => 1, // the number of accepted arguments by your hook
                'function' => 'wpse8170_my_first_init', // callback function
            ),
            'wpse8170_my_second_init' => array(...),
        ),
        10 => array(
            'wpse8170_my_third_init' => array(...),
        ),
    ),
);

现在,当init动作被触发时,所有的钩子都将使用ksort函数的使用进行排序,并且我们的数组看起来如下:

    array(
        10 => array(
            'wpse8170_my_third_init' => array(...),
        ),
        20 => array(
            'wpse8170_my_first_init' => array(
                'accepted_args' => 1, // the number of accepted arguments by your hook
                'function' => 'wpse8170_my_first_init', // callback function
            ),
            'wpse8170_my_second_init' => array(...),
        ),
    ),

并且所有钩子都将在此队列中执行:首先'wpse8170_my_third_init',然后是'wpse8170_my_first_init'最后'wpse8170_my_second_init'

因此,您可以看到没有限制和惩罚,并且可以使用PHP环境可以接受的任何值作为关联数组的键。


2
max( $priorities ) + 1如果最后一个数字等于,将失败PHP_INT_MAX。在这种情况下,您必须将值转换为字符串并添加一些内容。
fuxia

@toscho是的,同意。更新了奖金片段。
Eugene Manuilov 2013年

2
万一定义$wp_filter不断变化,“奖金”是个坏主意。它不能直接由插件使用。过去我们进行了修改(主要是出于性能方面的考虑,偶然)。
Andrew Nacin 2013年

@AndrewNacin好的,我已将其删除,因为它引起了太多问题:)
Eugene Manuilov 2013年

6

这是一个整数,因此在32位PHP系统上,它将限制为-2147483648至2147483647,而在64位PHP上,它将限制为-9223372036854775808至9223372036854775807。

编辑:没有性能损失,它是一个整数。

不过实话说?:)


我知道这是一个整数,但是我在谈论实际的挂钩机制。我听人说,有一个挂钩,就是太大将导致钩完全失败,并且回调将不会被执行
谢伊

WHO?什么时候?它只是一个数组的索引,而那只是一个稀疏的数组,因此影响可忽略不计。但老实说,大量数字几乎是不了解问题的指示(例如疯狂地尝试可能
有用的

1

@shea-WordPress操作与您假设的相反。较高优先级的数字将不会覆盖其他优先级,并且PHP_INT_MAX的使用不是某种“极端”尝试来强制此操作/过滤器先于其他任何运行。

要将操作/过滤器置于执行顺序的最前,您需要使用优先级0。

PHP_INT_MAX恰好在另一端。当您希望您的操作/过滤器在所有其他(正常优先级)钩子完成之后运行时,将使用它。


1
是的,这就是主意。在钩子上运行的最终过滤器将能够修改变量而无需担心任何进一步的更改
Shea

负整数值也可用于$priority,因此优先级挂钩的回调0不一定在执行顺序的顶部。
Dave Romsey '18

0

没有限制,没有性能损失。通过检查代码,您甚至可以将字符串用作优先级,尽管我不建议这样做;)

如果您的操作必须是最后一个操作,则可以通过在$wp_actions[your hook]调用操作时查看全局索引来检查分配的优先级,并在需要时以更高的优先级再次添加它,但是我看不出实际执行此操作的原因东西的。


0

实际上没有任何限制,因为挂钩实际上是作为数组存储的,并且优先级是数字索引。

但是,实际上,数组大小将受到为执行脚本分配的内存量的限制。

因此,我想设置一个荒谬的大优先级数字-只是将其转换为存储挂钩函数的数组中的数字索引-不应使wordpress崩溃。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.