2012-02-24 121 views
5

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

回答

2

php doc pageregister_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(); 
3

你不能做直的,但总是有一个变通方法:

$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

其他选项是使用以下功能:

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