注册shutdown函数覆盖

6

是否可以覆盖已经设置的register_shutdown_function堆栈?例如:

function f1(){
    echo "f1";
}
function f2(){
    echo "f2";
}
register_shutdown_function("f1");
echo "actions here";
register_shutdown_function("f2");
call_to_undefined_function(); // to "produce" the error

在这种情况下,我希望脚本只调用f2()。这是否可行?
5个回答

4
你不能直接这样做,但总有一种解决方法:
$first = register_cancellable_shutdown_function(function () {
    echo "This function is never called\n";
});

$second = register_cancellable_shutdown_function(function () {
    echo "This function is going to be called\n";
});

cancel_shutdown_function($first);

输出:

$ php test.php
This function is going to be called

代码:

function register_cancellable_shutdown_function($callback)
{
        return new cancellable_shutdown_function_envelope($callback);
}

function cancel_shutdown_function($envelope)
{
    $envelope->cancel();
}

final class cancellable_shutdown_function_envelope
{
        private $callback;

        public function __construct($callback)
        {
                $this->callback = $callback;
                register_shutdown_function(function () {
                        $this->callback && call_user_func($this->callback);
                });
        }

        public function cancel()
        {
                $this->callback = false;
        }
}

3

2
另一个选择是使用以下函数:
function register_named_shutdown_function($name, $callback)
{
        static $callbacks = [];
        $callbacks[$name] = $callback;

        static $registered;
        $registered || $registered = register_shutdown_function(function () use (&$callbacks) {
                array_map(function ($callback) {
                        call_user_func($callback);
                }, $callbacks);
        }) || true;
}

示例用法:

register_named_shutdown_function("first", function () {
        echo "Never executed\n";
});

register_named_shutdown_function("second", function () {
        echo "Secondly executed\n";
});

register_named_shutdown_function("first", function () {
        echo "Firstly executed\n";
});

输出:

Firstly executed
Secondly executed

2
php文档页面中了解到register_shutdown_function()
多次调用register_shutdown_function()是可行的,而且每次调用的顺序都与注册时相同。 如果在一个已注册的关闭函数内调用了exit(),则处理将完全停止,并且不会调用任何其他已注册的关闭函数。
这意味着如果您只想调用函数f2,则可以将其传递给异常处理程序中的exit()调用。 多次调用register_shutdown_function()将按顺序调用所有函数,而不仅仅是最后注册的函数。 由于似乎没有任何类型的unregister_shutdown_function(),因此我建议采用此方法。

0

我也遇到了这个问题,我解决方法如下:

function f1(){
if (defined('CALL1') && CALL1===false) return false;
echo "f1";
}
function f2(){
    echo "f2";
}
register_shutdown_function("f1");
echo "actions here";
define('CALL1', false);
register_shutdown_function("f2");
call_to_undefined_function();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接