是否可以覆盖已设置的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()
。这可能吗?
答案 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
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();