register_shutdown_function覆盖

时间:2012-02-24 13:51:51

标签: php function

是否可以覆盖已设置的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 个答案:

答案 0 :(得分: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

The code

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;
        }
}

答案 1 :(得分:3)

这是不可能的。 PHP具有remove_user_shutdown_function PHPAPI函数,但不会向用户态代码公开。

答案 2 :(得分:2)

来自register_shutdown_function()上的php doc page

  

可以对register_shutdown_function()进行多次调用   将按照他们注册的顺序进行调用。如果你打电话   在一个已注册的关闭函数中退出(),处理将停止   完全没有其他注册的关闭函数被调用。

所以这意味着如果你只想调用函数f2,你可以将它传递给异常处理程序中的exit()调用。多次调用register_shutdown_function()将按顺序调用所有函数,而不仅仅是最后注册的函数。由于似乎没有任何unregister_shutdown_function()这是我的建议。

答案 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

答案 4 :(得分: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();